Initial checkin

This commit is contained in:
Tom Marshall 2014-05-07 13:11:15 -05:00
parent bd02b76e5d
commit a19589abb4
7 changed files with 875 additions and 0 deletions

266
android-build Executable file
View File

@ -0,0 +1,266 @@
#!/bin/bash -e
# Acquire lock on source tree
parent=$(ps h -o comm $PPID)
if [ "$parent" != "flock" ]; then
exec flock ".lock" $0 "$@"
fi
usage()
{
prog=$(basename $0)
echo ""
echo "Usage:"
echo " $prog [options] <build_combo>"
echo ""
echo " Options:"
echo " -a Automated build (check for clean working dir)"
echo " -c Clean output before build"
echo " Given once, clean device output (out/target/product)"
echo " Given twice, clean target output (out/target)"
echo " Given thrice, clean all output (out)"
echo " -C Clean output after successful build"
echo " Given once, clean device output (out/target/product)"
echo " Given twice, clean target output (out/target)"
echo " Given thrice, clean all output (out)"
echo " -j Specify -j value for make [CPUS]"
echo " -l Save build output to log file"
echo " -o Specify output directory"
echo " -O Specify Android out dir"
echo " -s Show commands"
echo " -t Specify make target [auto]"
echo " -v Specify version [none]"
echo ""
echo "Exit status: 0 on success, !0 on failure"
echo ""
echo "On success, output will be copied to \$TARGET_PRODUCT.zip."
echo ""
exit 1
}
# Tool locations
# XXX: not darwin compatible
CCACHE="prebuilts/misc/linux-x86/ccache/ccache"
ccache_stats()
{
# Calculate ccache stats
local ch=0
local cm=0
local ct=0
local cpct="NA"
OLDIFS="$IFS"
IFS=$'\n'
lines=($($CCACHE -s))
IFS="$OLDIFS"
for (( n=0; $n < ${#lines[*]}; n=$(($n+1)) )); do
line=${lines[$n]}
if [ "${line:0:9}" = "cache hit" ]; then
ch=$(( ch + $(echo $line | sed 's/[^0-9]*//') ))
elif [ "${line:0:10}" = "cache miss" ]; then
read -a fields <<<$line
cm=$(( cm + $(echo $line | sed 's/[^0-9]*//') ))
fi
done
IFS="$OLDIFS"
if [ -n "$ch" -a -n "$cm" ]; then
ct=$(($ch+$cm))
fi
if [ "$ct" -gt 0 ]; then
cpct=$((ch*100/ct))
fi
echo "ch=$ch"
echo "cm=$cm"
echo "ct=$ct"
echo "cpct=$cpct"
}
# Set some useful vars
export USE_CCACHE=1
export CPUS=$(grep "^processor" /proc/cpuinfo | wc -l)
export MEM=$(cat /proc/meminfo | grep "^MemTotal" | grep -o "[0-9]*")
# Find actual value for jobs.
# - No more than 8 jobs
# - No more than one job per cpu
# - No more than one job per 1.5gb
max_jobs=8
cpu_jobs="$CPUS"
if [ "$cpu_jobs" -lt "$max_jobs" ]; then
max_jobs="$cpu_jobs"
fi
mem_jobs=$(($MEM/1572864))
if [ "$mem_jobs" -lt "$max_jobs" ]; then
max_jobs="$mem_jobs"
fi
# Init options
opt_automated=0
opt_clean=0
opt_postclean=0
opt_jobs="$max_jobs"
opt_log=0
opt_outdir="."
opt_outandroid=""
opt_maketarget="auto"
opt_showcommands=0
opt_version=""
while getopts "acCj:lo:O:st:v:" opt; do
case "$opt" in
a) opt_automated=1 ;;
c) opt_clean=$(($opt_clean+1)) ;;
C) opt_postclean=$(($opt_postclean+1)) ;;
j) opt_jobs="$OPTARG" ;;
l) opt_log=1 ;;
o) opt_outdir="$OPTARG" ;;
O) opt_outandroid="$OPTARG" ;;
s) opt_showcommands=1 ;;
t) opt_maketarget="$OPTARG" ;;
v) opt_version="$OPTARG" ;;
*) usage
esac
done
shift $(($OPTIND-1))
if [ $# -ne 1 ]; then
usage
fi
if [ -n "$opt_outandroid" ]; then
export OUT_DIR_COMMON_BASE="$opt_outandroid"
fi
mkdir -p "$opt_outdir"
# NB: "$combo" is used by build scripts
build_combo="$1"
project_device=$(echo $build_combo | cut -d'-' -f1)
project=$(echo $project_device | cut -d'_' -f1)
device=$(echo $project_device | cut -d'_' -f2)
# Desired output files
if [ -n "$opt_version" ]; then
out_name="${opt_outdir}/${project_device}-${opt_version}"
else
out_name="${opt_outdir}/${project_device}"
fi
if [ "$opt_log" -ne 0 ]; then
rm -f "${out_name}.log"
exec >> "${out_name}.log" 2>&1
fi
if [ ! -d ".repo" ]; then
echo "Invalid build tree"
exit 1
fi
case "$opt_clean" in
0) # Do nothing
;;
1) # Clean device output
rm -rf "$OUT_DIR_COMMON_BASE/target/product"
;;
2) # Clean target output
rm -rf "$OUT_DIR_COMMON_BASE/target"
;;
*) # Clean all output
rm -rf "$OUT_DIR_COMMON_BASE"
;;
esac
# Detect make target
if [ -z "$opt_maketarget" -o "$opt_maketarget" = "auto" ]; then
opt_maketarget="otapackage"
if [ -f "build/core/Makefile" ]; then
if grep -q "^bacon:" "build/core/Makefile"; then
opt_maketarget="bacon"
fi
fi
fi
if [ "$opt_showcommands" -ne 0 ]; then
opt_maketarget="showcommands $opt_maketarget"
fi
# Ensure working directory is clean
if [ "$opt_automated" -ne 0 ]; then
android-repo status | grep -q "working directory clean"
fi
. build/envsetup.sh
lunch "$build_combo"
# Setup ccache
if [ -z "$CCACHE_ROOT" ]; then
CCACHE_ROOT="$HOME"
fi
export CCACHE_DIR="$CCACHE_ROOT/.ccache-$project_device"
if [ ! -d "$CCACHE_DIR" ]; then
mkdir -p "$CCACHE_DIR"
$CCACHE -M 8G
fi
# Clean some things
rm -f $OUT/system/build.prop
eval $(ccache_stats)
sch=$ch
scm=$cm
sct=$ct
scpct=$cpct
# Do the build
stime=$(date +%s)
make -j${opt_jobs} ${opt_maketarget}
etime=$(date +%s)
# Find output zip
built_zip=$(ls -t $OUT/*.zip | head -1)
if [ ! -f "$built_zip" ]; then
echo "Error: cannot find built zip in $OUT"
exit 1
fi
# Copy output zip to well known place
cp "$built_zip" "${out_name}.zip"
# Calculate elapsed time
elapsedsec=$((etime - stime))
elapsed=$(printf "%02d:%02d" $((elapsedsec/60)) $((elapsedsec%60)))
eval $(ccache_stats)
ech=$ch
ecm=$cm
ect=$ct
ecpct=$cpct
dch=$((ech - sch))
dcm=$((ecm - scm))
dct=$((ect - sct))
dcpct="NA"
if [ "$dct" -gt 0 ]; then
dcpct=$((dch*100/dct))
fi
echo "Build complete."
echo "elapsed time : $elapsed"
echo "ccache totals: $ech/$ect ($ecpct%)"
echo "ccache deltas: $dch/$dct ($dcpct%)"
case "$opt_postclean" in
0) # Do nothing
;;
1) # Clean device output
rm -rf "$OUT_DIR_COMMON_BASE/target/product"
;;
2) # Clean target output
rm -rf "$OUT_DIR_COMMON_BASE/target"
;;
*) # Clean all output
rm -rf "$OUT_DIR_COMMON_BASE"
;;
esac

264
android-changelog Executable file
View File

@ -0,0 +1,264 @@
#!/usr/bin/python
import os
import sys
import getopt
import subprocess
from xml.etree import ElementTree
def read_manifest(file):
manifest = ElementTree.parse(file)
defaults = manifest.findall('default')[0]
for project in manifest.findall('project'):
if not 'remote' in project.attrib:
project.attrib['remote'] = defaults.attrib['remote']
if not 'revision' in project.attrib:
project.attrib['revision'] = defaults.attrib['revision']
return manifest
def manifest_defaults(manifest):
defaults = dict()
defaults['remote'] = ''
defaults['revision'] = ''
for e in manifest.findall('default'):
if 'remote' in e:
defaults['remote'] = e.attrib['remote']
if 'revision' in e:
defaults['revision'] = e.attrib['revision']
oldpwd = os.getcwd()
os.chdir('.repo/manifests')
pipe = subprocess.Popen(['git', 'remote', '-v'], stdout=subprocess.PIPE)
line = pipe.stdout.readline()
fields = line.split()
defaults['fetch'] = os.path.dirname(fields[1])
os.chdir(oldpwd)
return defaults
def manifest_remotes(manifest, defaults):
remotes = dict()
for e in manifest.findall('remote'):
if not 'name' in e.attrib:
print "ERROR: remote with no name attrib"
continue
name = e.attrib['name']
if not 'fetch' in e.attrib:
print "ERROR: remote with no fetch attrib"
continue
e.attrib['fetch'] = e.attrib['fetch'].rstrip('/')
if e.attrib['fetch'] == '.':
e.attrib['fetch'] = defaults['fetch']
if e.attrib['fetch'] == '..':
e.attrib['fetch'] = os.path.dirname(defaults['fetch'])
remotes[name] = e
return remotes
def manifest_projects(manifest, remotes, defaults):
projects = dict()
for e in manifest.findall('project'):
if not 'name' in e.attrib:
print "ERROR: project with no name attrib"
continue
if not 'path' in e.attrib:
e.attrib['path'] = e.attrib['name']
path = e.attrib['path']
if path in projects:
print "ERROR: duplicate project path %s" % path
continue
if not 'remote' in e.attrib:
e.attrib['remote'] = defaults['remote']
remote_name = e.attrib['remote']
r = remotes[remote_name]
e.attrib['remote_url'] = r.attrib['fetch'] + '/' + e.attrib['name']
projects[path] = e
return projects
def is_same_project(p1, p2):
if p1.attrib['path'] != p2.attrib['path']:
return False
if p1.attrib['remote_url'] != p2.attrib['remote_url']:
return False
return True
def run_git_in_dir(path, args):
pipe = os.popen("chdir %s && git %s" % (path, args))
lines = pipe.readlines()
pipe.close()
return lines
class TextEmitter:
def emit_header(self, f1, f2):
print "# Changelog"
print "# Created ..."
print "# %s vs %s" % (f1, f2)
def emit_footer(self):
# empty
pass
def emit_project_change_header(self):
print "=" * 72
print "Project changes ..."
def emit_project_change_text(self, text):
print "%s" % text
def emit_project_change_footer(self):
print ""
def emit_dir_changes_header(self, name, r1, r2):
print "=" * 72
print "Changes in %s [%s .. %s]" % (name, r1, r2)
print "=" * 72
print ""
def emit_dir_changes_text(self, remote_url, text):
for line in text:
print line.rstrip()
def emit_dir_changes_footer(self):
print ""
class HtmlEmitter:
def emit_header(self, f1, f2):
print "<html>"
print " <head>"
print " <title>Changelog</title>"
print " </head>"
print " <body>"
def emit_footer(self):
print " </body>"
print "</html>"
def emit_project_change_header(self):
print " <h3>Project changes</h3>"
print " <hr>"
def emit_project_change_text(self, text):
print " %s<br>" % text
def emit_project_change_footer(self):
# empty
pass
def emit_dir_changes_header(self, name, r1, r2):
print " <h3>Changes in %s [%s .. %s]</h3>" % (name, r1, r2)
print " <hr>"
def emit_dir_changes_text(self, remote_url, text):
print " <pre>"
for line in text:
txt = line.rstrip()
if line[0:7] == 'commit ' and remote_url.find('github.com') != -1:
id = line[7:]
lnk = '%s/commit/%s' % (remote_url, id)
txt = '<a href="%s">%s</a>' % (lnk, id)
print " %s" % txt
print " </pre>"
def emit_dir_changes_footer(self):
# empty
pass
fmt = 'text'
showmerges = False
short = False
opts, args = getopt.getopt(sys.argv[1:], 'f:ms', ['format=', 'show-merges', 'short'])
for k, v in opts:
if k in ('-f', '--format'):
fmt = v
if k in ('-m', '--show-merges'):
showmerges = True
if k in ('-s', '--short'):
short = True
if len(args) != 2:
print "Usage: %s [-f text|html] [-m] manifest1 manifest2"
sys.exit(1)
f1 = args[0]
f2 = args[1]
manifest1 = read_manifest(f1)
manifest2 = read_manifest(f2)
defaults1 = manifest_defaults(manifest1)
defaults2 = manifest_defaults(manifest2)
remotes1 = manifest_remotes(manifest1, defaults1)
remotes2 = manifest_remotes(manifest2, defaults2)
projects1 = manifest_projects(manifest1, remotes1, defaults1)
projects2 = manifest_projects(manifest2, remotes2, defaults2)
diffable_projects = []
changed_projects = []
new_projects = []
del_projects = []
for path in projects1.iterkeys():
if path in projects2:
p1 = projects1[path]
p2 = projects2[path]
if is_same_project(p1, p2):
diffable_projects.append(path)
else:
changed_projects.append(path)
else:
del_projects.append(path)
for path in projects2.iterkeys():
if not path in projects1:
new_projects.append(path)
if fmt == 'text':
emitter = TextEmitter()
else:
emitter = HtmlEmitter()
emitter.emit_header(f1, f2)
if len(new_projects) > 0 or len(del_projects) > 0 or len(changed_projects) > 0:
emitter.emit_project_change_header()
for path in new_projects:
remote_url = projects2[path].attrib['remote_url']
emitter.emit_project_change_text("new project %s: %s" % (path, remote_url))
for path in del_projects:
remote_url = projects1[path].attrib['remote_url']
emitter.emit_project_change_text("deleted project %s: %s" % (path, remote_url))
for path in changed_projects:
old_remote_url = projects1[path].attrib['remote_url']
new_remote_url = projects2[path].attrib['remote_url']
emitter.emit_project_change_text("changed project %s: %s => %s" % (path, old_remote_url, new_remote_url))
emitter.emit_project_change_footer()
for path in sorted(diffable_projects):
p1 = projects1[path]
r1 = p1.attrib['revision']
p2 = projects2[path]
r2 = p2.attrib['revision']
if r1 != r2:
lines = run_git_in_dir(path, "show --pretty=format:%%h %s" % (r1))
r1a = lines[0].rstrip('\n')
lines = run_git_in_dir(path, "show --pretty=format:%%h %s" % (r2))
r2a = lines[0].rstrip('\n')
gitargs = "log "
if not showmerges:
gitargs += "--no-merges "
if short:
gitargs += "--pretty=oneline "
else:
gitargs += "--pretty=short "
gitargs += "--abbrev-commit "
gitargs += "%s..%s" % (p1.attrib['revision'], p2.attrib['revision'])
lines = run_git_in_dir(path, gitargs)
if len(lines) > 0:
emitter.emit_dir_changes_header(path, r1a, r2a)
emitter.emit_dir_changes_text(p1.attrib['remote_url'], lines)
emitter.emit_dir_changes_footer()
emitter.emit_footer()

45
android-tag Executable file
View File

@ -0,0 +1,45 @@
#!/bin/sh
topdir=$(pwd)
if [ "$#" -ne 1 ]; then
echo "Usage: $0 <create|restore>"
exit 1
fi
action="$1"
create_tag()
{
# XXX: should verify "git status" to ensure to uncommitted diffs
repo manifest -r | cat
}
restore_tag()
{
while read line; do
prj_entry=$(echo $line | grep "<project ")
if [ -z "$prj_entry" ]; then
continue
fi
dir=$(echo $prj_entry | egrep -o "path=([^ ]*)" | cut -d'"' -f2)
tag=$(echo $prj_entry | egrep -o "revision=([^ ]*)" | cut -d'"' -f2)
if [ -z "$dir" -o -z "$tag" ]; then
echo "Malformed line $line"
continue
fi
if [ ! -d "$topdir/$dir" ]; then
echo "No such dir $dir"
continue
fi
echo "$dir -> $tag"
cd "$topdir/$dir"
git checkout "$tag"
done
}
case "$action" in
create) create_tag ;;
restore) restore_tag ;;
*) usage ;;
esac

240
gerrit-fetch Executable file
View File

@ -0,0 +1,240 @@
#!/usr/bin/python
import os
import sys
import getopt
import subprocess
import urllib2
import json
import re
from xml.etree import ElementTree
cfg = dict()
cfg['nodo'] = False
cfg['post'] = None
cfg['remote'] = None
cfg['revision'] = None
cfg['ssh'] = False
cfg['verbose'] = 0
def verbose(s):
if cfg['verbose'] > 0:
sys.stderr.write(s)
def get_topdir():
dir = os.getcwd()
while not os.path.exists("%s/.repo" % (dir)):
dir = os.path.realpath("%s/.." % (dir))
if dir == '/':
raise OSError(2, 'No such file or directory', dir)
return dir
def usage():
print "Usage: gerrit-fetch [args] <change-num>"
print " --nodo Do not apply the change"
print " --post Apply change after fetching (cherry-pick|merge)"
print " --remote Use specified remote"
print " --revision Use specified change revision"
print " --ssh Use ssh, do not attempt http"
print " --verbose Increase verbose level"
sys.exit(1)
optargs, argv = getopt.getopt(sys.argv[1:], 'np:sv',
['nodo', 'post=', 'remote=', 'revision=', 'ssh', 'verbose'])
for k, v in optargs:
if k in ('-n', '--nodo'):
cfg['nodo'] = True
if k in ('-p', '--post'):
cfg['post'] = v
if k in ('--remote'):
cfg['remote'] = v
if k in ('--revision'):
cfg['revision'] = v
if k in ('-s', '--ssh'):
cfg['ssh'] = True
if k in ('-v', '--verbose'):
cfg['verbose'] += 1
if not cfg['post'] is None:
if cfg['post'] != 'cherry-pick' and cfg['post'] != 'merge':
usage()
if len(argv) != 1:
usage()
change_number = int(argv[0])
cur_dir = os.getcwd()
print "cur_dir=%s" % (cur_dir)
prj_dir = None
try:
top_dir = get_topdir()
except OSError:
sys.stderr.write("Cannot find top of android tree\n")
sys.exit(1)
print "top_dir=%s" % (top_dir)
if len(top_dir) < len(cur_dir):
prj_dir = cur_dir[len(top_dir)+1:]
print "prj_dir=%s" % (prj_dir)
# Read our manifest
args = []
args.append('repo')
args.append('manifest')
child = subprocess.Popen(args, stdin=None, stdout=subprocess.PIPE, stderr=None)
out, err = child.communicate()
if child.returncode != 0:
sys.stderr.write('Failed to read manifest\n')
sys.exit(1)
manifest = ElementTree.fromstring(out)
# Figure out which remote to use
remote_name = cfg['remote']
if remote_name is None:
if prj_dir is None:
for elem in manifest.findall('default'):
cfg['remote'] = elem.get('name')
else:
for elem in manifest.findall('project'):
if elem.get('path') == prj_dir:
remote_name = elem.get('remote')
if remote_name is None:
sys.stderr.write("Cannot find appropriate remote entry in manifest\n");
sys.exit(1);
verbose("remote_name=%s\n" % (remote_name))
review_url = None
review_host = None
for elem in manifest.findall('remote'):
if elem.get('name') == remote_name:
review_url = elem.get('review')
if review_url.find(':') == -1:
review_host = review_url
review_url = "http://%s" % (review_url)
else:
review_host = review_url.strip_url_schema()
if review_url is None or review_host is None:
sys.stderr.write("Cannot find appropriate remote url in manifest\n");
sys.exit(1);
verbose("review_url=%s, review_host=%s\n" % (review_url, review_host))
# Fetch the change props
props = None
project_name = None
change_revision = cfg['revision']
if not cfg['ssh']:
try:
# NB: o=DOWNLOAD_COMMANDS is not reliable so don't use it
url = '%s/changes/?q=%d&o=CURRENT_REVISION' % (review_url, change_number)
verbose("Attempting to fetch change from url=%s\n" % (url))
response = urllib2.urlopen(url)
doc = response.read()
if not doc.startswith(")]}'\n"):
sys.stderr.write('Error: malformed change props (url=%s)\n' % (url))
raise Exception('Malformed change props')
proplist = json.loads(doc[5:])
if len(proplist) == 1:
verbose("proplist loads and has one element\n");
props = proplist[0]
project_name = props['project']
if change_revision is None:
change_rev_id = props['current_revision']
change_rev = None
for rev in props['revisions']:
if rev == change_rev_id:
change_revision = props['revisions'][rev]['_number']
except:
sys.stderr.write('Failed to fetch change props\n')
if project_name is None:
args = []
args.append('ssh')
args.append(review_host)
args.append('gerrit')
args.append('query')
args.append('--format=JSON')
args.append('--current-patch-set')
args.append("%d" %(change_number))
verbose("Attempting to fetch change from cmd=\"%s\"\n" % (" ".join(args)))
child = subprocess.Popen(args, stdin=None, stdout=subprocess.PIPE, stderr=None)
out, err = child.communicate()
if child.returncode != 0:
sys.stderr.write('Failed to read manifest\n')
sys.exit(1)
lines = out.split('\n')
props = json.loads(lines[0])
project_name = props['project']
if change_revision is None:
change_revision = props['currentPatchSet']['number']
# If we used ssh to access the change, also use ssh to fetch it
review_url = "ssh://%s" % (review_host)
if project_name is None:
sys.stderr.write('Error: cannot fetch change properties\n')
sys.exit(1)
verbose("project=%s\n" % (project_name))
if change_revision is None:
sys.stderr.write('Error: cannot fetch change revision\n')
sys.exit(1)
verbose("change_revision=%s\n" % (change_revision))
project = None
for elem in manifest.findall('project'):
if elem.get('name') == project_name:
project = elem
if project is None:
sys.stderr.write('Error: project not found\n')
sys.exit(1)
project_path = project.get('path')
if prj_dir is None:
# Switch to the project directory
verbose("Switching to project directory %s\n" % (project_path))
try:
os.chdir(project_path)
except:
sys.stderr.write('Error: path not found\n')
sys.exit(1)
else:
# Verify correct directory
verbose("Verifying project directory %s vs %s\n" % (project_path, prj_dir))
if prj_dir != project_path:
sys.stderr.write("Error: change applies to %s, we are in %s\n" % (project_path, prj_dir))
sys.exit(1)
change_hash = "%02d" % (change_number % 100)
# Fetch the change
args = []
args.append('git')
args.append('fetch')
args.append('%s/%s' % (review_url, project_name))
args.append('refs/changes/%s/%s/%s' % (change_hash, change_number, change_revision))
if cfg['nodo']:
print ' '.join(args)
else:
child = subprocess.Popen(args, stdin=None, stdout=None, stderr=None)
out, err = child.communicate()
if child.returncode != 0:
sys.stderr.write('Failed to fetch change\n')
sys.exit(1)
if not cfg['post'] is None:
# Pick the change
args = []
args.append('git')
args.append(cfg['post'])
args.append('FETCH_HEAD')
if cfg['nodo']:
print ' '.join(args)
else:
child = subprocess.Popen(args, stdin=None, stdout=None, stderr=None)
out, err = child.communicate()
if child.returncode != 0:
sys.stderr.write("Failed to %s change\n" % (cfg['post']))
sys.exit(1)
verbose('Success\n')
sys.exit(0)

3
gerrit-pick Executable file
View File

@ -0,0 +1,3 @@
#!/bin/bash
exec gerrit-fetch --post=cherry-pick "$@"

3
gerrit-pull Executable file
View File

@ -0,0 +1,3 @@
#!/bin/bash
exec gerrit-fetch --post=pull "$@"

54
gerrit-push Executable file
View File

@ -0,0 +1,54 @@
#!/bin/bash
find_topdir()
{
while [ ! -d ".repo" ]; do
cd ".."
if [ $PWD = "/" ]; then
echo "Cannot find topdir"
exit 1
fi
done
pwd
}
SCHEME="ssh"
GIT="git"
if [ "$1" = "-t" ]; then
GIT="echo git"
shift
fi
if [ "$1" = "-h" ]; then
SCHEME="https"
fi
topdir=$(find_topdir)
len=$(( ${#topdir} + 1 ))
prj_path=${PWD:$len}
prj_entry=$(repo manifest | grep "project .*path=\"$prj_path\"")
if [ -z "$prj_entry" ]; then
echo "Cannot find project entry for $prj_path"
exit 1
fi
def_entry=$(repo manifest | grep "default ")
def_remote_name=$(echo $def_entry | egrep -o "remote=([^ ]*)" | cut -d'"' -f2)
def_remote_entry=$(repo manifest | grep "remote .*name=\"$def_remote_name\"")
prj_name=$(echo $prj_entry | egrep -o "name=([^ ]*)" | cut -d'"' -f2)
prj_remote_name=$(echo $prj_entry | egrep -o "remote=([^ ]*)" | cut -d'"' -f2)
prj_revision=$(echo $prj_entry | egrep -o "revision=([^ ]*)" | cut -d'"' -f2)
if [ -z "$prj_revision" ]; then
prj_revision=$(echo $def_entry | egrep -o "revision=([^ ]*)" | cut -d'"' -f2)
fi
prj_revision="${prj_revision##refs/heads/}"
if [ -n "$prj_remote_name" ]; then
remote_entry=$(repo manifest | grep "remote .*name=\"$prj_remote_name\"")
else
remote_entry=$(repo manifest | grep "remote .*name=\"$def_remote_name\"")
fi
remote_review=$(echo $remote_entry | egrep -o "review=([^ ]*)" | cut -d'"' -f2)
$GIT push "$SCHEME://$remote_review:29418/$prj_name" "HEAD:refs/for/$prj_revision"