From 2daf66740bba0b2726462a547910d16cf0822db2 Mon Sep 17 00:00:00 2001 From: Matthew Buckett Date: Sat, 11 Jul 2009 09:43:47 -0400 Subject: Allow files to be copied into new folders Change-Id: I7f169e32be5a4328bb87ce7c2ff4b6529e925126 --- project.py | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'project.py') diff --git a/project.py b/project.py index ff896d01..1bcd9596 100644 --- a/project.py +++ b/project.py @@ -203,6 +203,10 @@ class _CopyFile: # remove existing file first, since it might be read-only if os.path.exists(dest): os.remove(dest) + else: + dir = os.path.dirname(dest) + if not os.path.isdir(dir): + os.makedirs(dir) shutil.copy(src, dest) # make the file read-only mode = os.stat(dest)[stat.ST_MODE] -- cgit v1.2.3-54-g00ecf From 0cb1b3f687da4634e431953ef84fee59dd3f5d59 Mon Sep 17 00:00:00 2001 From: Julius Gustavsson Date: Thu, 17 Jun 2010 17:55:02 +0200 Subject: sync: Try fetching a tag as a last resort before giving up If a tagged commit is not reachable by the fetch refspec configured for the git (usually refs/heads/*) it will not be downloaded by 'git fetch'. The tag can however be downloaded with 'git fetch --tags' or 'git fetch tag '. This patch fixes the situation when a tag is not found after a 'git fetch'. Repo will issue 'git fetch tag ' before giving up completely. Change-Id: I87796a5e1d51fcf398f346a274b7a069df37599a Signed-off-by: Shawn O. Pearce --- project.py | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) (limited to 'project.py') diff --git a/project.py b/project.py index 1bcd9596..956f45bf 100644 --- a/project.py +++ b/project.py @@ -283,7 +283,7 @@ class Project(object): return os.path.exists(os.path.join(g, 'rebase-apply')) \ or os.path.exists(os.path.join(g, 'rebase-merge')) \ or os.path.exists(os.path.join(w, '.dotest')) - + def IsDirty(self, consider_untracked=True): """Is the working directory modified in some way? """ @@ -416,7 +416,7 @@ class Project(object): try: f = df[p] except KeyError: f = None - + if i: i_status = i.status.upper() else: i_status = '-' @@ -601,6 +601,18 @@ class Project(object): if not self._RemoteFetch(): return False + #Check that the requested ref was found after fetch + # + try: + self.GetRevisionId() + except ManifestInvalidRevisionError: + # if the ref is a tag. We can try fetching + # the tag manually as a last resort + # + rev = self.revisionExpr + if rev.startswith(R_TAGS): + self._RemoteFetch(None, rev[len(R_TAGS):]) + if self.worktree: self._InitMRef() else: @@ -982,7 +994,7 @@ class Project(object): ## Direct Git Commands ## - def _RemoteFetch(self, name=None): + def _RemoteFetch(self, name=None, tag=None): if not name: name = self.remote.name @@ -994,6 +1006,9 @@ class Project(object): if not self.worktree: cmd.append('--update-head-ok') cmd.append(name) + if tag is not None: + cmd.append('tag') + cmd.append(tag) return GitCommand(self, cmd, bare = True, -- cgit v1.2.3-54-g00ecf From cc50bac8c7706082596d70756249d4964a67f281 Mon Sep 17 00:00:00 2001 From: Anthony Newnam Date: Thu, 8 Apr 2010 10:28:59 -0500 Subject: Warn users before uploading if there are local changes Change-Id: I231d7b6a3211e9f5ec71a542a0109b0c195d5e40 Signed-off-by: Shawn O. Pearce --- project.py | 21 +++++++++++++++++++++ subcmds/upload.py | 15 +++++++++++++++ 2 files changed, 36 insertions(+) (limited to 'project.py') diff --git a/project.py b/project.py index 956f45bf..4e8fa0e0 100644 --- a/project.py +++ b/project.py @@ -368,6 +368,27 @@ class Project(object): ## Status Display ## + def HasChanges(self): + """Returns true if there are uncommitted changes. + """ + self.work_git.update_index('-q', + '--unmerged', + '--ignore-missing', + '--refresh') + if self.IsRebaseInProgress(): + return True + + if self.work_git.DiffZ('diff-index', '--cached', HEAD): + return True + + if self.work_git.DiffZ('diff-files'): + return True + + if self.work_git.LsOthers(): + return True + + return False + def PrintWorkTreeStatus(self): """Prints the status of the repository to stdout. """ diff --git a/subcmds/upload.py b/subcmds/upload.py index ba532461..5a426113 100644 --- a/subcmds/upload.py +++ b/subcmds/upload.py @@ -320,6 +320,21 @@ Gerrit Code Review: http://code.google.com/p/gerrit/ people = copy.deepcopy(original_people) self._AppendAutoCcList(branch, people) + # Check if there are local changes that may have been forgotten + if branch.project.HasChanges(): + key = 'review.%s.autoupload' % branch.project.remote.review + answer = branch.project.config.GetBoolean(key) + + # if they want to auto upload, let's not ask because it could be automated + if answer is None: + sys.stdout.write('Uncommitted changes in ' + branch.project.name + ' (did you forget to amend?). Continue uploading? (y/n) ') + a = sys.stdin.readline().strip().lower() + if a not in ('y', 'yes', 't', 'true', 'on'): + print >>sys.stderr, "skipping upload" + branch.uploaded = False + branch.error = 'User aborted' + continue + branch.UploadForReview(people) branch.uploaded = True except UploadError, e: -- cgit v1.2.3-54-g00ecf From a5ece0e0505324218f38af02a1fe046ca2bcc278 Mon Sep 17 00:00:00 2001 From: "Shawn O. Pearce" Date: Thu, 15 Jul 2010 16:52:42 -0700 Subject: upload -t: Automatically include local branch name If the -t flag is given to upload, the local branch name is automatically sent to Gerrit Code Review as the topic branch name for the change(s). This requires the server to be Gerrit Code Review v2.1.3-53-gd50c94e or later, which isn't widely deployed right now, so the default is opt-out. Change-Id: I034fcacb405b7cb909147152db427fe69dd7bcbf Signed-off-by: Shawn O. Pearce --- project.py | 17 +++++++++++++---- subcmds/upload.py | 21 ++++++++++++--------- 2 files changed, 25 insertions(+), 13 deletions(-) (limited to 'project.py') diff --git a/project.py b/project.py index 4e8fa0e0..1b5d9a67 100644 --- a/project.py +++ b/project.py @@ -149,10 +149,11 @@ class ReviewableBranch(object): R_HEADS + self.name, '--') - def UploadForReview(self, people): + def UploadForReview(self, people, auto_topic=False): self.project.UploadForReview(self.name, self.replace_changes, - people) + people, + auto_topic=auto_topic) def GetPublishedRefs(self): refs = {} @@ -555,7 +556,10 @@ class Project(object): return rb return None - def UploadForReview(self, branch=None, replace_changes=None, people=([],[])): + def UploadForReview(self, branch=None, + replace_changes=None, + people=([],[]), + auto_topic=False): """Uploads the named branch for code review. """ if branch is None: @@ -587,10 +591,15 @@ class Project(object): for e in people[1]: rp.append('--cc=%s' % sq(e)) + ref_spec = '%s:refs/for/%s' % (R_HEADS + branch.name, dest_branch) + if auto_topic: + ref_spec = ref_spec + '/' + branch.name + cmd = ['push'] cmd.append('--receive-pack=%s' % " ".join(rp)) cmd.append(branch.remote.SshReviewUrl(self.UserEmail)) - cmd.append('%s:refs/for/%s' % (R_HEADS + branch.name, dest_branch)) + cmd.append(ref_spec) + if replace_changes: for change_id,commit_id in replace_changes.iteritems(): cmd.append('%s:refs/changes/%s/new' % (commit_id, change_id)) diff --git a/subcmds/upload.py b/subcmds/upload.py index 5a426113..569e31c1 100644 --- a/subcmds/upload.py +++ b/subcmds/upload.py @@ -111,6 +111,9 @@ Gerrit Code Review: http://code.google.com/p/gerrit/ """ def _Options(self, p): + p.add_option('-t', + dest='auto_topic', action='store_true', + help='Send local branch name to Gerrit Code Review') p.add_option('--replace', dest='replace', action='store_true', help='Upload replacement patchesets from this branch') @@ -121,7 +124,7 @@ Gerrit Code Review: http://code.google.com/p/gerrit/ type='string', action='append', dest='cc', help='Also send email to these email addresses.') - def _SingleBranch(self, branch, people): + def _SingleBranch(self, opt, branch, people): project = branch.project name = branch.name remote = project.GetBranch(name).remote @@ -154,11 +157,11 @@ Gerrit Code Review: http://code.google.com/p/gerrit/ answer = _ConfirmManyUploads() if answer: - self._UploadAndReport([branch], people) + self._UploadAndReport(opt, [branch], people) else: _die("upload aborted by user") - def _MultipleBranches(self, pending, people): + def _MultipleBranches(self, opt, pending, people): projects = {} branches = {} @@ -227,7 +230,7 @@ Gerrit Code Review: http://code.google.com/p/gerrit/ if not _ConfirmManyUploads(multiple_branches=True): _die("upload aborted by user") - self._UploadAndReport(todo, people) + self._UploadAndReport(opt, todo, people) def _AppendAutoCcList(self, branch, people): """ @@ -311,9 +314,9 @@ Gerrit Code Review: http://code.google.com/p/gerrit/ _die("upload aborted by user") branch.replace_changes = to_replace - self._UploadAndReport([branch], people) + self._UploadAndReport(opt, [branch], people) - def _UploadAndReport(self, todo, original_people): + def _UploadAndReport(self, opt, todo, original_people): have_errors = False for branch in todo: try: @@ -335,7 +338,7 @@ Gerrit Code Review: http://code.google.com/p/gerrit/ branch.error = 'User aborted' continue - branch.UploadForReview(people) + branch.UploadForReview(people, auto_topic=opt.auto_topic) branch.uploaded = True except UploadError, e: branch.error = e @@ -391,6 +394,6 @@ Gerrit Code Review: http://code.google.com/p/gerrit/ if not pending: print >>sys.stdout, "no branches ready for upload" elif len(pending) == 1 and len(pending[0][1]) == 1: - self._SingleBranch(pending[0][1][0], people) + self._SingleBranch(opt, pending[0][1][0], people) else: - self._MultipleBranches(pending, people) + self._MultipleBranches(opt, pending, people) -- cgit v1.2.3-54-g00ecf From 88443387b1b0508f43b57e104821c6b375806fea Mon Sep 17 00:00:00 2001 From: "Shawn O. Pearce" Date: Fri, 8 Oct 2010 10:02:09 +0200 Subject: sync: Enable use of git clone --reference Use git clone to initialize a new repository, and when possible allow callers to use --reference to reuse an existing checkout as the initial object storage area for the new checkout. Change-Id: Ie27f760247f311ce484c6d3e85a90d94da2febfc Signed-off-by: Shawn O. Pearce --- project.py | 101 ++++++++++++++++++++++++++++++++++++++++++++++++++++---- repo | 5 ++- subcmds/init.py | 14 +++++++- 3 files changed, 111 insertions(+), 9 deletions(-) (limited to 'project.py') diff --git a/project.py b/project.py index 1b5d9a67..8ffed842 100644 --- a/project.py +++ b/project.py @@ -622,13 +622,14 @@ class Project(object): """Perform only the network IO portion of the sync process. Local working directory/branch state is not affected. """ - if not self.Exists: + is_new = not self.Exists + if is_new: print >>sys.stderr print >>sys.stderr, 'Initializing project %s ...' % self.name self._InitGitDir() self._InitRemote() - if not self._RemoteFetch(): + if not self._RemoteFetch(initial = is_new): return False #Check that the requested ref was found after fetch @@ -1024,7 +1025,7 @@ class Project(object): ## Direct Git Commands ## - def _RemoteFetch(self, name=None, tag=None): + def _RemoteFetch(self, name=None, tag=None, initial=False): if not name: name = self.remote.name @@ -1032,6 +1033,60 @@ class Project(object): if self.GetRemote(name).PreConnectFetch(): ssh_proxy = True + if initial: + alt = os.path.join(self.gitdir, 'objects/info/alternates') + try: + fd = open(alt, 'rb') + try: + ref_dir = fd.readline() + if ref_dir and ref_dir.endswith('\n'): + ref_dir = ref_dir[:-1] + finally: + fd.close() + except IOError, e: + ref_dir = None + + if ref_dir and 'objects' == os.path.basename(ref_dir): + ref_dir = os.path.dirname(ref_dir) + packed_refs = os.path.join(self.gitdir, 'packed-refs') + remote = self.GetRemote(name) + + all = self.bare_ref.all + ids = set(all.values()) + tmp = set() + + for r, id in GitRefs(ref_dir).all.iteritems(): + if r not in all: + if r.startswith(R_TAGS) or remote.WritesTo(r): + all[r] = id + ids.add(id) + continue + + if id in ids: + continue + + r = 'refs/_alt/%s' % id + all[r] = id + ids.add(id) + tmp.add(r) + + ref_names = list(all.keys()) + ref_names.sort() + + tmp_packed = '' + old_packed = '' + + for r in ref_names: + line = '%s %s\n' % (all[r], r) + tmp_packed += line + if r not in tmp: + old_packed += line + + _lwrite(packed_refs, tmp_packed) + + else: + ref_dir = None + cmd = ['fetch'] if not self.worktree: cmd.append('--update-head-ok') @@ -1039,10 +1094,21 @@ class Project(object): if tag is not None: cmd.append('tag') cmd.append(tag) - return GitCommand(self, - cmd, - bare = True, - ssh_proxy = ssh_proxy).Wait() == 0 + + ok = GitCommand(self, + cmd, + bare = True, + ssh_proxy = ssh_proxy).Wait() == 0 + + if initial: + if ref_dir: + if old_packed != '': + _lwrite(packed_refs, old_packed) + else: + os.remove(packed_refs) + self.bare_git.pack_refs('--all', '--prune') + + return ok def _Checkout(self, rev, quiet=False): cmd = ['checkout'] @@ -1080,6 +1146,27 @@ class Project(object): os.makedirs(self.gitdir) self.bare_git.init() + mp = self.manifest.manifestProject + ref_dir = mp.config.GetString('repo.reference') + + if ref_dir: + mirror_git = os.path.join(ref_dir, self.name + '.git') + repo_git = os.path.join(ref_dir, '.repo', 'projects', + self.relpath + '.git') + + if os.path.exists(mirror_git): + ref_dir = mirror_git + + elif os.path.exists(repo_git): + ref_dir = repo_git + + else: + ref_dir = None + + if ref_dir: + _lwrite(os.path.join(self.gitdir, 'objects/info/alternates'), + os.path.join(ref_dir, 'objects') + '\n') + if self.manifest.IsMirror: self.config.SetString('core.bare', 'true') else: diff --git a/repo b/repo index 13742559..bdc05c3b 100755 --- a/repo +++ b/repo @@ -28,7 +28,7 @@ if __name__ == '__main__': del magic # increment this whenever we make important changes to this script -VERSION = (1, 8) +VERSION = (1, 9) # increment this if the MAINTAINER_KEYS block is modified KEYRING_VERSION = (1,0) @@ -118,6 +118,9 @@ group.add_option('-m', '--manifest-name', group.add_option('--mirror', dest='mirror', action='store_true', help='mirror the forrest') +group.add_option('--reference', + dest='reference', + help='location of mirror directory', metavar='DIR') # Tool group = init_optparse.add_option_group('repo Version options') diff --git a/subcmds/init.py b/subcmds/init.py index 4023ab6d..17edfa05 100644 --- a/subcmds/init.py +++ b/subcmds/init.py @@ -41,6 +41,13 @@ The optional -m argument can be used to specify an alternate manifest to be used. If no manifest is specified, the manifest default.xml will be used. +The --reference option can be used to point to a directory that +has the content of a --mirror sync. This will make the working +directory use as much data as possible from the local reference +directory when fetching from the server. This will make the sync +go a lot faster by reducing data traffic on the network. + + Switching Manifest Branches --------------------------- @@ -71,7 +78,9 @@ to update the working directory files. g.add_option('--mirror', dest='mirror', action='store_true', help='mirror the forrest') - + g.add_option('--reference', + dest='reference', + help='location of mirror directory', metavar='DIR') # Tool g = p.add_option_group('repo Version options') @@ -115,6 +124,9 @@ to update the working directory files. r.ResetFetch() r.Save() + if opt.reference: + m.config.SetString('repo.reference', opt.reference) + if opt.mirror: if is_new: m.config.SetString('repo.mirror', 'true') -- cgit v1.2.3-54-g00ecf From 16614f86b3cc8d61ccae7197624fa93fc752767b Mon Sep 17 00:00:00 2001 From: "Shawn O. Pearce" Date: Fri, 29 Oct 2010 12:05:43 -0700 Subject: sync --quiet: be more quiet Change-Id: I5e8363c7b32e4546d1236cfc5a32e01c3e5ea8e6 Signed-off-by: Shawn O. Pearce --- project.py | 17 +++++++++++------ subcmds/sync.py | 24 ++++++++++++++++-------- 2 files changed, 27 insertions(+), 14 deletions(-) (limited to 'project.py') diff --git a/project.py b/project.py index 8ffed842..ce85b863 100644 --- a/project.py +++ b/project.py @@ -618,18 +618,19 @@ class Project(object): ## Sync ## - def Sync_NetworkHalf(self): + def Sync_NetworkHalf(self, quiet=False): """Perform only the network IO portion of the sync process. Local working directory/branch state is not affected. """ is_new = not self.Exists if is_new: - print >>sys.stderr - print >>sys.stderr, 'Initializing project %s ...' % self.name + if not quiet: + print >>sys.stderr + print >>sys.stderr, 'Initializing project %s ...' % self.name self._InitGitDir() self._InitRemote() - if not self._RemoteFetch(initial = is_new): + if not self._RemoteFetch(initial=is_new, quiet=quiet): return False #Check that the requested ref was found after fetch @@ -642,7 +643,7 @@ class Project(object): # rev = self.revisionExpr if rev.startswith(R_TAGS): - self._RemoteFetch(None, rev[len(R_TAGS):]) + self._RemoteFetch(None, rev[len(R_TAGS):], quiet=quiet) if self.worktree: self._InitMRef() @@ -1025,7 +1026,9 @@ class Project(object): ## Direct Git Commands ## - def _RemoteFetch(self, name=None, tag=None, initial=False): + def _RemoteFetch(self, name=None, tag=None, + initial=False, + quiet=False): if not name: name = self.remote.name @@ -1088,6 +1091,8 @@ class Project(object): ref_dir = None cmd = ['fetch'] + if quiet: + cmd.append('--quiet') if not self.worktree: cmd.append('--update-head-ok') cmd.append(name) diff --git a/subcmds/sync.py b/subcmds/sync.py index 6cac2e52..1f4b137f 100644 --- a/subcmds/sync.py +++ b/subcmds/sync.py @@ -110,6 +110,9 @@ later is required to fix a server side protocol bug. p.add_option('-d','--detach', dest='detach_head', action='store_true', help='detach projects back to manifest revision') + p.add_option('-q','--quiet', + dest='quiet', action='store_true', + help='be more quiet') p.add_option('-j','--jobs', dest='jobs', action='store', type='int', help="number of projects to fetch simultaneously") @@ -126,8 +129,8 @@ later is required to fix a server side protocol bug. dest='repo_upgraded', action='store_true', help=SUPPRESS_HELP) - def _FetchHelper(self, project, lock, fetched, pm, sem): - if not project.Sync_NetworkHalf(): + def _FetchHelper(self, opt, project, lock, fetched, pm, sem): + if not project.Sync_NetworkHalf(quiet=opt.quiet): print >>sys.stderr, 'error: Cannot fetch %s' % project.name sem.release() sys.exit(1) @@ -138,14 +141,14 @@ later is required to fix a server side protocol bug. lock.release() sem.release() - def _Fetch(self, projects): + def _Fetch(self, projects, opt): fetched = set() pm = Progress('Fetching projects', len(projects)) if self.jobs == 1: for project in projects: pm.update() - if project.Sync_NetworkHalf(): + if project.Sync_NetworkHalf(quiet=opt.quiet): fetched.add(project.gitdir) else: print >>sys.stderr, 'error: Cannot fetch %s' % project.name @@ -157,7 +160,12 @@ later is required to fix a server side protocol bug. for project in projects: sem.acquire() t = _threading.Thread(target = self._FetchHelper, - args = (project, lock, fetched, pm, sem)) + args = (opt, + project, + lock, + fetched, + pm, + sem)) threads.add(t) t.start() @@ -291,7 +299,7 @@ uncommitted changes are present' % project.relpath _PostRepoUpgrade(self.manifest) if not opt.local_only: - mp.Sync_NetworkHalf() + mp.Sync_NetworkHalf(quiet=opt.quiet) if mp.HasChanges: syncbuf = SyncBuffer(mp.config) @@ -308,7 +316,7 @@ uncommitted changes are present' % project.relpath to_fetch.append(rp) to_fetch.extend(all) - fetched = self._Fetch(to_fetch) + fetched = self._Fetch(to_fetch, opt) _PostRepoFetch(rp, opt.no_repo_verify) if opt.network_only: # bail out now; the rest touches the working tree @@ -320,7 +328,7 @@ uncommitted changes are present' % project.relpath for project in all: if project.gitdir not in fetched: missing.append(project) - self._Fetch(missing) + self._Fetch(missing, opt) if self.manifest.IsMirror: # bail out now, we have no working tree -- cgit v1.2.3-54-g00ecf From a0de6e8eab97f5dcdb2f51d4e09dd1568623ec58 Mon Sep 17 00:00:00 2001 From: Ficus Kirkpatrick Date: Fri, 22 Oct 2010 13:06:47 -0700 Subject: upload: Remove --replace option It hasn't been necessary for a long time, and its functionality can be accomplished with 'git push'. Change-Id: Ic00d3adbe4cee7be3955117489c69d6e90106559 --- project.py | 6 ----- subcmds/upload.py | 78 +------------------------------------------------------ 2 files changed, 1 insertion(+), 83 deletions(-) (limited to 'project.py') diff --git a/project.py b/project.py index ce85b863..01dc8678 100644 --- a/project.py +++ b/project.py @@ -111,7 +111,6 @@ class ReviewableBranch(object): self.project = project self.branch = branch self.base = base - self.replace_changes = None @property def name(self): @@ -151,7 +150,6 @@ class ReviewableBranch(object): def UploadForReview(self, people, auto_topic=False): self.project.UploadForReview(self.name, - self.replace_changes, people, auto_topic=auto_topic) @@ -557,7 +555,6 @@ class Project(object): return None def UploadForReview(self, branch=None, - replace_changes=None, people=([],[]), auto_topic=False): """Uploads the named branch for code review. @@ -600,9 +597,6 @@ class Project(object): cmd.append(branch.remote.SshReviewUrl(self.UserEmail)) cmd.append(ref_spec) - if replace_changes: - for change_id,commit_id in replace_changes.iteritems(): - cmd.append('%s:refs/changes/%s/new' % (commit_id, change_id)) if GitCommand(self, cmd, bare = True).Wait() != 0: raise UploadError('Upload failed') diff --git a/subcmds/upload.py b/subcmds/upload.py index 153b3ebe..1964bffa 100644 --- a/subcmds/upload.py +++ b/subcmds/upload.py @@ -47,7 +47,7 @@ class Upload(InteractiveCommand): common = True helpSummary = "Upload changes for code review" helpUsage=""" -%prog [--re --cc] {[]... | --replace } +%prog [--re --cc] []... """ helpDescription = """ The '%prog' command is used to send changes to the Gerrit Code @@ -67,12 +67,6 @@ added to the respective list of users, and emails are sent to any new users. Users passed as --reviewers must already be registered with the code review system, or the upload will fail. -If the --replace option is passed the user can designate which -existing change(s) in Gerrit match up to the commits in the branch -being uploaded. For each matched pair of change,commit the commit -will be added as a new patch set, completely replacing the set of -files and description associated with the change in Gerrit. - Configuration ------------- @@ -119,9 +113,6 @@ Gerrit Code Review: http://code.google.com/p/gerrit/ p.add_option('-t', dest='auto_topic', action='store_true', help='Send local branch name to Gerrit Code Review') - p.add_option('--replace', - dest='replace', action='store_true', - help='Upload replacement patchesets from this branch') p.add_option('--re', '--reviewers', type='string', action='append', dest='reviewers', help='Request reviews from these people.') @@ -262,65 +253,6 @@ Gerrit Code Review: http://code.google.com/p/gerrit/ except: return "" - def _ReplaceBranch(self, opt, project, people): - branch = project.CurrentBranch - if not branch: - print >>sys.stdout, "no branches ready for upload" - return - branch = project.GetUploadableBranch(branch) - if not branch: - print >>sys.stdout, "no branches ready for upload" - return - - script = [] - script.append('# Replacing from branch %s' % branch.name) - - if len(branch.commits) == 1: - change = self._FindGerritChange(branch) - script.append('[%-6s] %s' % (change, branch.commits[0])) - else: - for commit in branch.commits: - script.append('[ ] %s' % commit) - - script.append('') - script.append('# Insert change numbers in the brackets to add a new patch set.') - script.append('# To create a new change record, leave the brackets empty.') - - script = Editor.EditString("\n".join(script)).split("\n") - - change_re = re.compile(r'^\[\s*(\d{1,})\s*\]\s*([0-9a-f]{1,}) .*$') - to_replace = dict() - full_hashes = branch.unabbrev_commits - - for line in script: - m = change_re.match(line) - if m: - c = m.group(1) - f = m.group(2) - try: - f = full_hashes[f] - except KeyError: - print 'fh = %s' % full_hashes - print >>sys.stderr, "error: commit %s not found" % f - sys.exit(1) - if c in to_replace: - print >>sys.stderr,\ - "error: change %s cannot accept multiple commits" % c - sys.exit(1) - to_replace[c] = f - - if not to_replace: - print >>sys.stderr, "error: no replacements specified" - print >>sys.stderr, " use 'repo upload' without --replace" - sys.exit(1) - - if len(branch.commits) > UNUSUAL_COMMIT_THRESHOLD: - if not _ConfirmManyUploads(multiple_branches=True): - _die("upload aborted by user") - - branch.replace_changes = to_replace - self._UploadAndReport(opt, [branch], people) - def _UploadAndReport(self, opt, todo, original_people): have_errors = False for branch in todo: @@ -383,14 +315,6 @@ Gerrit Code Review: http://code.google.com/p/gerrit/ cc = _SplitEmails(opt.cc) people = (reviewers,cc) - if opt.replace: - if len(project_list) != 1: - print >>sys.stderr, \ - 'error: --replace requires exactly one project' - sys.exit(1) - self._ReplaceBranch(opt, project_list[0], people) - return - for project in project_list: avail = project.GetUploadableBranches() if avail: -- cgit v1.2.3-54-g00ecf