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')
示例#2
0
  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')
示例#5
0
  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))
示例#8
0
 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')
示例#10
0
  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()
示例#11
0
 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()
示例#12
0
 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()
示例#13
0
 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()
示例#14
0
 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')
示例#15
0
 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()
示例#16
0
 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)
示例#19
0
  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()
示例#21
0
  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))
示例#22
0
  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))
示例#23
0
 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()
示例#24
0
  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))
示例#25
0
  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))
示例#26
0
 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()
示例#27
0
  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))
示例#28
0
  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))