mirror of
https://gerrit.googlesource.com/git-repo
synced 2025-06-30 20:17:08 +00:00
Compare commits
10 Commits
Author | SHA1 | Date | |
---|---|---|---|
c3d2f2b76f | |||
cd7c5deca0 | |||
e02ac0af2e | |||
898e12a2d9 | |||
ae0a36c9a5 | |||
76abcc1d1e | |||
d315382572 | |||
43bda84362 | |||
9b017dab46 | |||
e9dc3b3368 |
@ -5,7 +5,7 @@ Short Version:
|
|||||||
- Make sure all code is under the Apache License, 2.0.
|
- Make sure all code is under the Apache License, 2.0.
|
||||||
- Publish your changes for review:
|
- Publish your changes for review:
|
||||||
|
|
||||||
git push ssh://review.source.android.com:29418/tools/repo.git HEAD:refs/for/master
|
git push https://gerrit-review.googlesource.com/git-repo HEAD:refs/for/maint
|
||||||
|
|
||||||
|
|
||||||
Long Version:
|
Long Version:
|
||||||
@ -55,24 +55,23 @@ Do not email your patches to anyone.
|
|||||||
|
|
||||||
Instead, login to the Gerrit Code Review tool at:
|
Instead, login to the Gerrit Code Review tool at:
|
||||||
|
|
||||||
https://review.source.android.com/
|
https://gerrit-review.googlesource.com/
|
||||||
|
|
||||||
Ensure you have completed one of the necessary contributor
|
Ensure you have completed one of the necessary contributor
|
||||||
agreements, providing documentation to the project maintainers that
|
agreements, providing documentation to the project maintainers that
|
||||||
they have right to redistribute your work under the Apache License:
|
they have right to redistribute your work under the Apache License:
|
||||||
|
|
||||||
https://review.source.android.com/#settings,agreements
|
https://gerrit-review.googlesource.com/#/settings/agreements
|
||||||
|
|
||||||
Ensure you have registered one or more SSH public keys, so you can
|
Ensure you have obtained an HTTP password to authenticate:
|
||||||
push your commits directly over SSH:
|
|
||||||
|
|
||||||
https://review.source.android.com/#settings,ssh-keys
|
https://gerrit-review.googlesource.com/new-password
|
||||||
|
|
||||||
Push your patches over SSH to the review server, possibly through
|
Push your patches over HTTPS to the review server, possibly through
|
||||||
a remembered remote to make this easier in the future:
|
a remembered remote to make this easier in the future:
|
||||||
|
|
||||||
git config remote.review.url ssh://review.source.android.com:29418/tools/repo.git
|
git config remote.review.url https://gerrit-review.googlesource.com/git-repo
|
||||||
git config remote.review.push HEAD:refs/for/master
|
git config remote.review.push HEAD:refs/for/maint
|
||||||
|
|
||||||
git push review
|
git push review
|
||||||
|
|
||||||
|
@ -488,7 +488,7 @@ def close_ssh():
|
|||||||
_master_keys_lock = None
|
_master_keys_lock = None
|
||||||
|
|
||||||
URI_SCP = re.compile(r'^([^@:]*@?[^:/]{1,}):')
|
URI_SCP = re.compile(r'^([^@:]*@?[^:/]{1,}):')
|
||||||
URI_ALL = re.compile(r'^([a-z][a-z+]*)://([^@/]*@?[^/]*)/')
|
URI_ALL = re.compile(r'^([a-z][a-z+-]*)://([^@/]*@?[^/]*)/')
|
||||||
|
|
||||||
def GetSchemeFromUrl(url):
|
def GetSchemeFromUrl(url):
|
||||||
m = URI_ALL.match(url)
|
m = URI_ALL.match(url)
|
||||||
|
23
main.py
23
main.py
@ -295,6 +295,24 @@ class _BasicAuthHandler(urllib2.HTTPBasicAuthHandler):
|
|||||||
self.retried = 0
|
self.retried = 0
|
||||||
raise
|
raise
|
||||||
|
|
||||||
|
class _DigestAuthHandler(urllib2.HTTPDigestAuthHandler):
|
||||||
|
def http_error_auth_reqed(self, auth_header, host, req, headers):
|
||||||
|
try:
|
||||||
|
old_add_header = req.add_header
|
||||||
|
def _add_header(name, val):
|
||||||
|
val = val.replace('\n', '')
|
||||||
|
old_add_header(name, val)
|
||||||
|
req.add_header = _add_header
|
||||||
|
return urllib2.AbstractDigestAuthHandler.http_error_auth_reqed(
|
||||||
|
self, auth_header, host, req, headers)
|
||||||
|
except:
|
||||||
|
reset = getattr(self, 'reset_retry_count', None)
|
||||||
|
if reset is not None:
|
||||||
|
reset()
|
||||||
|
elif getattr(self, 'retried', None):
|
||||||
|
self.retried = 0
|
||||||
|
raise
|
||||||
|
|
||||||
def init_http():
|
def init_http():
|
||||||
handlers = [_UserAgentHandler()]
|
handlers = [_UserAgentHandler()]
|
||||||
|
|
||||||
@ -303,13 +321,14 @@ def init_http():
|
|||||||
n = netrc.netrc()
|
n = netrc.netrc()
|
||||||
for host in n.hosts:
|
for host in n.hosts:
|
||||||
p = n.hosts[host]
|
p = n.hosts[host]
|
||||||
mgr.add_password(None, 'http://%s/' % host, p[0], p[2])
|
mgr.add_password(p[1], 'http://%s/' % host, p[0], p[2])
|
||||||
mgr.add_password(None, 'https://%s/' % host, p[0], p[2])
|
mgr.add_password(p[1], 'https://%s/' % host, p[0], p[2])
|
||||||
except netrc.NetrcParseError:
|
except netrc.NetrcParseError:
|
||||||
pass
|
pass
|
||||||
except IOError:
|
except IOError:
|
||||||
pass
|
pass
|
||||||
handlers.append(_BasicAuthHandler(mgr))
|
handlers.append(_BasicAuthHandler(mgr))
|
||||||
|
handlers.append(_DigestAuthHandler(mgr))
|
||||||
|
|
||||||
if 'http_proxy' in os.environ:
|
if 'http_proxy' in os.environ:
|
||||||
url = os.environ['http_proxy']
|
url = os.environ['http_proxy']
|
||||||
|
@ -498,6 +498,12 @@ class XmlManifest(object):
|
|||||||
"project %s path cannot be absolute in %s" % \
|
"project %s path cannot be absolute in %s" % \
|
||||||
(name, self.manifestFile)
|
(name, self.manifestFile)
|
||||||
|
|
||||||
|
rebase = node.getAttribute('rebase')
|
||||||
|
if not rebase:
|
||||||
|
rebase = True
|
||||||
|
else:
|
||||||
|
rebase = rebase.lower() in ("yes", "true", "1")
|
||||||
|
|
||||||
if self.IsMirror:
|
if self.IsMirror:
|
||||||
relpath = None
|
relpath = None
|
||||||
worktree = None
|
worktree = None
|
||||||
@ -513,7 +519,8 @@ class XmlManifest(object):
|
|||||||
worktree = worktree,
|
worktree = worktree,
|
||||||
relpath = path,
|
relpath = path,
|
||||||
revisionExpr = revisionExpr,
|
revisionExpr = revisionExpr,
|
||||||
revisionId = None)
|
revisionId = None,
|
||||||
|
rebase = rebase)
|
||||||
|
|
||||||
for n in node.childNodes:
|
for n in node.childNodes:
|
||||||
if n.nodeName == 'copyfile':
|
if n.nodeName == 'copyfile':
|
||||||
|
29
project.py
29
project.py
@ -503,7 +503,8 @@ class Project(object):
|
|||||||
worktree,
|
worktree,
|
||||||
relpath,
|
relpath,
|
||||||
revisionExpr,
|
revisionExpr,
|
||||||
revisionId):
|
revisionId,
|
||||||
|
rebase = True):
|
||||||
self.manifest = manifest
|
self.manifest = manifest
|
||||||
self.name = name
|
self.name = name
|
||||||
self.remote = remote
|
self.remote = remote
|
||||||
@ -522,6 +523,8 @@ class Project(object):
|
|||||||
else:
|
else:
|
||||||
self.revisionId = revisionId
|
self.revisionId = revisionId
|
||||||
|
|
||||||
|
self.rebase = rebase
|
||||||
|
|
||||||
self.snapshots = {}
|
self.snapshots = {}
|
||||||
self.copyfiles = []
|
self.copyfiles = []
|
||||||
self.config = GitConfig.ForRepository(
|
self.config = GitConfig.ForRepository(
|
||||||
@ -688,7 +691,7 @@ class Project(object):
|
|||||||
di = self.work_git.DiffZ('diff-index', '-M', '--cached', HEAD)
|
di = self.work_git.DiffZ('diff-index', '-M', '--cached', HEAD)
|
||||||
df = self.work_git.DiffZ('diff-files')
|
df = self.work_git.DiffZ('diff-files')
|
||||||
do = self.work_git.LsOthers()
|
do = self.work_git.LsOthers()
|
||||||
if not rb and not di and not df and not do:
|
if not rb and not di and not df and not do and not self.CurrentBranch:
|
||||||
return 'CLEAN'
|
return 'CLEAN'
|
||||||
|
|
||||||
out = StatusColoring(self.config)
|
out = StatusColoring(self.config)
|
||||||
@ -899,7 +902,11 @@ class Project(object):
|
|||||||
|
|
||||||
## Sync ##
|
## Sync ##
|
||||||
|
|
||||||
def Sync_NetworkHalf(self, quiet=False, is_new=None, current_branch_only=False):
|
def Sync_NetworkHalf(self,
|
||||||
|
quiet=False,
|
||||||
|
is_new=None,
|
||||||
|
current_branch_only=False,
|
||||||
|
clone_bundle=True):
|
||||||
"""Perform only the network IO portion of the sync process.
|
"""Perform only the network IO portion of the sync process.
|
||||||
Local working directory/branch state is not affected.
|
Local working directory/branch state is not affected.
|
||||||
"""
|
"""
|
||||||
@ -922,7 +929,9 @@ class Project(object):
|
|||||||
else:
|
else:
|
||||||
alt_dir = None
|
alt_dir = None
|
||||||
|
|
||||||
if alt_dir is None and self._ApplyCloneBundle(initial=is_new, quiet=quiet):
|
if clone_bundle \
|
||||||
|
and alt_dir is None \
|
||||||
|
and self._ApplyCloneBundle(initial=is_new, quiet=quiet):
|
||||||
is_new = False
|
is_new = False
|
||||||
|
|
||||||
if not self._RemoteFetch(initial=is_new, quiet=quiet, alt_dir=alt_dir,
|
if not self._RemoteFetch(initial=is_new, quiet=quiet, alt_dir=alt_dir,
|
||||||
@ -1093,10 +1102,12 @@ class Project(object):
|
|||||||
len(local_changes) - cnt_mine)
|
len(local_changes) - cnt_mine)
|
||||||
|
|
||||||
branch.remote = self.GetRemote(self.remote.name)
|
branch.remote = self.GetRemote(self.remote.name)
|
||||||
branch.merge = self.revisionExpr
|
if not ID_RE.match(self.revisionExpr):
|
||||||
|
# in case of manifest sync the revisionExpr might be a SHA1
|
||||||
|
branch.merge = self.revisionExpr
|
||||||
branch.Save()
|
branch.Save()
|
||||||
|
|
||||||
if cnt_mine > 0:
|
if cnt_mine > 0 and self.rebase:
|
||||||
def _dorebase():
|
def _dorebase():
|
||||||
self._Rebase(upstream = '%s^1' % last_mine, onto = revid)
|
self._Rebase(upstream = '%s^1' % last_mine, onto = revid)
|
||||||
self._CopyFiles()
|
self._CopyFiles()
|
||||||
@ -1446,6 +1457,8 @@ class Project(object):
|
|||||||
remote = self.GetRemote(self.remote.name)
|
remote = self.GetRemote(self.remote.name)
|
||||||
bundle_url = remote.url + '/clone.bundle'
|
bundle_url = remote.url + '/clone.bundle'
|
||||||
bundle_url = GitConfig.ForUser().UrlInsteadOf(bundle_url)
|
bundle_url = GitConfig.ForUser().UrlInsteadOf(bundle_url)
|
||||||
|
if GetSchemeFromUrl(bundle_url) in ('persistent-http', 'persistent-https'):
|
||||||
|
bundle_url = bundle_url[len('persistent-'):]
|
||||||
if GetSchemeFromUrl(bundle_url) not in ('http', 'https'):
|
if GetSchemeFromUrl(bundle_url) not in ('http', 'https'):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@ -1503,7 +1516,7 @@ class Project(object):
|
|||||||
except:
|
except:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
if e.code == 404:
|
if e.code in (401, 403, 404):
|
||||||
keep = False
|
keep = False
|
||||||
return False
|
return False
|
||||||
elif _content_type() == 'text/plain':
|
elif _content_type() == 'text/plain':
|
||||||
@ -1529,7 +1542,7 @@ class Project(object):
|
|||||||
|
|
||||||
p = None
|
p = None
|
||||||
try:
|
try:
|
||||||
size = r.headers['content-length']
|
size = r.headers.get('content-length', 0)
|
||||||
unit = 1 << 10
|
unit = 1 << 10
|
||||||
|
|
||||||
if size and not quiet:
|
if size and not quiet:
|
||||||
|
9
repo
9
repo
@ -28,7 +28,7 @@ if __name__ == '__main__':
|
|||||||
del magic
|
del magic
|
||||||
|
|
||||||
# increment this whenever we make important changes to this script
|
# increment this whenever we make important changes to this script
|
||||||
VERSION = (1, 13)
|
VERSION = (1, 14)
|
||||||
|
|
||||||
# increment this if the MAINTAINER_KEYS block is modified
|
# increment this if the MAINTAINER_KEYS block is modified
|
||||||
KEYRING_VERSION = (1,0)
|
KEYRING_VERSION = (1,0)
|
||||||
@ -154,7 +154,7 @@ def _Init(args):
|
|||||||
"""Installs repo by cloning it over the network.
|
"""Installs repo by cloning it over the network.
|
||||||
"""
|
"""
|
||||||
opt, args = init_optparse.parse_args(args)
|
opt, args = init_optparse.parse_args(args)
|
||||||
if args or not opt.manifest_url:
|
if args:
|
||||||
init_optparse.print_usage()
|
init_optparse.print_usage()
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
@ -311,11 +311,12 @@ def _InitHttp():
|
|||||||
n = netrc.netrc()
|
n = netrc.netrc()
|
||||||
for host in n.hosts:
|
for host in n.hosts:
|
||||||
p = n.hosts[host]
|
p = n.hosts[host]
|
||||||
mgr.add_password(None, 'http://%s/' % host, p[0], p[2])
|
mgr.add_password(p[1], 'http://%s/' % host, p[0], p[2])
|
||||||
mgr.add_password(None, 'https://%s/' % host, p[0], p[2])
|
mgr.add_password(p[1], 'https://%s/' % host, p[0], p[2])
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
handlers.append(urllib2.HTTPBasicAuthHandler(mgr))
|
handlers.append(urllib2.HTTPBasicAuthHandler(mgr))
|
||||||
|
handlers.append(urllib2.HTTPDigestAuthHandler(mgr))
|
||||||
|
|
||||||
if 'http_proxy' in os.environ:
|
if 'http_proxy' in os.environ:
|
||||||
url = os.environ['http_proxy']
|
url = os.environ['http_proxy']
|
||||||
|
@ -101,19 +101,6 @@ the following meanings:
|
|||||||
all = self.GetProjects(args)
|
all = self.GetProjects(args)
|
||||||
counter = itertools.count()
|
counter = itertools.count()
|
||||||
|
|
||||||
on = {}
|
|
||||||
for project in all:
|
|
||||||
cb = project.CurrentBranch
|
|
||||||
if cb:
|
|
||||||
if cb not in on:
|
|
||||||
on[cb] = []
|
|
||||||
on[cb].append(project)
|
|
||||||
|
|
||||||
branch_names = list(on.keys())
|
|
||||||
branch_names.sort()
|
|
||||||
for cb in branch_names:
|
|
||||||
print '# on branch %s' % cb
|
|
||||||
|
|
||||||
if opt.jobs == 1:
|
if opt.jobs == 1:
|
||||||
for project in all:
|
for project in all:
|
||||||
state = project.PrintWorkTreeStatus()
|
state = project.PrintWorkTreeStatus()
|
||||||
|
@ -86,6 +86,12 @@ specify a custom tag/label.
|
|||||||
The -f/--force-broken option can be used to proceed with syncing
|
The -f/--force-broken option can be used to proceed with syncing
|
||||||
other projects if a project sync fails.
|
other projects if a project sync fails.
|
||||||
|
|
||||||
|
The --no-clone-bundle option disables any attempt to use
|
||||||
|
$URL/clone.bundle to bootstrap a new Git repository from a
|
||||||
|
resumeable bundle file on a content delivery network. This
|
||||||
|
may be necessary if there are problems with the local Python
|
||||||
|
HTTP client or proxy configuration, but the Git binary works.
|
||||||
|
|
||||||
SSH Connections
|
SSH Connections
|
||||||
---------------
|
---------------
|
||||||
|
|
||||||
@ -140,6 +146,12 @@ later is required to fix a server side protocol bug.
|
|||||||
p.add_option('-j','--jobs',
|
p.add_option('-j','--jobs',
|
||||||
dest='jobs', action='store', type='int',
|
dest='jobs', action='store', type='int',
|
||||||
help="projects to fetch simultaneously (default %d)" % self.jobs)
|
help="projects to fetch simultaneously (default %d)" % self.jobs)
|
||||||
|
p.add_option('-m', '--manifest-name',
|
||||||
|
dest='manifest_name',
|
||||||
|
help='temporary manifest to use for this sync', metavar='NAME.xml')
|
||||||
|
p.add_option('--no-clone-bundle',
|
||||||
|
dest='no_clone_bundle', action='store_true',
|
||||||
|
help='disable use of /clone.bundle on HTTP/HTTPS')
|
||||||
if show_smart:
|
if show_smart:
|
||||||
p.add_option('-s', '--smart-sync',
|
p.add_option('-s', '--smart-sync',
|
||||||
dest='smart_sync', action='store_true',
|
dest='smart_sync', action='store_true',
|
||||||
@ -182,8 +194,10 @@ later is required to fix a server side protocol bug.
|
|||||||
# - We always make sure we unlock the lock if we locked it.
|
# - We always make sure we unlock the lock if we locked it.
|
||||||
try:
|
try:
|
||||||
try:
|
try:
|
||||||
success = project.Sync_NetworkHalf(quiet=opt.quiet,
|
success = project.Sync_NetworkHalf(
|
||||||
current_branch_only=opt.current_branch_only)
|
quiet=opt.quiet,
|
||||||
|
current_branch_only=opt.current_branch_only,
|
||||||
|
clone_bundle=not opt.no_clone_bundle)
|
||||||
|
|
||||||
# Lock around all the rest of the code, since printing, updating a set
|
# Lock around all the rest of the code, since printing, updating a set
|
||||||
# and Progress.update() are not thread safe.
|
# and Progress.update() are not thread safe.
|
||||||
@ -333,6 +347,15 @@ uncommitted changes are present' % project.relpath
|
|||||||
if opt.network_only and opt.local_only:
|
if opt.network_only and opt.local_only:
|
||||||
print >>sys.stderr, 'error: cannot combine -n and -l'
|
print >>sys.stderr, 'error: cannot combine -n and -l'
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
if opt.manifest_name and opt.smart_sync:
|
||||||
|
print >>sys.stderr, 'error: cannot combine -m and -s'
|
||||||
|
sys.exit(1)
|
||||||
|
if opt.manifest_name and opt.smart_tag:
|
||||||
|
print >>sys.stderr, 'error: cannot combine -m and -t'
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
if opt.manifest_name:
|
||||||
|
self.manifest.Override(opt.manifest_name)
|
||||||
|
|
||||||
if opt.smart_sync or opt.smart_tag:
|
if opt.smart_sync or opt.smart_tag:
|
||||||
if not self.manifest.manifest_server:
|
if not self.manifest.manifest_server:
|
||||||
|
Reference in New Issue
Block a user