OLD | NEW |
1 # Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 # Copyright (c) 2010 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 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
120 """Wrapper for Git""" | 120 """Wrapper for Git""" |
121 | 121 |
122 @staticmethod | 122 @staticmethod |
123 def cleanup(options, args, file_list): | 123 def cleanup(options, args, file_list): |
124 """'Cleanup' the repo. | 124 """'Cleanup' the repo. |
125 | 125 |
126 There's no real git equivalent for the svn cleanup command, do a no-op. | 126 There's no real git equivalent for the svn cleanup command, do a no-op. |
127 """ | 127 """ |
128 | 128 |
129 def diff(self, options, args, file_list): | 129 def diff(self, options, args, file_list): |
130 merge_base = self._Run(['merge-base', 'HEAD', 'origin']) | 130 merge_base = self._Capture(['merge-base', 'HEAD', 'origin']) |
131 self._Run(['diff', merge_base], redirect_stdout=False) | 131 self._Run(['diff', merge_base]) |
132 | 132 |
133 def export(self, options, args, file_list): | 133 def export(self, options, args, file_list): |
134 """Export a clean directory tree into the given path. | 134 """Export a clean directory tree into the given path. |
135 | 135 |
136 Exports into the specified directory, creating the path if it does | 136 Exports into the specified directory, creating the path if it does |
137 already exist. | 137 already exist. |
138 """ | 138 """ |
139 assert len(args) == 1 | 139 assert len(args) == 1 |
140 export_path = os.path.abspath(os.path.join(args[0], self.relpath)) | 140 export_path = os.path.abspath(os.path.join(args[0], self.relpath)) |
141 if not os.path.exists(export_path): | 141 if not os.path.exists(export_path): |
142 os.makedirs(export_path) | 142 os.makedirs(export_path) |
143 self._Run(['checkout-index', '-a', '--prefix=%s/' % export_path], | 143 self._Run(['checkout-index', '-a', '--prefix=%s/' % export_path]) |
144 redirect_stdout=False) | |
145 | 144 |
146 def pack(self, options, args, file_list): | 145 def pack(self, options, args, file_list): |
147 """Generates a patch file which can be applied to the root of the | 146 """Generates a patch file which can be applied to the root of the |
148 repository. | 147 repository. |
149 | 148 |
150 The patch file is generated from a diff of the merge base of HEAD and | 149 The patch file is generated from a diff of the merge base of HEAD and |
151 its upstream branch. | 150 its upstream branch. |
152 """ | 151 """ |
153 merge_base = self._Run(['merge-base', 'HEAD', 'origin']) | 152 merge_base = self._Capture(['merge-base', 'HEAD', 'origin']) |
154 gclient_utils.CheckCallAndFilter( | 153 gclient_utils.CheckCallAndFilter( |
155 ['git', 'diff', merge_base], | 154 ['git', 'diff', merge_base], |
156 cwd=self.checkout_path, | 155 cwd=self.checkout_path, |
157 filter_fn=DiffFilterer(self.relpath, options.stdout).Filter, | 156 filter_fn=DiffFilterer(self.relpath, options.stdout).Filter, |
158 stdout=options.stdout) | 157 stdout=options.stdout) |
159 | 158 |
160 def update(self, options, args, file_list): | 159 def update(self, options, args, file_list): |
161 """Runs git to update or transparently checkout the working copy. | 160 """Runs git to update or transparently checkout the working copy. |
162 | 161 |
163 All updated files will be appended to file_list. | 162 All updated files will be appended to file_list. |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
195 elif revision.startswith('origin/'): | 194 elif revision.startswith('origin/'): |
196 # For compatability with old naming, translate 'origin' to 'refs/heads' | 195 # For compatability with old naming, translate 'origin' to 'refs/heads' |
197 revision = revision.replace('origin/', 'refs/heads/') | 196 revision = revision.replace('origin/', 'refs/heads/') |
198 rev_type = "branch" | 197 rev_type = "branch" |
199 else: | 198 else: |
200 # hash is also a tag, only make a distinction at checkout | 199 # hash is also a tag, only make a distinction at checkout |
201 rev_type = "hash" | 200 rev_type = "hash" |
202 | 201 |
203 if not os.path.exists(self.checkout_path): | 202 if not os.path.exists(self.checkout_path): |
204 self._Clone(revision, url, options) | 203 self._Clone(revision, url, options) |
205 files = self._Run(['ls-files']).split() | 204 files = self._Capture(['ls-files']).split() |
206 file_list.extend([os.path.join(self.checkout_path, f) for f in files]) | 205 file_list.extend([os.path.join(self.checkout_path, f) for f in files]) |
207 if not verbose: | 206 if not verbose: |
208 # Make the output a little prettier. It's nice to have some whitespace | 207 # Make the output a little prettier. It's nice to have some whitespace |
209 # between projects when cloning. | 208 # between projects when cloning. |
210 options.stdout.write('\n') | 209 options.stdout.write('\n') |
211 return | 210 return |
212 | 211 |
213 if not os.path.exists(os.path.join(self.checkout_path, '.git')): | 212 if not os.path.exists(os.path.join(self.checkout_path, '.git')): |
214 raise gclient_utils.Error('\n____ %s%s\n' | 213 raise gclient_utils.Error('\n____ %s%s\n' |
215 '\tPath is not a git repo. No .git dir.\n' | 214 '\tPath is not a git repo. No .git dir.\n' |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
276 continue | 275 continue |
277 raise | 276 raise |
278 | 277 |
279 if verbose: | 278 if verbose: |
280 options.stdout.write(remote_output.strip() + '\n') | 279 options.stdout.write(remote_output.strip() + '\n') |
281 # git remote update prints to stderr when used with --verbose | 280 # git remote update prints to stderr when used with --verbose |
282 options.stdout.write(remote_err.strip() + '\n') | 281 options.stdout.write(remote_err.strip() + '\n') |
283 | 282 |
284 # This is a big hammer, debatable if it should even be here... | 283 # This is a big hammer, debatable if it should even be here... |
285 if options.force or options.reset: | 284 if options.force or options.reset: |
286 self._Run(['reset', '--hard', 'HEAD'], redirect_stdout=False) | 285 self._Run(['reset', '--hard', 'HEAD']) |
287 | 286 |
288 if current_type == 'detached': | 287 if current_type == 'detached': |
289 # case 0 | 288 # case 0 |
290 self._CheckClean(rev_str) | 289 self._CheckClean(rev_str) |
291 self._CheckDetachedHead(rev_str, options) | 290 self._CheckDetachedHead(rev_str, options) |
292 self._Run(['checkout', '--quiet', '%s^0' % revision]) | 291 self._Capture(['checkout', '--quiet', '%s^0' % revision]) |
293 if not printed_path: | 292 if not printed_path: |
294 options.stdout.write('\n_____ %s%s\n' % (self.relpath, rev_str)) | 293 options.stdout.write('\n_____ %s%s\n' % (self.relpath, rev_str)) |
295 elif current_type == 'hash': | 294 elif current_type == 'hash': |
296 # case 1 | 295 # case 1 |
297 if scm.GIT.IsGitSvn(self.checkout_path) and upstream_branch is not None: | 296 if scm.GIT.IsGitSvn(self.checkout_path) and upstream_branch is not None: |
298 # Our git-svn branch (upstream_branch) is our upstream | 297 # Our git-svn branch (upstream_branch) is our upstream |
299 self._AttemptRebase(upstream_branch, files, options, | 298 self._AttemptRebase(upstream_branch, files, options, |
300 newbase=revision, printed_path=printed_path) | 299 newbase=revision, printed_path=printed_path) |
301 printed_path = True | 300 printed_path = True |
302 else: | 301 else: |
(...skipping 17 matching lines...) Expand all Loading... |
320 if not printed_path: | 319 if not printed_path: |
321 options.stdout.write('\n_____ %s%s\n' % (self.relpath, rev_str)) | 320 options.stdout.write('\n_____ %s%s\n' % (self.relpath, rev_str)) |
322 switch_error = ("Switching upstream branch from %s to %s\n" | 321 switch_error = ("Switching upstream branch from %s to %s\n" |
323 % (upstream_branch, new_base) + | 322 % (upstream_branch, new_base) + |
324 "Please merge or rebase manually:\n" + | 323 "Please merge or rebase manually:\n" + |
325 "cd %s; git rebase %s\n" % (self.checkout_path, new_base) + | 324 "cd %s; git rebase %s\n" % (self.checkout_path, new_base) + |
326 "OR git checkout -b <some new branch> %s" % new_base) | 325 "OR git checkout -b <some new branch> %s" % new_base) |
327 raise gclient_utils.Error(switch_error) | 326 raise gclient_utils.Error(switch_error) |
328 else: | 327 else: |
329 # case 3 - the default case | 328 # case 3 - the default case |
330 files = self._Run(['diff', upstream_branch, '--name-only']).split() | 329 files = self._Capture(['diff', upstream_branch, '--name-only']).split() |
331 if verbose: | 330 if verbose: |
332 options.stdout.write('Trying fast-forward merge to branch : %s\n' % | 331 options.stdout.write('Trying fast-forward merge to branch : %s\n' % |
333 upstream_branch) | 332 upstream_branch) |
334 try: | 333 try: |
335 merge_output, merge_err = scm.GIT.Capture(['merge', '--ff-only', | 334 merge_output, merge_err = scm.GIT.Capture(['merge', '--ff-only', |
336 upstream_branch], | 335 upstream_branch], |
337 self.checkout_path, | 336 self.checkout_path, |
338 print_error=False) | 337 print_error=False) |
339 except gclient_utils.CheckCallError, e: | 338 except gclient_utils.CheckCallError, e: |
340 if re.match('fatal: Not possible to fast-forward, aborting.', e.stderr): | 339 if re.match('fatal: Not possible to fast-forward, aborting.', e.stderr): |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
419 # Don't reuse the args. | 418 # Don't reuse the args. |
420 return self.update(options, [], file_list) | 419 return self.update(options, [], file_list) |
421 | 420 |
422 default_rev = "refs/heads/master" | 421 default_rev = "refs/heads/master" |
423 _, deps_revision = gclient_utils.SplitUrlRevision(self.url) | 422 _, deps_revision = gclient_utils.SplitUrlRevision(self.url) |
424 if not deps_revision: | 423 if not deps_revision: |
425 deps_revision = default_rev | 424 deps_revision = default_rev |
426 if deps_revision.startswith('refs/heads/'): | 425 if deps_revision.startswith('refs/heads/'): |
427 deps_revision = deps_revision.replace('refs/heads/', 'origin/') | 426 deps_revision = deps_revision.replace('refs/heads/', 'origin/') |
428 | 427 |
429 files = self._Run(['diff', deps_revision, '--name-only']).split() | 428 files = self._Capture(['diff', deps_revision, '--name-only']).split() |
430 self._Run(['reset', '--hard', deps_revision], redirect_stdout=False) | 429 self._Run(['reset', '--hard', deps_revision]) |
431 file_list.extend([os.path.join(self.checkout_path, f) for f in files]) | 430 file_list.extend([os.path.join(self.checkout_path, f) for f in files]) |
432 | 431 |
433 def revinfo(self, options, args, file_list): | 432 def revinfo(self, options, args, file_list): |
434 """Display revision""" | 433 """Returns revision""" |
435 return self._Run(['rev-parse', 'HEAD']) | 434 return self._Capture(['rev-parse', 'HEAD']) |
436 | 435 |
437 def runhooks(self, options, args, file_list): | 436 def runhooks(self, options, args, file_list): |
438 self.status(options, args, file_list) | 437 self.status(options, args, file_list) |
439 | 438 |
440 def status(self, options, args, file_list): | 439 def status(self, options, args, file_list): |
441 """Display status information.""" | 440 """Display status information.""" |
442 if not os.path.isdir(self.checkout_path): | 441 if not os.path.isdir(self.checkout_path): |
443 options.stdout.write( | 442 options.stdout.write( |
444 ('\n________ couldn\'t run status in %s:\nThe directory ' | 443 ('\n________ couldn\'t run status in %s:\nThe directory ' |
445 'does not exist.\n') % self.checkout_path) | 444 'does not exist.\n') % self.checkout_path) |
446 else: | 445 else: |
447 merge_base = self._Run(['merge-base', 'HEAD', 'origin']) | 446 merge_base = self._Capture(['merge-base', 'HEAD', 'origin']) |
448 self._Run(['diff', '--name-status', merge_base], redirect_stdout=False) | 447 self._Run(['diff', '--name-status', merge_base]) |
449 files = self._Run(['diff', '--name-only', merge_base]).split() | 448 files = self._Capture(['diff', '--name-only', merge_base]).split() |
450 file_list.extend([os.path.join(self.checkout_path, f) for f in files]) | 449 file_list.extend([os.path.join(self.checkout_path, f) for f in files]) |
451 | 450 |
452 def FullUrlForRelativeUrl(self, url): | 451 def FullUrlForRelativeUrl(self, url): |
453 # Strip from last '/' | 452 # Strip from last '/' |
454 # Equivalent to unix basename | 453 # Equivalent to unix basename |
455 base_url = self.url | 454 base_url = self.url |
456 return base_url[:base_url.rfind('/')] + url | 455 return base_url[:base_url.rfind('/')] + url |
457 | 456 |
458 def _Clone(self, revision, url, options): | 457 def _Clone(self, revision, url, options): |
459 """Clone a git repository from the given URL. | 458 """Clone a git repository from the given URL. |
(...skipping 14 matching lines...) Expand all Loading... |
474 detach_head = False | 473 detach_head = False |
475 else: | 474 else: |
476 clone_cmd.append('--no-checkout') | 475 clone_cmd.append('--no-checkout') |
477 detach_head = True | 476 detach_head = True |
478 if options.verbose: | 477 if options.verbose: |
479 clone_cmd.append('--verbose') | 478 clone_cmd.append('--verbose') |
480 clone_cmd.extend([url, self.checkout_path]) | 479 clone_cmd.extend([url, self.checkout_path]) |
481 | 480 |
482 for _ in range(3): | 481 for _ in range(3): |
483 try: | 482 try: |
484 self._Run(clone_cmd, cwd=self._root_dir, redirect_stdout=False) | 483 self._Run(clone_cmd, cwd=self._root_dir) |
485 break | 484 break |
486 except gclient_utils.Error, e: | 485 except gclient_utils.Error, e: |
487 # TODO(maruel): Hackish, should be fixed by moving _Run() to | 486 # TODO(maruel): Hackish, should be fixed by moving _Run() to |
488 # CheckCall(). | 487 # CheckCall(). |
489 # Too bad we don't have access to the actual output. | 488 # Too bad we don't have access to the actual output. |
490 # We should check for "transfer closed with NNN bytes remaining to | 489 # We should check for "transfer closed with NNN bytes remaining to |
491 # read". In the meantime, just make sure .git exists. | 490 # read". In the meantime, just make sure .git exists. |
492 if (e.args[0] == 'git command clone returned 128' and | 491 if (e.args[0] == 'git command clone returned 128' and |
493 os.path.exists(os.path.join(self.checkout_path, '.git'))): | 492 os.path.exists(os.path.join(self.checkout_path, '.git'))): |
494 options.stdout.write(str(e) + '\n') | 493 options.stdout.write(str(e) + '\n') |
495 options.stdout.write('Retrying...\n') | 494 options.stdout.write('Retrying...\n') |
496 continue | 495 continue |
497 raise e | 496 raise e |
498 | 497 |
499 if detach_head: | 498 if detach_head: |
500 # Squelch git's very verbose detached HEAD warning and use our own | 499 # Squelch git's very verbose detached HEAD warning and use our own |
501 self._Run(['checkout', '--quiet', '%s^0' % revision]) | 500 self._Capture(['checkout', '--quiet', '%s^0' % revision]) |
502 options.stdout.write( | 501 options.stdout.write( |
503 ('Checked out %s to a detached HEAD. Before making any commits\n' | 502 ('Checked out %s to a detached HEAD. Before making any commits\n' |
504 'in this repo, you should use \'git checkout <branch>\' to switch to\n' | 503 'in this repo, you should use \'git checkout <branch>\' to switch to\n' |
505 'an existing branch or use \'git checkout origin -b <branch>\' to\n' | 504 'an existing branch or use \'git checkout origin -b <branch>\' to\n' |
506 'create a new branch for your work.') % revision) | 505 'create a new branch for your work.') % revision) |
507 | 506 |
508 def _AttemptRebase(self, upstream, files, options, newbase=None, | 507 def _AttemptRebase(self, upstream, files, options, newbase=None, |
509 branch=None, printed_path=False): | 508 branch=None, printed_path=False): |
510 """Attempt to rebase onto either upstream or, if specified, newbase.""" | 509 """Attempt to rebase onto either upstream or, if specified, newbase.""" |
511 files.extend(self._Run(['diff', upstream, '--name-only']).split()) | 510 files.extend(self._Capture(['diff', upstream, '--name-only']).split()) |
512 revision = upstream | 511 revision = upstream |
513 if newbase: | 512 if newbase: |
514 revision = newbase | 513 revision = newbase |
515 if not printed_path: | 514 if not printed_path: |
516 options.stdout.write('\n_____ %s : Attempting rebase onto %s...\n' % ( | 515 options.stdout.write('\n_____ %s : Attempting rebase onto %s...\n' % ( |
517 self.relpath, revision)) | 516 self.relpath, revision)) |
518 printed_path = True | 517 printed_path = True |
519 else: | 518 else: |
520 options.stdout.write('Attempting rebase onto %s...\n' % revision) | 519 options.stdout.write('Attempting rebase onto %s...\n' % revision) |
521 | 520 |
(...skipping 16 matching lines...) Expand all Loading... |
538 if re.match(r'cannot rebase: you have unstaged changes', e.stderr) or \ | 537 if re.match(r'cannot rebase: you have unstaged changes', e.stderr) or \ |
539 re.match(r'cannot rebase: your index contains uncommitted changes', | 538 re.match(r'cannot rebase: your index contains uncommitted changes', |
540 e.stderr): | 539 e.stderr): |
541 while True: | 540 while True: |
542 rebase_action = str(raw_input("Cannot rebase because of unstaged " | 541 rebase_action = str(raw_input("Cannot rebase because of unstaged " |
543 "changes.\n'git reset --hard HEAD' ?\n" | 542 "changes.\n'git reset --hard HEAD' ?\n" |
544 "WARNING: destroys any uncommitted " | 543 "WARNING: destroys any uncommitted " |
545 "work in your current branch!" | 544 "work in your current branch!" |
546 " (y)es / (q)uit / (s)how : ")) | 545 " (y)es / (q)uit / (s)how : ")) |
547 if re.match(r'yes|y', rebase_action, re.I): | 546 if re.match(r'yes|y', rebase_action, re.I): |
548 self._Run(['reset', '--hard', 'HEAD'], redirect_stdout=False) | 547 self._Run(['reset', '--hard', 'HEAD']) |
549 # Should this be recursive? | 548 # Should this be recursive? |
550 rebase_output, rebase_err = scm.GIT.Capture(rebase_cmd, | 549 rebase_output, rebase_err = scm.GIT.Capture(rebase_cmd, |
551 self.checkout_path) | 550 self.checkout_path) |
552 break | 551 break |
553 elif re.match(r'quit|q', rebase_action, re.I): | 552 elif re.match(r'quit|q', rebase_action, re.I): |
554 raise gclient_utils.Error("Please merge or rebase manually\n" | 553 raise gclient_utils.Error("Please merge or rebase manually\n" |
555 "cd %s && git " % self.checkout_path | 554 "cd %s && git " % self.checkout_path |
556 + "%s" % ' '.join(rebase_cmd)) | 555 + "%s" % ' '.join(rebase_cmd)) |
557 elif re.match(r'show|s', rebase_action, re.I): | 556 elif re.match(r'show|s', rebase_action, re.I): |
558 options.stdout.write('\n%s\n' % e.stderr.strip()) | 557 options.stdout.write('\n%s\n' % e.stderr.strip()) |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
631 # Commit is not contained by any rev. See if the user is rebasing: | 630 # Commit is not contained by any rev. See if the user is rebasing: |
632 if self._IsRebasing(): | 631 if self._IsRebasing(): |
633 # Punt to the user | 632 # Punt to the user |
634 raise gclient_utils.Error('\n____ %s%s\n' | 633 raise gclient_utils.Error('\n____ %s%s\n' |
635 '\tAlready in a conflict, i.e. (no branch).\n' | 634 '\tAlready in a conflict, i.e. (no branch).\n' |
636 '\tFix the conflict and run gclient again.\n' | 635 '\tFix the conflict and run gclient again.\n' |
637 '\tOr to abort run:\n\t\tgit-rebase --abort\n' | 636 '\tOr to abort run:\n\t\tgit-rebase --abort\n' |
638 '\tSee man git-rebase for details.\n' | 637 '\tSee man git-rebase for details.\n' |
639 % (self.relpath, rev_str)) | 638 % (self.relpath, rev_str)) |
640 # Let's just save off the commit so we can proceed. | 639 # Let's just save off the commit so we can proceed. |
641 name = "saved-by-gclient-" + self._Run(["rev-parse", "--short", "HEAD"]) | 640 name = ('saved-by-gclient-' + |
642 self._Run(["branch", name]) | 641 self._Capture(['rev-parse', '--short', 'HEAD'])) |
| 642 self._Capture(['branch', name]) |
643 options.stdout.write( | 643 options.stdout.write( |
644 '\n_____ found an unreferenced commit and saved it as \'%s\'\n' % | 644 '\n_____ found an unreferenced commit and saved it as \'%s\'\n' % |
645 name) | 645 name) |
646 | 646 |
647 def _GetCurrentBranch(self): | 647 def _GetCurrentBranch(self): |
648 # Returns name of current branch or None for detached HEAD | 648 # Returns name of current branch or None for detached HEAD |
649 branch = self._Run(['rev-parse', '--abbrev-ref=strict', 'HEAD']) | 649 branch = self._Capture(['rev-parse', '--abbrev-ref=strict', 'HEAD']) |
650 if branch == 'HEAD': | 650 if branch == 'HEAD': |
651 return None | 651 return None |
652 return branch | 652 return branch |
653 | 653 |
654 def _Run(self, args, cwd=None, redirect_stdout=True): | 654 def _Capture(self, args): |
655 # TODO(maruel): Merge with Capture or better gclient_utils.CheckCall(). | 655 return gclient_utils.CheckCall(['git'] + args, |
656 if cwd is None: | 656 cwd=self.checkout_path)[0].strip() |
657 cwd = self.checkout_path | 657 |
658 stdout = None | 658 def _Run(self, args, **kwargs): |
659 if redirect_stdout: | 659 kwargs.setdefault('cwd', self.checkout_path) |
660 stdout = subprocess.PIPE | |
661 if cwd == None: | |
662 cwd = self.checkout_path | |
663 cmd = ['git'] + args | |
664 logging.debug(cmd) | |
665 try: | 660 try: |
666 sp = gclient_utils.Popen(cmd, cwd=cwd, stdout=stdout) | 661 gclient_utils.Popen(['git'] + args, **kwargs).communicate() |
667 output = sp.communicate()[0] | |
668 except OSError: | 662 except OSError: |
669 raise gclient_utils.Error("git command '%s' failed to run." % | 663 raise gclient_utils.Error("git command '%s' failed to run." % |
670 ' '.join(cmd) + "\nCheck that you have git installed.") | 664 ' '.join(cmd) + "\nCheck that you have git installed.") |
671 if sp.returncode: | |
672 raise gclient_utils.Error('git command %s returned %d' % | |
673 (args[0], sp.returncode)) | |
674 if output is not None: | |
675 return output.strip() | |
676 | 665 |
677 | 666 |
678 class SVNWrapper(SCMWrapper): | 667 class SVNWrapper(SCMWrapper): |
679 """ Wrapper for SVN """ | 668 """ Wrapper for SVN """ |
680 | 669 |
681 def cleanup(self, options, args, file_list): | 670 def cleanup(self, options, args, file_list): |
682 """Cleanup working copy.""" | 671 """Cleanup working copy.""" |
683 self._Run(['cleanup'] + args, options) | 672 self._Run(['cleanup'] + args, options) |
684 | 673 |
685 def diff(self, options, args, file_list): | 674 def diff(self, options, args, file_list): |
(...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
973 | 962 |
974 This method returns a new list to be used as a command.""" | 963 This method returns a new list to be used as a command.""" |
975 new_command = command[:] | 964 new_command = command[:] |
976 if revision: | 965 if revision: |
977 new_command.extend(['--revision', str(revision).strip()]) | 966 new_command.extend(['--revision', str(revision).strip()]) |
978 # --force was added to 'svn update' in svn 1.5. | 967 # --force was added to 'svn update' in svn 1.5. |
979 if ((options.force or options.manually_grab_svn_rev) and | 968 if ((options.force or options.manually_grab_svn_rev) and |
980 scm.SVN.AssertVersion("1.5")[0]): | 969 scm.SVN.AssertVersion("1.5")[0]): |
981 new_command.append('--force') | 970 new_command.append('--force') |
982 return new_command | 971 return new_command |
OLD | NEW |