[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/tests/git_cl_test.py b/tests/git_cl_test.py
index 9ed8a1f..150369c 100755
--- a/tests/git_cl_test.py
+++ b/tests/git_cl_test.py
@@ -2274,6 +2274,7 @@
self.calls = [
((['git', 'for-each-ref', '--format=%(refname)', 'refs/heads'],),
'refs/heads/master\nrefs/heads/foo\nrefs/heads/bar'),
+ ((['git', 'for-each-ref', '--format=%(refname)', 'refs/tags'],), ''),
((['git', 'symbolic-ref', 'HEAD'],), 'master'),
((['git', 'tag', 'git-cl-archived-456-foo', 'foo'],), ''),
((['git', 'branch', '-D', 'foo'],), '')
@@ -2287,11 +2288,33 @@
self.assertEqual(0, git_cl.main(['archive', '-f']))
+ def test_archive_tag_collision(self):
+ self.mock(git_cl.sys, 'stdout', StringIO())
+
+ self.calls = [
+ ((['git', 'for-each-ref', '--format=%(refname)', 'refs/heads'],),
+ 'refs/heads/master\nrefs/heads/foo\nrefs/heads/bar'),
+ ((['git', 'for-each-ref', '--format=%(refname)', 'refs/tags'],),
+ 'refs/tags/git-cl-archived-456-foo'),
+ ((['git', 'symbolic-ref', 'HEAD'],), 'master'),
+ ((['git', 'tag', 'git-cl-archived-456-foo-2', 'foo'],), ''),
+ ((['git', 'branch', '-D', 'foo'],), '')
+ ]
+
+ self.mock(git_cl, 'get_cl_statuses',
+ lambda branches, fine_grained, max_processes:
+ [(MockChangelistWithBranchAndIssue('master', 1), 'open'),
+ (MockChangelistWithBranchAndIssue('foo', 456), 'closed'),
+ (MockChangelistWithBranchAndIssue('bar', 789), 'open')])
+
+ self.assertEqual(0, git_cl.main(['archive', '-f']))
+
def test_archive_current_branch_fails(self):
self.mock(git_cl.sys, 'stdout', StringIO())
self.calls = [
((['git', 'for-each-ref', '--format=%(refname)', 'refs/heads'],),
'refs/heads/master'),
+ ((['git', 'for-each-ref', '--format=%(refname)', 'refs/tags'],), ''),
((['git', 'symbolic-ref', 'HEAD'],), 'master'),
]
@@ -2307,6 +2330,7 @@
self.calls = [
((['git', 'for-each-ref', '--format=%(refname)', 'refs/heads'],),
'refs/heads/master\nrefs/heads/foo\nrefs/heads/bar'),
+ ((['git', 'for-each-ref', '--format=%(refname)', 'refs/tags'],), ''),
((['git', 'symbolic-ref', 'HEAD'],), 'master')
]
@@ -2324,6 +2348,7 @@
self.calls = [
((['git', 'for-each-ref', '--format=%(refname)', 'refs/heads'],),
'refs/heads/master\nrefs/heads/foo\nrefs/heads/bar'),
+ ((['git', 'for-each-ref', '--format=%(refname)', 'refs/tags'],), ''),
((['git', 'symbolic-ref', 'HEAD'],), 'master'),
((['git', 'branch', '-D', 'foo'],), '')
]
@@ -2336,6 +2361,29 @@
self.assertEqual(0, git_cl.main(['archive', '-f', '--notags']))
+ def test_archive_tag_cleanup_on_branch_deletion_error(self):
+ self.mock(git_cl.sys, 'stdout', StringIO())
+
+ self.calls = [
+ ((['git', 'for-each-ref', '--format=%(refname)', 'refs/heads'],),
+ 'refs/heads/master\nrefs/heads/foo\nrefs/heads/bar'),
+ ((['git', 'for-each-ref', '--format=%(refname)', 'refs/tags'],), ''),
+ ((['git', 'symbolic-ref', 'HEAD'],), 'master'),
+ ((['git', 'tag', 'git-cl-archived-456-foo', 'foo'],),
+ 'refs/tags/git-cl-archived-456-foo'),
+ ((['git', 'branch', '-D', 'foo'],), CERR1),
+ ((['git', 'tag', '-d', 'git-cl-archived-456-foo'],),
+ 'refs/tags/git-cl-archived-456-foo'),
+ ]
+
+ self.mock(git_cl, 'get_cl_statuses',
+ lambda branches, fine_grained, max_processes:
+ [(MockChangelistWithBranchAndIssue('master', 1), 'open'),
+ (MockChangelistWithBranchAndIssue('foo', 456), 'closed'),
+ (MockChangelistWithBranchAndIssue('bar', 789), 'open')])
+
+ self.assertEqual(0, git_cl.main(['archive', '-f']))
+
def test_cmd_issue_erase_existing(self):
out = StringIO()
self.mock(git_cl.sys, 'stdout', out)