| OLD | NEW |
| 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 collections | 7 import collections |
| 8 import logging | 8 import logging |
| 9 import os | 9 import os |
| 10 import posixpath | 10 import posixpath |
| (...skipping 455 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 466 self._CheckClean(rev_str) | 466 self._CheckClean(rev_str) |
| 467 self._CheckDetachedHead(rev_str, options) | 467 self._CheckDetachedHead(rev_str, options) |
| 468 self._Capture(['checkout', '--quiet', '%s' % revision]) | 468 self._Capture(['checkout', '--quiet', '%s' % revision]) |
| 469 if not printed_path: | 469 if not printed_path: |
| 470 print('\n_____ %s%s' % (self.relpath, rev_str)) | 470 print('\n_____ %s%s' % (self.relpath, rev_str)) |
| 471 elif current_type == 'hash': | 471 elif current_type == 'hash': |
| 472 # case 1 | 472 # case 1 |
| 473 if scm.GIT.IsGitSvn(self.checkout_path) and upstream_branch is not None: | 473 if scm.GIT.IsGitSvn(self.checkout_path) and upstream_branch is not None: |
| 474 # Our git-svn branch (upstream_branch) is our upstream | 474 # Our git-svn branch (upstream_branch) is our upstream |
| 475 self._AttemptRebase(upstream_branch, files, options, | 475 self._AttemptRebase(upstream_branch, files, options, |
| 476 newbase=revision, printed_path=printed_path) | 476 newbase=revision, printed_path=printed_path, |
| 477 merge=options.merge) |
| 477 printed_path = True | 478 printed_path = True |
| 478 else: | 479 else: |
| 479 # Can't find a merge-base since we don't know our upstream. That makes | 480 # Can't find a merge-base since we don't know our upstream. That makes |
| 480 # this command VERY likely to produce a rebase failure. For now we | 481 # this command VERY likely to produce a rebase failure. For now we |
| 481 # assume origin is our upstream since that's what the old behavior was. | 482 # assume origin is our upstream since that's what the old behavior was. |
| 482 upstream_branch = self.remote | 483 upstream_branch = self.remote |
| 483 if options.revision or deps_revision: | 484 if options.revision or deps_revision: |
| 484 upstream_branch = revision | 485 upstream_branch = revision |
| 485 self._AttemptRebase(upstream_branch, files, options, | 486 self._AttemptRebase(upstream_branch, files, options, |
| 486 printed_path=printed_path) | 487 printed_path=printed_path, merge=options.merge) |
| 487 printed_path = True | 488 printed_path = True |
| 488 elif rev_type == 'hash': | 489 elif rev_type == 'hash': |
| 489 # case 2 | 490 # case 2 |
| 490 self._AttemptRebase(upstream_branch, files, options, | 491 self._AttemptRebase(upstream_branch, files, options, |
| 491 newbase=revision, printed_path=printed_path) | 492 newbase=revision, printed_path=printed_path, |
| 493 merge=options.merge) |
| 492 printed_path = True | 494 printed_path = True |
| 493 elif revision.replace('heads', 'remotes/' + self.remote) != upstream_branch: | 495 elif revision.replace('heads', 'remotes/' + self.remote) != upstream_branch: |
| 494 # case 4 | 496 # case 4 |
| 495 new_base = revision.replace('heads', 'remotes/' + self.remote) | 497 new_base = revision.replace('heads', 'remotes/' + self.remote) |
| 496 if not printed_path: | 498 if not printed_path: |
| 497 print('\n_____ %s%s' % (self.relpath, rev_str)) | 499 print('\n_____ %s%s' % (self.relpath, rev_str)) |
| 498 switch_error = ("Switching upstream branch from %s to %s\n" | 500 switch_error = ("Switching upstream branch from %s to %s\n" |
| 499 % (upstream_branch, new_base) + | 501 % (upstream_branch, new_base) + |
| 500 "Please merge or rebase manually:\n" + | 502 "Please merge or rebase manually:\n" + |
| 501 "cd %s; git rebase %s\n" % (self.checkout_path, new_base) + | 503 "cd %s; git rebase %s\n" % (self.checkout_path, new_base) + |
| 502 "OR git checkout -b <some new branch> %s" % new_base) | 504 "OR git checkout -b <some new branch> %s" % new_base) |
| 503 raise gclient_utils.Error(switch_error) | 505 raise gclient_utils.Error(switch_error) |
| 504 else: | 506 else: |
| 505 # case 3 - the default case | 507 # case 3 - the default case |
| 506 if files is not None: | 508 if files is not None: |
| 507 files = self._Capture(['diff', upstream_branch, '--name-only']).split() | 509 files = self._Capture(['diff', upstream_branch, '--name-only']).split() |
| 508 if verbose: | 510 if verbose: |
| 509 print('Trying fast-forward merge to branch : %s' % upstream_branch) | 511 print('Trying fast-forward merge to branch : %s' % upstream_branch) |
| 510 try: | 512 try: |
| 511 merge_args = ['merge'] | 513 merge_args = ['merge'] |
| 512 if not options.merge: | 514 if options.merge: |
| 515 merge_args.append('--ff') |
| 516 else: |
| 513 merge_args.append('--ff-only') | 517 merge_args.append('--ff-only') |
| 514 merge_args.append(upstream_branch) | 518 merge_args.append(upstream_branch) |
| 515 merge_output = scm.GIT.Capture(merge_args, cwd=self.checkout_path) | 519 merge_output = scm.GIT.Capture(merge_args, cwd=self.checkout_path) |
| 516 except subprocess2.CalledProcessError as e: | 520 except subprocess2.CalledProcessError as e: |
| 517 if re.match('fatal: Not possible to fast-forward, aborting.', e.stderr): | 521 if re.match('fatal: Not possible to fast-forward, aborting.', e.stderr): |
| 522 files = [] |
| 518 if not printed_path: | 523 if not printed_path: |
| 519 print('\n_____ %s%s' % (self.relpath, rev_str)) | 524 print('\n_____ %s%s' % (self.relpath, rev_str)) |
| 520 printed_path = True | 525 printed_path = True |
| 521 while True: | 526 while True: |
| 522 try: | 527 try: |
| 523 action = ask_for_data( | 528 action = ask_for_data( |
| 524 'Cannot fast-forward merge, attempt to rebase? ' | 529 'Cannot %s, attempt to rebase? ' |
| 525 '(y)es / (q)uit / (s)kip : ', options) | 530 '(y)es / (q)uit / (s)kip : ' % |
| 531 ('merge' if options.merge else 'fast-forward merge'), |
| 532 options) |
| 526 except ValueError: | 533 except ValueError: |
| 527 raise gclient_utils.Error('Invalid Character') | 534 raise gclient_utils.Error('Invalid Character') |
| 528 if re.match(r'yes|y', action, re.I): | 535 if re.match(r'yes|y', action, re.I): |
| 529 self._AttemptRebase(upstream_branch, files, options, | 536 self._AttemptRebase(upstream_branch, files, options, |
| 530 printed_path=printed_path) | 537 printed_path=printed_path, merge=False) |
| 531 printed_path = True | 538 printed_path = True |
| 532 break | 539 break |
| 533 elif re.match(r'quit|q', action, re.I): | 540 elif re.match(r'quit|q', action, re.I): |
| 534 raise gclient_utils.Error("Can't fast-forward, please merge or " | 541 raise gclient_utils.Error("Can't fast-forward, please merge or " |
| 535 "rebase manually.\n" | 542 "rebase manually.\n" |
| 536 "cd %s && git " % self.checkout_path | 543 "cd %s && git " % self.checkout_path |
| 537 + "rebase %s" % upstream_branch) | 544 + "rebase %s" % upstream_branch) |
| 538 elif re.match(r'skip|s', action, re.I): | 545 elif re.match(r'skip|s', action, re.I): |
| 539 print('Skipping %s' % self.relpath) | 546 print('Skipping %s' % self.relpath) |
| 540 return | 547 return |
| (...skipping 336 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 877 else: | 884 else: |
| 878 # Squelch git's very verbose detached HEAD warning and use our own | 885 # Squelch git's very verbose detached HEAD warning and use our own |
| 879 self._Run(['checkout', '--quiet', revision], options) | 886 self._Run(['checkout', '--quiet', revision], options) |
| 880 print( | 887 print( |
| 881 ('Checked out %s to a detached HEAD. Before making any commits\n' | 888 ('Checked out %s to a detached HEAD. Before making any commits\n' |
| 882 'in this repo, you should use \'git checkout <branch>\' to switch to\n' | 889 'in this repo, you should use \'git checkout <branch>\' to switch to\n' |
| 883 'an existing branch or use \'git checkout %s -b <branch>\' to\n' | 890 'an existing branch or use \'git checkout %s -b <branch>\' to\n' |
| 884 'create a new branch for your work.') % (revision, self.remote)) | 891 'create a new branch for your work.') % (revision, self.remote)) |
| 885 | 892 |
| 886 def _AttemptRebase(self, upstream, files, options, newbase=None, | 893 def _AttemptRebase(self, upstream, files, options, newbase=None, |
| 887 branch=None, printed_path=False): | 894 branch=None, printed_path=False, merge=False): |
| 888 """Attempt to rebase onto either upstream or, if specified, newbase.""" | 895 """Attempt to rebase onto either upstream or, if specified, newbase.""" |
| 889 if files is not None: | 896 if files is not None: |
| 890 files.extend(self._Capture(['diff', upstream, '--name-only']).split()) | 897 files.extend(self._Capture(['diff', upstream, '--name-only']).split()) |
| 891 revision = upstream | 898 revision = upstream |
| 892 if newbase: | 899 if newbase: |
| 893 revision = newbase | 900 revision = newbase |
| 901 action = 'merge' if merge else 'rebase' |
| 894 if not printed_path: | 902 if not printed_path: |
| 895 print('\n_____ %s : Attempting rebase onto %s...' % ( | 903 print('\n_____ %s : Attempting %s onto %s...' % ( |
| 896 self.relpath, revision)) | 904 self.relpath, action, revision)) |
| 897 printed_path = True | 905 printed_path = True |
| 898 else: | 906 else: |
| 899 print('Attempting rebase onto %s...' % revision) | 907 print('Attempting %s onto %s...' % (action, revision)) |
| 908 |
| 909 if merge: |
| 910 merge_output = self._Capture(['merge', revision]) |
| 911 if options.verbose: |
| 912 print(merge_output) |
| 913 return |
| 900 | 914 |
| 901 # Build the rebase command here using the args | 915 # Build the rebase command here using the args |
| 902 # git rebase [options] [--onto <newbase>] <upstream> [<branch>] | 916 # git rebase [options] [--onto <newbase>] <upstream> [<branch>] |
| 903 rebase_cmd = ['rebase'] | 917 rebase_cmd = ['rebase'] |
| 904 if options.verbose: | 918 if options.verbose: |
| 905 rebase_cmd.append('--verbose') | 919 rebase_cmd.append('--verbose') |
| 906 if newbase: | 920 if newbase: |
| 907 rebase_cmd.extend(['--onto', newbase]) | 921 rebase_cmd.extend(['--onto', newbase]) |
| 908 rebase_cmd.append(upstream) | 922 rebase_cmd.append(upstream) |
| 909 if branch: | 923 if branch: |
| (...skipping 614 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1524 new_command.append('--force') | 1538 new_command.append('--force') |
| 1525 if command[0] != 'checkout' and scm.SVN.AssertVersion('1.6')[0]: | 1539 if command[0] != 'checkout' and scm.SVN.AssertVersion('1.6')[0]: |
| 1526 new_command.extend(('--accept', 'theirs-conflict')) | 1540 new_command.extend(('--accept', 'theirs-conflict')) |
| 1527 elif options.manually_grab_svn_rev: | 1541 elif options.manually_grab_svn_rev: |
| 1528 new_command.append('--force') | 1542 new_command.append('--force') |
| 1529 if command[0] != 'checkout' and scm.SVN.AssertVersion('1.6')[0]: | 1543 if command[0] != 'checkout' and scm.SVN.AssertVersion('1.6')[0]: |
| 1530 new_command.extend(('--accept', 'postpone')) | 1544 new_command.extend(('--accept', 'postpone')) |
| 1531 elif command[0] != 'checkout' and scm.SVN.AssertVersion('1.6')[0]: | 1545 elif command[0] != 'checkout' and scm.SVN.AssertVersion('1.6')[0]: |
| 1532 new_command.extend(('--accept', 'postpone')) | 1546 new_command.extend(('--accept', 'postpone')) |
| 1533 return new_command | 1547 return new_command |
| OLD | NEW |