def testUpdateCloneOnFetchedRemoteBranch(self): if not self.enabled: return options = self.Options() origin_root_dir = self.root_dir self.addCleanup(gclient_utils.rmtree, origin_root_dir) self.root_dir = tempfile.mkdtemp() self.relpath = '.' self.base_path = join(self.root_dir, self.relpath) url_with_branch_ref = origin_root_dir + '@refs/remotes/origin/feature' scm = gclient_scm.GitWrapper(url_with_branch_ref, self.root_dir, self.relpath) expected_file_list = [join(self.base_path, "a"), join(self.base_path, "b"), join(self.base_path, "c")] file_list = [] options.revision = 'unmanaged' scm.update(options, (), file_list) self.assertEqual(file_list, expected_file_list) self.assertEqual(scm.revinfo(options, (), None), '9a51244740b25fa2ded5252ca00a3178d3f665a9') # indicates detached HEAD self.assertEqual(self.getCurrentBranch(), None) self.checkInStdout( 'Checked out refs/remotes/origin/feature to a detached HEAD')
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 testUpdateConflict( self, mockCheckOutput, mockExists, mockIsdir, mockClone): mockIsdir.side_effect = lambda path: path == self.base_path mockExists.side_effect = lambda path: path == self.base_path mockCheckOutput.return_value = b'' mockClone.side_effect = [ gclient_scm.subprocess2.CalledProcessError( None, None, None, None, None), None, ] options = self.Options() scm = gclient_scm.GitWrapper(self.url, self.root_dir, self.relpath) scm.update(options, None, []) env = gclient_scm.scm.GIT.ApplyEnvVars({}) self.assertEqual( mockCheckOutput.mock_calls, [ mock.call( ['git', '-c', 'core.quotePath=false', 'ls-files'], cwd=self.base_path, env=env, stderr=-1), mock.call( ['git', 'rev-parse', '--verify', 'HEAD'], cwd=self.base_path, env=env, stderr=-1), ]) mockClone.assert_called_with( 'refs/remotes/origin/master', self.url, options) self.checkstdout('\n')
def testUpdateClone(self): if not self.enabled: return options = self.Options() origin_root_dir = self.root_dir self.addCleanup(gclient_utils.rmtree, origin_root_dir) self.root_dir = tempfile.mkdtemp() self.relpath = '.' self.base_path = join(self.root_dir, self.relpath) scm = gclient_scm.GitWrapper(origin_root_dir, self.root_dir, self.relpath) expected_file_list = [join(self.base_path, "a"), join(self.base_path, "b")] file_list = [] options.revision = 'unmanaged' scm.update(options, (), file_list) self.assertEqual(file_list, expected_file_list) self.assertEqual(scm.revinfo(options, (), None), '069c602044c5388d2d15c3f875b057c852003458') # indicates detached HEAD self.assertEqual(self.getCurrentBranch(), None) self.checkInStdout( 'Checked out refs/remotes/origin/master to a detached HEAD')
def testGetUsableRevGit(self): # pylint: disable=no-member options = self.Options(verbose=True) self.mox.StubOutWithMock(gclient_scm.scm.GIT, 'IsValidRevision', True) gclient_scm.scm.GIT.IsValidRevision(cwd=self.base_path, rev=self.fake_hash_1 ).AndReturn(True) gclient_scm.scm.GIT.IsValidRevision(cwd=self.base_path, rev='1' ).AndReturn(False) gclient_scm.scm.GIT.IsValidRevision(cwd=self.base_path, rev='1' ).AndReturn(False) self.mox.StubOutWithMock(gclient_scm.GitWrapper, '_Fetch', True) # pylint: disable=no-value-for-parameter gclient_scm.GitWrapper._Fetch(options).AndReturn(None) gclient_scm.scm.os.path.isdir(self.base_path).AndReturn(True) gclient_scm.os.path.isdir(self.base_path).AndReturn(True) self.mox.ReplayAll() git_scm = gclient_scm.GitWrapper(self.url, self.root_dir, self.relpath) # A [fake] git sha1 with a git repo should work (this is in the case that # the LKGR gets flipped to git sha1's some day). self.assertEquals(git_scm.GetUsableRev(self.fake_hash_1, options), self.fake_hash_1) # An SVN rev with an existing purely git repo should raise an exception. self.assertRaises(gclient_scm.gclient_utils.Error, git_scm.GetUsableRev, '1', options)
def testUpdateConflict(self): if not self.enabled: return options = self.Options() scm = gclient_scm.GitWrapper(self.url, self.root_dir, self.relpath) file_path = join(self.base_path, 'b') with open(file_path, 'w') as f: f.writelines('conflict\n') scm._Run(['commit', '-am', 'test'], options) scm._AskForData = self._GetAskForDataCallback( 'Cannot fast-forward merge, attempt to rebase? ' '(y)es / (q)uit / (s)kip : ', 'y') with self.assertRaises(gclient_scm.gclient_utils.Error) as e: scm.update(options, (), []) self.assertEqual( e.exception.args[0], 'Conflict while rebasing this branch.\n' 'Fix the conflict and run gclient again.\n' 'See \'man git-rebase\' for details.\n') with self.assertRaises(gclient_scm.gclient_utils.Error) as e: scm.update(options, (), []) self.assertEqual( e.exception.args[0], '\n____ . at refs/remotes/origin/master\n' '\tYou have unstaged changes.\n' '\tPlease commit, stash, or reset.\n') sys.stdout.close()
def testCanCloneGerritChange(self): scm = gclient_scm.GitWrapper(self.url, self.root_dir, '.') file_list = [] self.options.revision = 'refs/changes/35/1235/1' scm.update(self.options, None, file_list) self.assertEqual(self.githash('repo_1', 6), self.gitrevparse(self.root_dir))
def testRevinfo(self): if not self.enabled: return options = self.Options() scm = gclient_scm.GitWrapper(self.url, self.root_dir, self.relpath) rev_info = scm.revinfo(options, (), None) self.assertEquals(rev_info, '069c602044c5388d2d15c3f875b057c852003458')
def testUpdateCloneOnCommit(self): if not self.enabled: return options = self.Options() origin_root_dir = self.root_dir self.addCleanup(gclient_utils.rmtree, origin_root_dir) self.root_dir = tempfile.mkdtemp() self.relpath = '.' self.base_path = join(self.root_dir, self.relpath) url_with_commit_ref = origin_root_dir +\ '@a7142dc9f0009350b96a11f372b6ea658592aa95' scm = gclient_scm.GitWrapper(url_with_commit_ref, self.root_dir, self.relpath) expected_file_list = [join(self.base_path, "a"), join(self.base_path, "b")] file_list = [] options.revision = 'unmanaged' scm.update(options, (), file_list) self.assertEqual(file_list, expected_file_list) self.assertEqual(scm.revinfo(options, (), None), 'a7142dc9f0009350b96a11f372b6ea658592aa95') # indicates detached HEAD self.assertEqual(self.getCurrentBranch(), None) self.checkInStdout( 'Checked out a7142dc9f0009350b96a11f372b6ea658592aa95 to a detached HEAD')
def testMirrorPushUrl(self): if not self.enabled: return fakes = fake_repos.FakeRepos() fakes.set_up_git() self.url = fakes.git_base + 'repo_1' self.root_dir = fakes.root_dir self.addCleanup(fake_repos.FakeRepos.tear_down_git, fakes) mirror = tempfile.mkdtemp() self.addCleanup(rmtree, mirror) # This should never happen, but if it does, it'd render the other assertions # in this test meaningless. self.assertFalse(self.url.startswith(mirror)) git_cache.Mirror.SetCachePath(mirror) self.addCleanup(git_cache.Mirror.SetCachePath, None) options = self.Options() scm = gclient_scm.GitWrapper(self.url, self.root_dir, self.relpath) self.assertIsNotNone(scm._GetMirror(self.url, options)) scm.update(options, (), []) fetch_url = scm._Capture(['remote', 'get-url', 'origin']) self.assertTrue( fetch_url.startswith(mirror), msg='\n'.join([ 'Repository fetch url should be in the git cache mirror directory.', ' fetch_url: %s' % fetch_url, ' mirror: %s' % mirror])) push_url = scm._Capture(['remote', 'get-url', '--push', 'origin']) self.assertEquals(push_url, self.url) sys.stdout.close()
def testUpdateLocked(self): if not self.enabled: return options = self.Options() scm = gclient_scm.GitWrapper(self.url, self.root_dir, self.relpath) file_path = join(self.base_path, '.git', 'index.lock') with open(file_path, 'w'): pass with self.assertRaises(subprocess2.CalledProcessError): scm.update(options, (), []) sys.stdout.close()
def testUpdateUpdate(self): if not self.enabled: return options = self.Options() expected_file_list = [join(self.base_path, x) for x in ['a', 'b']] scm = gclient_scm.GitWrapper(self.url, self.root_dir, self.relpath) file_list = [] scm.update(options, (), file_list) self.assertEquals(file_list, expected_file_list) self.assertEquals(scm.revinfo(options, (), None), 'a7142dc9f0009350b96a11f372b6ea658592aa95') sys.stdout.close()
def testRevertNone(self): if not self.enabled: return options = self.Options() scm = gclient_scm.GitWrapper(self.url, self.root_dir, self.relpath) file_list = [] scm.update(options, None, file_list) file_list = [] scm.revert(options, self.args, file_list) self.assertEquals(file_list, []) self.assertEquals(scm.revinfo(options, self.args, None), 'a7142dc9f0009350b96a11f372b6ea658592aa95') sys.stdout.close()
def testUpdateUpdate(self): if not self.enabled: return options = self.Options() expected_file_list = [] scm = gclient_scm.GitWrapper(self.url, self.root_dir, self.relpath) file_list = [] options.revision = 'unmanaged' scm.update(options, (), file_list) self.assertEquals(file_list, expected_file_list) self.assertEquals(scm.revinfo(options, (), None), '069c602044c5388d2d15c3f875b057c852003458') self.checkstdout('________ unmanaged solution; skipping .\n')
def testUpdateLockedBreak(self): if not self.enabled: return options = self.Options() options.break_repo_locks = True scm = gclient_scm.GitWrapper(self.url, self.root_dir, self.relpath) file_path = join(self.base_path, '.git', 'index.lock') with open(file_path, 'w'): pass scm.update(options, (), []) self.assertRegexpMatches(sys.stdout.getvalue(), "breaking lock.*\.git/index\.lock") self.assertFalse(os.path.exists(file_path)) sys.stdout.close()
def testStatusNew(self): if not self.enabled: return options = self.Options() file_path = join(self.base_path, 'a') open(file_path, 'a').writelines('touched\n') scm = gclient_scm.GitWrapper(self.url, self.root_dir, self.relpath) file_list = [] scm.status(options, self.args, file_list) self.assertEquals(file_list, [file_path]) self.checkstdout(( '\n________ running \'git -c core.quotePath=false diff --name-status ' '069c602044c5388d2d15c3f875b057c852003458\' in \'%s\'\nM\ta\n') % join(self.root_dir, '.'))
def testStatusNewNoBaseRev(self): if not self.enabled: return options = self.Options() file_path = join(self.base_path, 'a') with open(file_path, 'a') as f: f.writelines('touched\n') scm = gclient_scm.GitWrapper(self.url, self.root_dir, self.relpath) file_list = [] scm.status(options, self.args, file_list) self.assertEqual(file_list, [file_path]) self.checkstdout( ('\n________ running \'git -c core.quotePath=false diff --name-status' '\' in \'%s\'\n\nM\ta\n') % join(self.root_dir, '.'))
def testGetUsableRevGit(self, mockIsValidRevision): # pylint: disable=no-member options = self.Options(verbose=True) mockIsValidRevision.side_effect = lambda cwd, rev: rev != '1' git_scm = gclient_scm.GitWrapper(self.url, self.root_dir, self.relpath) # A [fake] git sha1 with a git repo should work (this is in the case that # the LKGR gets flipped to git sha1's some day). self.assertEqual(git_scm.GetUsableRev(self.fake_hash_1, options), self.fake_hash_1) # An SVN rev with an existing purely git repo should raise an exception. self.assertRaises(gclient_scm.gclient_utils.Error, git_scm.GetUsableRev, '1', options)
def testAppliesPatchOnTopOfMasterByDefault(self): """Test the default case, where we apply a patch on top of master.""" scm = gclient_scm.GitWrapper(self.url, self.root_dir, '.') file_list = [] # Make sure we don't specify a revision. self.options.revision = None scm.update(self.options, None, file_list) self.assertEqual(self.githash('repo_1', 4), self.gitrevparse(self.root_dir)) scm.apply_patch_ref(self.url, 'refs/changes/35/1235/1', None, self.options, file_list) self.assertCommits([1, 2, 3, 4, 5, 6]) self.assertEqual(self.githash('repo_1', 4), self.gitrevparse(self.root_dir))
def testUpdateResetUnsetsFetchConfig(self): if not self.enabled: return options = self.Options() options.reset = True scm = gclient_scm.GitWrapper(self.url, self.root_dir, self.relpath) scm._Run(['config', 'remote.origin.fetch', '+refs/heads/bad/ref:refs/remotes/origin/bad/ref'], options) file_list = [] scm.update(options, (), file_list) self.assertEqual(scm.revinfo(options, (), None), '069c602044c5388d2d15c3f875b057c852003458') sys.stdout.close()
def testDoesntRebasePatchMaster(self): """Tests that we can apply a patch without rebasing it. """ scm = gclient_scm.GitWrapper(self.url, self.root_dir, '.') file_list = [] self.options.rebase_patch_ref = False scm.update(self.options, None, file_list) self.assertEqual(self.githash('repo_1', 4), self.gitrevparse(self.root_dir)) # Apply the change on top of that. scm.apply_patch_ref(self.url, 'refs/changes/35/1235/1', None, self.options, file_list) self.assertCommits([1, 2, 3, 5, 6]) self.assertEqual(self.githash('repo_1', 4), self.gitrevparse(self.root_dir))
def testCheckoutOriginFeature(self): """Tests that we can apply a patch on a branch other than master.""" scm = gclient_scm.GitWrapper(self.url, self.root_dir, '.') file_list = [] # Sync to remote's refs/heads/feature self.options.revision = 'refs/heads/feature' scm.update(self.options, None, file_list) self.assertEqual(self.githash('repo_1', 9), self.gitrevparse(self.root_dir)) # Apply the change on top of that. scm.apply_patch_ref(self.url, 'refs/changes/36/1236/1', None, self.options, file_list) self.assertCommits([1, 2, 7, 8, 9, 10]) self.assertEqual(self.githash('repo_1', 9), self.gitrevparse(self.root_dir))
def testRevertMissing(self): if not self.enabled: return options = self.Options() file_path = join(self.base_path, 'a') scm = gclient_scm.GitWrapper(self.url, self.root_dir, self.relpath) file_list = [] scm.update(options, None, file_list) gclient_scm.os.remove(file_path) file_list = [] scm.revert(options, self.args, file_list) self.assertEquals(file_list, [file_path]) file_list = [] scm.diff(options, self.args, file_list) self.assertEquals(file_list, []) sys.stdout.close()
def testDoesntSoftResetIfNotAskedTo(self): """Test that we can apply a patch without doing a soft reset.""" scm = gclient_scm.GitWrapper(self.url, self.root_dir, '.') file_list = [] self.options.reset_patch_ref = False scm.update(self.options, None, file_list) self.assertEqual(self.githash('repo_1', 4), self.gitrevparse(self.root_dir)) scm.apply_patch_ref(self.url, 'refs/changes/35/1235/1', None, self.options, file_list) self.assertCommits([1, 2, 3, 4, 5, 6]) # The commit hash after cherry-picking is not known, but it must be # different from what the repo was synced at before patching. self.assertNotEqual(self.githash('repo_1', 4), self.gitrevparse(self.root_dir))
def testIgnoresAlreadyMergedCommits(self): scm = gclient_scm.GitWrapper(self.url, self.root_dir, '.') file_list = [] self.options.revision = 'refs/heads/master-with-5' scm.update(self.options, None, file_list) self.assertEqual(self.githash('repo_1', 12), self.gitrevparse(self.root_dir)) # When we try 'refs/changes/35/1235/1' on top of 'refs/heads/feature', # 'refs/changes/34/1234/1' will be an empty commit, since the changes were # already present in the tree as commit 11. # Make sure we deal with this gracefully. scm.apply_patch_ref(self.url, 'refs/changes/35/1235/1', None, self.options, file_list) self.assertCommits([1, 2, 3, 5, 6, 12]) self.assertEqual(self.githash('repo_1', 12), self.gitrevparse(self.root_dir))
def testRevertModified(self): if not self.enabled: return options = self.Options() scm = gclient_scm.GitWrapper(self.url, self.root_dir, self.relpath) file_list = [] scm.update(options, None, file_list) file_path = join(self.base_path, 'a') open(file_path, 'a').writelines('touched\n') file_list = [] scm.revert(options, self.args, file_list) self.assertEquals(file_list, [file_path]) file_list = [] scm.diff(options, self.args, file_list) self.assertEquals(file_list, []) self.assertEquals(scm.revinfo(options, self.args, None), 'a7142dc9f0009350b96a11f372b6ea658592aa95') sys.stdout.close()
def testCheckoutOriginFeaturePatchBranch(self): scm = gclient_scm.GitWrapper(self.url, self.root_dir, '.') file_list = [] # Sync to the hash instead of remote's refs/heads/feature. self.options.revision = self.githash('repo_1', 9) scm.update(self.options, None, file_list) self.assertEqual(self.githash('repo_1', 9), self.gitrevparse(self.root_dir)) # Apply refs/changes/34/1234/1, created for remote's master branch on top of # remote's feature branch. scm.apply_patch_ref(self.url, 'refs/changes/35/1235/1', 'refs/heads/master', self.options, file_list) # Commits 5 and 6 are part of the patch, and commits 1, 2, 7, 8 and 9 are # part of remote's feature branch. self.assertCommits([1, 2, 5, 6, 7, 8, 9]) self.assertEqual(self.githash('repo_1', 9), 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 testMirrorPushUrl(self): self.setUpMirror() scm = gclient_scm.GitWrapper(self.url, self.root_dir, '.') file_list = [] self.assertIsNotNone(scm._GetMirror(self.url, self.options)) scm.update(self.options, None, file_list) fetch_url = scm._Capture(['remote', 'get-url', 'origin']) self.assertTrue( fetch_url.startswith(self.mirror), msg='\n'.join([ 'Repository fetch url should be in the git cache mirror directory.', ' fetch_url: %s' % fetch_url, ' mirror: %s' % self.mirror])) push_url = scm._Capture(['remote', 'get-url', '--push', 'origin']) self.assertEqual(push_url, self.url)
def testDoesntRebasePatchOldCheckout(self): """Tests that we can apply a patch without rebasing it on an old checkout. """ scm = gclient_scm.GitWrapper(self.url, self.root_dir, '.') file_list = [] # Sync to commit 1 self.options.revision = self.githash('repo_1', 1) self.options.rebase_patch_ref = False scm.update(self.options, None, file_list) self.assertEqual(self.githash('repo_1', 1), self.gitrevparse(self.root_dir)) # Apply the change on top of that. scm.apply_patch_ref( self.url, 'refs/changes/35/1235/1', 'refs/heads/master', self.options, file_list) self.assertCommits([1, 2, 3, 5, 6]) self.assertEqual(self.githash('repo_1', 5), self.gitrevparse(self.root_dir))