gclient: Set with_branch_heads if asked to sync to refs/branch-heads/*
The bug is caused because we already have refs/branch-heads/XXXX locally,
so we don't attempt to fetch it again, even if it has been updated.
This solution is a bit of a hack to make sure that we fetch
refs/branch-heads/*, which is the most common case for this to fail.
Bug: 1070545
Change-Id: Iec7cfff18219794230188e2b9e901c587acd274b
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/tools/depot_tools/+/2149849
Commit-Queue: Edward Lesmes <ehmaldonado@chromium.org>
Reviewed-by: Josip Sokcevic <sokcevic@google.com>
diff --git a/tests/gclient_scm_test.py b/tests/gclient_scm_test.py
index 81cc233..fae7a08 100755
--- a/tests/gclient_scm_test.py
+++ b/tests/gclient_scm_test.py
@@ -981,6 +981,79 @@
scm.update(None, (), [])
+class BranchHeadsFakeRepo(fake_repos.FakeReposBase):
+ def populateGit(self):
+ # Creates a tree that looks like this:
+ #
+ # 5 refs/branch-heads/5
+ # |
+ # 4
+ # |
+ # 1--2--3 refs/heads/master
+ self._commit_git('repo_1', {'commit 1': 'touched'})
+ self._commit_git('repo_1', {'commit 2': 'touched'})
+ self._commit_git('repo_1', {'commit 3': 'touched'})
+ self._create_ref('repo_1', 'refs/heads/master', 3)
+
+ self._commit_git('repo_1', {'commit 4': 'touched'}, base=2)
+ self._commit_git('repo_1', {'commit 5': 'touched'}, base=2)
+ self._create_ref('repo_1', 'refs/branch-heads/5', 5)
+
+
+class BranchHeadsTest(fake_repos.FakeReposTestBase):
+ FAKE_REPOS_CLASS = BranchHeadsFakeRepo
+
+ def setUp(self):
+ super(BranchHeadsTest, self).setUp()
+ self.enabled = self.FAKE_REPOS.set_up_git()
+ self.options = BaseGitWrapperTestCase.OptionsObject()
+ self.url = self.git_base + 'repo_1'
+ self.mirror = None
+ mock.patch('sys.stdout').start()
+ self.addCleanup(mock.patch.stopall)
+
+ def setUpMirror(self):
+ self.mirror = tempfile.mkdtemp('mirror')
+ git_cache.Mirror.SetCachePath(self.mirror)
+ self.addCleanup(gclient_utils.rmtree, self.mirror)
+ self.addCleanup(git_cache.Mirror.SetCachePath, None)
+
+ def testCheckoutBranchHeads(self):
+ scm = gclient_scm.GitWrapper(self.url, self.root_dir, '.')
+ file_list = []
+
+ self.options.revision = 'refs/branch-heads/5'
+ scm.update(self.options, None, file_list)
+ self.assertEqual(self.githash('repo_1', 5), self.gitrevparse(self.root_dir))
+
+ def testCheckoutUpdatedBranchHeads(self):
+ # Travel back in time, and set refs/branch-heads/5 to its parent.
+ subprocess2.check_call(
+ ['git', 'update-ref', 'refs/branch-heads/5', self.githash('repo_1', 4)],
+ cwd=self.url)
+
+ # Sync to refs/branch-heads/5
+ scm = gclient_scm.GitWrapper(self.url, self.root_dir, '.')
+ self.options.revision = 'refs/branch-heads/5'
+ scm.update(self.options, None, [])
+
+ # Set refs/branch-heads/5 back to its original value.
+ subprocess2.check_call(
+ ['git', 'update-ref', 'refs/branch-heads/5', self.githash('repo_1', 5)],
+ cwd=self.url)
+
+ # Attempt to sync to refs/branch-heads/5 again.
+ self.testCheckoutBranchHeads()
+
+ def testCheckoutBranchHeadsMirror(self):
+ self.setUpMirror()
+ self.testCheckoutBranchHeads()
+
+ def testCheckoutUpdatedBranchHeadsMirror(self):
+ self.setUpMirror()
+ self.testCheckoutUpdatedBranchHeads()
+
+
class GerritChangesFakeRepo(fake_repos.FakeReposBase):
def populateGit(self):
# Creates a tree that looks like this: