diff options
| author | Mike Frysinger <vapier@google.com> | 2019-09-11 18:43:17 -0400 |
|---|---|---|
| committer | Mike Frysinger <vapier@google.com> | 2019-11-16 19:55:02 +0000 |
| commit | 6da17751ca4e3b90834ca763f448ddc39b32651b (patch) | |
| tree | 4962f9913b689de734d3d11e981d3a2e18841504 /tests/test_project.py | |
| parent | 2ba5a1e96347e735b12998c057a6c1eed79712e9 (diff) | |
| download | git-repo-6da17751ca4e3b90834ca763f448ddc39b32651b.tar.gz | |
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 <dpursehouse@collab.net>
Reviewed-by: Kirtika Ruchandani <kirtika@google.com>
Reviewed-by: Mike Frysinger <vapier@google.com>
Tested-by: Mike Frysinger <vapier@google.com>
Diffstat (limited to 'tests/test_project.py')
| -rw-r--r-- | tests/test_project.py | 74 |
1 files changed, 74 insertions, 0 deletions
diff --git a/tests/test_project.py b/tests/test_project.py index 9b289e11..77126dff 100644 --- a/tests/test_project.py +++ b/tests/test_project.py | |||
| @@ -18,11 +18,30 @@ | |||
| 18 | 18 | ||
| 19 | from __future__ import print_function | 19 | from __future__ import print_function |
| 20 | 20 | ||
| 21 | import contextlib | ||
| 22 | import os | ||
| 23 | import shutil | ||
| 24 | import subprocess | ||
| 25 | import tempfile | ||
| 21 | import unittest | 26 | import unittest |
| 22 | 27 | ||
| 28 | import git_config | ||
| 23 | import project | 29 | import project |
| 24 | 30 | ||
| 25 | 31 | ||
| 32 | @contextlib.contextmanager | ||
| 33 | def TempGitTree(): | ||
| 34 | """Create a new empty git checkout for testing.""" | ||
| 35 | # TODO(vapier): Convert this to tempfile.TemporaryDirectory once we drop | ||
| 36 | # Python 2 support entirely. | ||
| 37 | try: | ||
| 38 | tempdir = tempfile.mkdtemp(prefix='repo-tests') | ||
| 39 | subprocess.check_call(['git', 'init'], cwd=tempdir) | ||
| 40 | yield tempdir | ||
| 41 | finally: | ||
| 42 | shutil.rmtree(tempdir) | ||
| 43 | |||
| 44 | |||
| 26 | class RepoHookShebang(unittest.TestCase): | 45 | class RepoHookShebang(unittest.TestCase): |
| 27 | """Check shebang parsing in RepoHook.""" | 46 | """Check shebang parsing in RepoHook.""" |
| 28 | 47 | ||
| @@ -60,3 +79,58 @@ class RepoHookShebang(unittest.TestCase): | |||
| 60 | for shebang, interp in DATA: | 79 | for shebang, interp in DATA: |
| 61 | self.assertEqual(project.RepoHook._ExtractInterpFromShebang(shebang), | 80 | self.assertEqual(project.RepoHook._ExtractInterpFromShebang(shebang), |
| 62 | interp) | 81 | interp) |
| 82 | |||
| 83 | |||
| 84 | class FakeProject(object): | ||
| 85 | """A fake for Project for basic functionality.""" | ||
| 86 | |||
| 87 | def __init__(self, worktree): | ||
| 88 | self.worktree = worktree | ||
| 89 | self.gitdir = os.path.join(worktree, '.git') | ||
| 90 | self.name = 'fakeproject' | ||
| 91 | self.work_git = project.Project._GitGetByExec( | ||
| 92 | self, bare=False, gitdir=self.gitdir) | ||
| 93 | self.bare_git = project.Project._GitGetByExec( | ||
| 94 | self, bare=True, gitdir=self.gitdir) | ||
| 95 | self.config = git_config.GitConfig.ForRepository(gitdir=self.gitdir) | ||
| 96 | |||
| 97 | |||
| 98 | class ReviewableBranchTests(unittest.TestCase): | ||
| 99 | """Check ReviewableBranch behavior.""" | ||
| 100 | |||
| 101 | def test_smoke(self): | ||
| 102 | """A quick run through everything.""" | ||
| 103 | with TempGitTree() as tempdir: | ||
| 104 | fakeproj = FakeProject(tempdir) | ||
| 105 | |||
| 106 | # Generate some commits. | ||
| 107 | with open(os.path.join(tempdir, 'readme'), 'w') as fp: | ||
| 108 | fp.write('txt') | ||
| 109 | fakeproj.work_git.add('readme') | ||
| 110 | fakeproj.work_git.commit('-mAdd file') | ||
| 111 | fakeproj.work_git.checkout('-b', 'work') | ||
| 112 | fakeproj.work_git.rm('-f', 'readme') | ||
| 113 | fakeproj.work_git.commit('-mDel file') | ||
| 114 | |||
| 115 | # Start off with the normal details. | ||
| 116 | rb = project.ReviewableBranch( | ||
| 117 | fakeproj, fakeproj.config.GetBranch('work'), 'master') | ||
| 118 | self.assertEqual('work', rb.name) | ||
| 119 | self.assertEqual(1, len(rb.commits)) | ||
| 120 | self.assertIn('Del file', rb.commits[0]) | ||
| 121 | d = rb.unabbrev_commits | ||
| 122 | self.assertEqual(1, len(d)) | ||
| 123 | short, long = next(iter(d.items())) | ||
| 124 | self.assertTrue(long.startswith(short)) | ||
| 125 | self.assertTrue(rb.base_exists) | ||
| 126 | # Hard to assert anything useful about this. | ||
| 127 | self.assertTrue(rb.date) | ||
| 128 | |||
| 129 | # Now delete the tracking branch! | ||
| 130 | fakeproj.work_git.branch('-D', 'master') | ||
| 131 | rb = project.ReviewableBranch( | ||
| 132 | fakeproj, fakeproj.config.GetBranch('work'), 'master') | ||
| 133 | self.assertEqual(0, len(rb.commits)) | ||
| 134 | self.assertFalse(rb.base_exists) | ||
| 135 | # Hard to assert anything useful about this. | ||
| 136 | self.assertTrue(rb.date) | ||
