| OLD | NEW |
| 1 # Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 # Copyright (c) 2009 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 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 172 if options.revision: | 172 if options.revision: |
| 173 # Override the revision number. | 173 # Override the revision number. |
| 174 revision = str(options.revision) | 174 revision = str(options.revision) |
| 175 if revision: | 175 if revision: |
| 176 rev_str = ' at %s' % revision | 176 rev_str = ' at %s' % revision |
| 177 | 177 |
| 178 if options.verbose: | 178 if options.verbose: |
| 179 print("\n_____ %s%s" % (self.relpath, rev_str)) | 179 print("\n_____ %s%s" % (self.relpath, rev_str)) |
| 180 | 180 |
| 181 if not os.path.exists(self.checkout_path): | 181 if not os.path.exists(self.checkout_path): |
| 182 self._Run(['clone', url, self.checkout_path], | 182 # Cloning |
| 183 cwd=self._root_dir, redirect_stdout=False) | 183 for i in range(3): |
| 184 try: |
| 185 self._Run(['clone', url, self.checkout_path], |
| 186 cwd=self._root_dir, redirect_stdout=False) |
| 187 break |
| 188 except gclient_utils.Error, e: |
| 189 # TODO(maruel): Hackish, should be fixed by moving _Run() to |
| 190 # CheckCall(). |
| 191 # Too bad we don't have access to the actual output. |
| 192 # We should check for "transfer closed with NNN bytes remaining to |
| 193 # read". In the meantime, just make sure .git exists. |
| 194 if (e.args[0] == 'git command clone returned 128' and |
| 195 os.path.exists(os.path.join(self.checkout_path, '.git'))): |
| 196 print str(e) |
| 197 print "Retrying..." |
| 198 continue |
| 199 raise e |
| 200 |
| 184 if revision: | 201 if revision: |
| 185 self._Run(['reset', '--hard', revision], redirect_stdout=False) | 202 self._Run(['reset', '--hard', revision], redirect_stdout=False) |
| 186 files = self._Run(['ls-files']).split() | 203 files = self._Run(['ls-files']).split() |
| 187 file_list.extend([os.path.join(self.checkout_path, f) for f in files]) | 204 file_list.extend([os.path.join(self.checkout_path, f) for f in files]) |
| 188 return | 205 return |
| 189 | 206 |
| 190 if not os.path.exists(os.path.join(self.checkout_path, '.git')): | 207 if not os.path.exists(os.path.join(self.checkout_path, '.git')): |
| 191 raise gclient_utils.Error('\n____ %s%s\n' | 208 raise gclient_utils.Error('\n____ %s%s\n' |
| 192 '\tPath is not a git repo. No .git dir.\n' | 209 '\tPath is not a git repo. No .git dir.\n' |
| 193 '\tTo resolve:\n' | 210 '\tTo resolve:\n' |
| 194 '\t\trm -rf %s\n' | 211 '\t\trm -rf %s\n' |
| 195 '\tAnd run gclient sync again\n' | 212 '\tAnd run gclient sync again\n' |
| 196 % (self.relpath, rev_str, self.relpath)) | 213 % (self.relpath, rev_str, self.relpath)) |
| 197 | 214 |
| 198 new_base = 'origin' | 215 new_base = 'origin' |
| 199 if revision: | 216 if revision: |
| 200 new_base = revision | 217 new_base = revision |
| 201 cur_branch = self._GetCurrentBranch() | 218 cur_branch = self._GetCurrentBranch() |
| 202 | 219 |
| 203 # Check if we are in a rebase conflict | 220 # Check if we are in a rebase conflict |
| 204 if cur_branch is None: | 221 if cur_branch is None: |
| 205 raise gclient_utils.Error('\n____ %s%s\n' | 222 raise gclient_utils.Error('\n____ %s%s\n' |
| 206 '\tAlready in a conflict, i.e. (no branch).\n' | 223 '\tAlready in a conflict, i.e. (no branch).\n' |
| 207 '\tFix the conflict and run gclient again.\n' | 224 '\tFix the conflict and run gclient again.\n' |
| 208 '\tOr to abort run:\n\t\tgit-rebase --abort\n' | 225 '\tOr to abort run:\n\t\tgit-rebase --abort\n' |
| 209 '\tSee man git-rebase for details.\n' | 226 '\tSee man git-rebase for details.\n' |
| 210 % (self.relpath, rev_str)) | 227 % (self.relpath, rev_str)) |
| 211 | 228 |
| 229 # TODO(maruel): Do we need to do an automatic retry here? Probably overkill |
| 212 merge_base = self._Run(['merge-base', 'HEAD', new_base]) | 230 merge_base = self._Run(['merge-base', 'HEAD', new_base]) |
| 213 self._Run(['remote', 'update'], redirect_stdout=False) | 231 self._Run(['remote', 'update'], redirect_stdout=False) |
| 214 files = self._Run(['diff', new_base, '--name-only']).split() | 232 files = self._Run(['diff', new_base, '--name-only']).split() |
| 215 file_list.extend([os.path.join(self.checkout_path, f) for f in files]) | 233 file_list.extend([os.path.join(self.checkout_path, f) for f in files]) |
| 216 if options.force: | 234 if options.force: |
| 217 self._Run(['reset', '--hard', merge_base], redirect_stdout=False) | 235 self._Run(['reset', '--hard', merge_base], redirect_stdout=False) |
| 218 self._Run(['rebase', '-v', '--onto', new_base, merge_base, cur_branch], | 236 try: |
| 219 redirect_stdout=False, checkrc=False) | 237 self._Run(['rebase', '-v', '--onto', new_base, merge_base, cur_branch], |
| 238 redirect_stdout=False) |
| 239 except gclient_utils.Error: |
| 240 pass |
| 220 | 241 |
| 221 # If the rebase generated a conflict, abort and ask user to fix | 242 # If the rebase generated a conflict, abort and ask user to fix |
| 222 if self._GetCurrentBranch() is None: | 243 if self._GetCurrentBranch() is None: |
| 223 raise gclient_utils.Error('\n____ %s%s\n' | 244 raise gclient_utils.Error('\n____ %s%s\n' |
| 224 '\nConflict while rebasing this branch.\n' | 245 '\nConflict while rebasing this branch.\n' |
| 225 'Fix the conflict and run gclient again.\n' | 246 'Fix the conflict and run gclient again.\n' |
| 226 'See man git-rebase for details.\n' | 247 'See man git-rebase for details.\n' |
| 227 % (self.relpath, rev_str)) | 248 % (self.relpath, rev_str)) |
| 228 | 249 |
| 229 print "Checked out revision %s." % self.revinfo(options, (), None) | 250 print "Checked out revision %s." % self.revinfo(options, (), None) |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 291 | 312 |
| 292 def _GetCurrentBranch(self): | 313 def _GetCurrentBranch(self): |
| 293 # Returns name of current branch | 314 # Returns name of current branch |
| 294 # Returns None if inside a (no branch) | 315 # Returns None if inside a (no branch) |
| 295 tokens = self._Run(['branch']).split() | 316 tokens = self._Run(['branch']).split() |
| 296 branch = tokens[tokens.index('*') + 1] | 317 branch = tokens[tokens.index('*') + 1] |
| 297 if branch == '(no': | 318 if branch == '(no': |
| 298 return None | 319 return None |
| 299 return branch | 320 return branch |
| 300 | 321 |
| 301 def _Run(self, args, cwd=None, checkrc=True, redirect_stdout=True): | 322 def _Run(self, args, cwd=None, redirect_stdout=True): |
| 302 # TODO(maruel): Merge with Capture? | 323 # TODO(maruel): Merge with Capture or better gclient_utils.CheckCall(). |
| 303 if cwd is None: | 324 if cwd is None: |
| 304 cwd = self.checkout_path | 325 cwd = self.checkout_path |
| 305 stdout=None | 326 stdout = None |
| 306 if redirect_stdout: | 327 if redirect_stdout: |
| 307 stdout=subprocess.PIPE | 328 stdout = subprocess.PIPE |
| 308 if cwd == None: | 329 if cwd == None: |
| 309 cwd = self.checkout_path | 330 cwd = self.checkout_path |
| 310 cmd = [self.COMMAND] | 331 cmd = [self.COMMAND] |
| 311 cmd.extend(args) | 332 cmd.extend(args) |
| 312 logging.debug(cmd) | 333 logging.debug(cmd) |
| 313 try: | 334 try: |
| 314 sp = subprocess.Popen(cmd, cwd=cwd, stdout=stdout) | 335 sp = subprocess.Popen(cmd, cwd=cwd, stdout=stdout) |
| 315 output = sp.communicate()[0] | 336 output = sp.communicate()[0] |
| 316 except OSError: | 337 except OSError: |
| 317 raise gclient_utils.Error("git command '%s' failed to run." % | 338 raise gclient_utils.Error("git command '%s' failed to run." % |
| 318 ' '.join(cmd) + "\nCheck that you have git installed.") | 339 ' '.join(cmd) + "\nCheck that you have git installed.") |
| 319 if checkrc and sp.returncode: | 340 if sp.returncode: |
| 320 raise gclient_utils.Error('git command %s returned %d' % | 341 raise gclient_utils.Error('git command %s returned %d' % |
| 321 (args[0], sp.returncode)) | 342 (args[0], sp.returncode)) |
| 322 if output is not None: | 343 if output is not None: |
| 323 return output.strip() | 344 return output.strip() |
| 324 | 345 |
| 325 | 346 |
| 326 class SVNWrapper(SCMWrapper, scm.SVN): | 347 class SVNWrapper(SCMWrapper, scm.SVN): |
| 327 """ Wrapper for SVN """ | 348 """ Wrapper for SVN """ |
| 328 | 349 |
| 329 def cleanup(self, options, args, file_list): | 350 def cleanup(self, options, args, file_list): |
| (...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 549 print("\n________ couldn't run \'%s\' in \'%s\':\nThe directory " | 570 print("\n________ couldn't run \'%s\' in \'%s\':\nThe directory " |
| 550 "does not exist." | 571 "does not exist." |
| 551 % (' '.join(command), path)) | 572 % (' '.join(command), path)) |
| 552 # There's no file list to retrieve. | 573 # There's no file list to retrieve. |
| 553 else: | 574 else: |
| 554 self.RunAndGetFileList(options, command, path, file_list) | 575 self.RunAndGetFileList(options, command, path, file_list) |
| 555 | 576 |
| 556 def FullUrlForRelativeUrl(self, url): | 577 def FullUrlForRelativeUrl(self, url): |
| 557 # Find the forth '/' and strip from there. A bit hackish. | 578 # Find the forth '/' and strip from there. A bit hackish. |
| 558 return '/'.join(self.url.split('/')[:4]) + url | 579 return '/'.join(self.url.split('/')[:4]) + url |
| OLD | NEW |