Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1102)

Side by Side Diff: gclient_scm.py

Issue 16763004: Repair broken git checkouts caused by aborting git clone. (Closed) Base URL: https://chromium.googlesource.com/chromium/tools/depot_tools.git@master
Patch Set: Fixed gclient status output interfering with tests. Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 # Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 # Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be 2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file. 3 # found in the LICENSE file.
4 4
5 """Gclient-specific SCM-specific operations.""" 5 """Gclient-specific SCM-specific operations."""
6 6
7 import logging 7 import logging
8 import os 8 import os
9 import posixpath 9 import posixpath
10 import re 10 import re
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after
230 # Not a fatal error, or even very interesting in a non-git-submodule 230 # Not a fatal error, or even very interesting in a non-git-submodule
231 # world. So just keep it quiet. 231 # world. So just keep it quiet.
232 pass 232 pass
233 try: 233 try:
234 gclient_utils.CheckCallAndFilter(cmd3, **kwargs) 234 gclient_utils.CheckCallAndFilter(cmd3, **kwargs)
235 except subprocess2.CalledProcessError: 235 except subprocess2.CalledProcessError:
236 gclient_utils.CheckCallAndFilter(cmd3 + ['always'], **kwargs) 236 gclient_utils.CheckCallAndFilter(cmd3 + ['always'], **kwargs)
237 237
238 gclient_utils.CheckCallAndFilter(cmd4, **kwargs) 238 gclient_utils.CheckCallAndFilter(cmd4, **kwargs)
239 239
240 def _FetchAndReset(self, revision, file_list, options):
241 """Equivalent to git fetch; git reset."""
242 quiet = []
243 if not options.verbose:
244 quiet = ['--quiet']
245 self._UpdateBranchHeads(options, fetch=False)
246 self._Run(['fetch', 'origin', '--prune'] + quiet, options)
247 self._Run(['reset', '--hard', revision] + quiet, options)
248 self.UpdateSubmoduleConfig()
249 files = self._Capture(['ls-files']).splitlines()
250 file_list.extend([os.path.join(self.checkout_path, f) for f in files])
251
240 def update(self, options, args, file_list): 252 def update(self, options, args, file_list):
241 """Runs git to update or transparently checkout the working copy. 253 """Runs git to update or transparently checkout the working copy.
242 254
243 All updated files will be appended to file_list. 255 All updated files will be appended to file_list.
244 256
245 Raises: 257 Raises:
246 Error: if can't get URL for relative path. 258 Error: if can't get URL for relative path.
247 """ 259 """
248 if args: 260 if args:
249 raise gclient_utils.Error("Unsupported argument(s): %s" % ",".join(args)) 261 raise gclient_utils.Error("Unsupported argument(s): %s" % ",".join(args))
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
331 if (current_url != url and 343 if (current_url != url and
332 url != 'git://foo' and 344 url != 'git://foo' and
333 subprocess2.capture( 345 subprocess2.capture(
334 ['git', 'config', 'remote.origin.gclient-auto-fix-url'], 346 ['git', 'config', 'remote.origin.gclient-auto-fix-url'],
335 cwd=self.checkout_path).strip() != 'False'): 347 cwd=self.checkout_path).strip() != 'False'):
336 print('_____ switching %s to a new upstream' % self.relpath) 348 print('_____ switching %s to a new upstream' % self.relpath)
337 # Make sure it's clean 349 # Make sure it's clean
338 self._CheckClean(rev_str) 350 self._CheckClean(rev_str)
339 # Switch over to the new upstream 351 # Switch over to the new upstream
340 self._Run(['remote', 'set-url', 'origin', url], options) 352 self._Run(['remote', 'set-url', 'origin', url], options)
341 quiet = [] 353 self._FetchAndReset(revision, file_list, options)
342 if not options.verbose:
343 quiet = ['--quiet']
344 self._UpdateBranchHeads(options, fetch=False)
345 self._Run(['fetch', 'origin', '--prune'] + quiet, options)
346 self._Run(['reset', '--hard', revision] + quiet, options)
347 self.UpdateSubmoduleConfig()
348 files = self._Capture(['ls-files']).splitlines()
349 file_list.extend([os.path.join(self.checkout_path, f) for f in files])
350 return 354 return
351 355
356 if not self._IsValidGitRepo():
357 # .git directory is hosed for some reason, set it back up.
358 print('_____ %s/.git is corrupted, rebuilding' % self.relpath)
359 self._Run(['init'], options)
360 self._Run(['remote', 'set-url', 'origin', url], options)
361
362 if not self._HasHead():
363 # Previous checkout was aborted before branches could be created in repo,
364 # so we need to reconstruct them here.
365 self._Run(['pull', 'origin', 'master'], options)
366 self._FetchAndReset(revision, file_list, options)
367
352 cur_branch = self._GetCurrentBranch() 368 cur_branch = self._GetCurrentBranch()
353 369
354 # Cases: 370 # Cases:
355 # 0) HEAD is detached. Probably from our initial clone. 371 # 0) HEAD is detached. Probably from our initial clone.
356 # - make sure HEAD is contained by a named ref, then update. 372 # - make sure HEAD is contained by a named ref, then update.
357 # Cases 1-4. HEAD is a branch. 373 # Cases 1-4. HEAD is a branch.
358 # 1) current branch is not tracking a remote branch (could be git-svn) 374 # 1) current branch is not tracking a remote branch (could be git-svn)
359 # - try to rebase onto the new hash or branch 375 # - try to rebase onto the new hash or branch
360 # 2) current branch is tracking a remote branch with local committed 376 # 2) current branch is tracking a remote branch with local committed
361 # changes, but the DEPS file switched to point to a hash 377 # changes, but the DEPS file switched to point to a hash
(...skipping 432 matching lines...) Expand 10 before | Expand all | Expand 10 after
794 "manually.\ncd %s && git " % 810 "manually.\ncd %s && git " %
795 self.checkout_path 811 self.checkout_path
796 + "%s" % ' '.join(rebase_cmd)) 812 + "%s" % ' '.join(rebase_cmd))
797 813
798 print(rebase_output.strip()) 814 print(rebase_output.strip())
799 if not options.verbose: 815 if not options.verbose:
800 # Make the output a little prettier. It's nice to have some 816 # Make the output a little prettier. It's nice to have some
801 # whitespace between projects when syncing. 817 # whitespace between projects when syncing.
802 print('') 818 print('')
803 819
820 def _IsValidGitRepo(self):
821 """Returns if the directory is a valid git repository.
822
823 Checks if git status works.
824 """
825 try:
826 self._Capture(['status'])
Isaac (away) 2013/07/16 10:06:21 status is a expensive command on some projects (li
827 return True
828 except subprocess2.CalledProcessError:
829 return False
830
831 def _HasHead(self):
832 """Returns True if any commit is checked out.
833
834 This is done by checking if rev-parse HEAD works in the current repository.
835 """
836 try:
837 self._GetCurrentBranch()
838 return True
839 except subprocess2.CalledProcessError:
840 return False
841
804 @staticmethod 842 @staticmethod
805 def _CheckMinVersion(min_version): 843 def _CheckMinVersion(min_version):
806 (ok, current_version) = scm.GIT.AssertVersion(min_version) 844 (ok, current_version) = scm.GIT.AssertVersion(min_version)
807 if not ok: 845 if not ok:
808 raise gclient_utils.Error('git version %s < minimum required %s' % 846 raise gclient_utils.Error('git version %s < minimum required %s' %
809 (current_version, min_version)) 847 (current_version, min_version))
810 848
811 def _IsRebasing(self): 849 def _IsRebasing(self):
812 # Check for any of REBASE-i/REBASE-m/REBASE/AM. Unfortunately git doesn't 850 # Check for any of REBASE-i/REBASE-m/REBASE/AM. Unfortunately git doesn't
813 # have a plumbing command to determine whether a rebase is in progress, so 851 # have a plumbing command to determine whether a rebase is in progress, so
(...skipping 477 matching lines...) Expand 10 before | Expand all | Expand 10 after
1291 new_command.append('--force') 1329 new_command.append('--force')
1292 if command[0] != 'checkout' and scm.SVN.AssertVersion('1.6')[0]: 1330 if command[0] != 'checkout' and scm.SVN.AssertVersion('1.6')[0]:
1293 new_command.extend(('--accept', 'theirs-conflict')) 1331 new_command.extend(('--accept', 'theirs-conflict'))
1294 elif options.manually_grab_svn_rev: 1332 elif options.manually_grab_svn_rev:
1295 new_command.append('--force') 1333 new_command.append('--force')
1296 if command[0] != 'checkout' and scm.SVN.AssertVersion('1.6')[0]: 1334 if command[0] != 'checkout' and scm.SVN.AssertVersion('1.6')[0]:
1297 new_command.extend(('--accept', 'postpone')) 1335 new_command.extend(('--accept', 'postpone'))
1298 elif command[0] != 'checkout' and scm.SVN.AssertVersion('1.6')[0]: 1336 elif command[0] != 'checkout' and scm.SVN.AssertVersion('1.6')[0]:
1299 new_command.extend(('--accept', 'postpone')) 1337 new_command.extend(('--accept', 'postpone'))
1300 return new_command 1338 return new_command
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698