[git-cl] Add graceful error handling to "git cl archive".
Adds error handling logic for pre-existing tags (which can occur
if "archive" is CTRL-C aborted midway through) and for undeletable
branches (which can happen if they are currently checked out in a
working dir).
Change-Id: I27b6da9f5860c307f49cbeabb1b0ccf9cfb28eb6
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/tools/depot_tools/+/1930023
Commit-Queue: Edward Lesmes <ehmaldonado@chromium.org>
Reviewed-by: Edward Lesmes <ehmaldonado@chromium.org>
Auto-Submit: Kevin Marshall <kmarshall@chromium.org>
diff --git a/git_cl.py b/git_cl.py
index 505a3e8..d41f483 100755
--- a/git_cl.py
+++ b/git_cl.py
@@ -3727,6 +3727,22 @@
return 0
+def GetArchiveTagForBranch(issue_num, branch_name, existing_tags):
+ """Given a proposed tag name, returns a tag name that is guaranteed to be
+ unique. If 'foo' is proposed but already exists, then 'foo-2' is used,
+ or 'foo-3', and so on."""
+
+ proposed_tag = 'git-cl-archived-%s-%s' % (issue_num, branch_name)
+ for suffix_num in itertools.count(1):
+ if suffix_num == 1:
+ to_check = proposed_tag
+ else:
+ to_check = '%s-%d' % (proposed_tag, suffix_num)
+
+ if to_check not in existing_tags:
+ return to_check
+
+
@metrics.collector.collect_metrics('git cl archive')
def CMDarchive(parser, args):
"""Archives and deletes branches associated with closed changelists."""
@@ -3752,6 +3768,10 @@
if not branches:
return 0
+ tags = RunGit(['for-each-ref', '--format=%(refname)',
+ 'refs/tags']).splitlines() or []
+ tags = [t.split('/')[-1] for t in tags]
+
print('Finding all branches associated with closed issues...')
changes = [Changelist(branchref=b)
for b in branches.splitlines()]
@@ -3760,7 +3780,8 @@
fine_grained=True,
max_processes=options.maxjobs)
proposal = [(cl.GetBranch(),
- 'git-cl-archived-%s-%s' % (cl.GetIssue(), cl.GetBranch()))
+ GetArchiveTagForBranch(cl.GetIssue(), cl.GetBranch(),
+ tags))
for cl, status in statuses
if status in ('closed', 'rietveld-not-supported')]
proposal.sort()
@@ -3800,7 +3821,10 @@
for branch, tagname in proposal:
if not options.notags:
RunGit(['tag', tagname, branch])
- RunGit(['branch', '-D', branch])
+
+ if RunGitWithCode(['branch', '-D', branch])[0] != 0:
+ # Clean up the tag if we failed to delete the branch.
+ RunGit(['tag', '-d', tagname])
print('\nJob\'s done!')