From 6da17751ca4e3b90834ca763f448ddc39b32651b Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Wed, 11 Sep 2019 18:43:17 -0400 Subject: prune: handle branches that track missing branches Series of steps: * Create a local "b1" branch with `repo start b1` that tracks a remote branch (totally fine) * Manually create a local "b2" branch with `git branch --track b1 b2` that tracks the local "b1" (uh-oh...) * Delete the local "b1" branch manually or via `repo prune` (....) * Try to process the "b2" branch with `repo prune` Since b2 tracks a branch that no longer exists, everything blows up at this point as we try to probe the non-existent ref. Instead, we should flag this as unknown and leave it up to the user to resolve. This probably could come up if a local branch was tracking a remote branch that was deleted from the server, and users ran something like `repo sync --prune` which cleaned up the remote refs. Bug: https://crbug.com/gerrit/11485 Change-Id: I6b6b6041943944b8efa6e2ad0b8b10f13a75a5c2 Reviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/236793 Reviewed-by: David Pursehouse Reviewed-by: Kirtika Ruchandani Reviewed-by: Mike Frysinger Tested-by: Mike Frysinger --- project.py | 39 +++++++++++++++++++++++++++++++-------- 1 file changed, 31 insertions(+), 8 deletions(-) (limited to 'project.py') diff --git a/project.py b/project.py index 5ffa5424..7811d6ba 100755 --- a/project.py +++ b/project.py @@ -134,6 +134,7 @@ class DownloadedChange(object): class ReviewableBranch(object): _commit_cache = None + _base_exists = None def __init__(self, project, branch, base): self.project = project @@ -147,14 +148,19 @@ class ReviewableBranch(object): @property def commits(self): if self._commit_cache is None: - self._commit_cache = self.project.bare_git.rev_list('--abbrev=8', - '--abbrev-commit', - '--pretty=oneline', - '--reverse', - '--date-order', - not_rev(self.base), - R_HEADS + self.name, - '--') + args = ('--abbrev=8', '--abbrev-commit', '--pretty=oneline', '--reverse', + '--date-order', not_rev(self.base), R_HEADS + self.name, '--') + try: + self._commit_cache = self.project.bare_git.rev_list(*args) + except GitError: + # We weren't able to probe the commits for this branch. Was it tracking + # a branch that no longer exists? If so, return no commits. Otherwise, + # rethrow the error as we don't know what's going on. + if self.base_exists: + raise + + self._commit_cache = [] + return self._commit_cache @property @@ -173,6 +179,23 @@ class ReviewableBranch(object): R_HEADS + self.name, '--') + @property + def base_exists(self): + """Whether the branch we're tracking exists. + + Normally it should, but sometimes branches we track can get deleted. + """ + if self._base_exists is None: + try: + self.project.bare_git.rev_parse('--verify', not_rev(self.base)) + # If we're still here, the base branch exists. + self._base_exists = True + except GitError: + # If we failed to verify, the base branch doesn't exist. + self._base_exists = False + + return self._base_exists + def UploadForReview(self, people, auto_topic=False, draft=False, -- cgit v1.2.3-54-g00ecf