| 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 from __future__ import print_function | 7 from __future__ import print_function |
| 8 | 8 |
| 9 import errno | 9 import errno |
| 10 import logging | 10 import logging |
| (...skipping 351 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 362 rev_str = ' at %s' % revision | 362 rev_str = ' at %s' % revision |
| 363 files = [] if file_list is not None else None | 363 files = [] if file_list is not None else None |
| 364 | 364 |
| 365 printed_path = False | 365 printed_path = False |
| 366 verbose = [] | 366 verbose = [] |
| 367 if options.verbose: | 367 if options.verbose: |
| 368 self.Print('_____ %s%s' % (self.relpath, rev_str), timestamp=False) | 368 self.Print('_____ %s%s' % (self.relpath, rev_str), timestamp=False) |
| 369 verbose = ['--verbose'] | 369 verbose = ['--verbose'] |
| 370 printed_path = True | 370 printed_path = True |
| 371 | 371 |
| 372 if revision.startswith('refs/'): | 372 remote_ref = scm.GIT.RefToRemoteRef(revision, self.remote) |
| 373 if remote_ref: |
| 374 # Rewrite remote refs to their local equivalents. |
| 375 revision = ''.join(remote_ref) |
| 373 rev_type = "branch" | 376 rev_type = "branch" |
| 374 elif revision.startswith(self.remote + '/'): | 377 elif revision.startswith('refs/'): |
| 375 # Rewrite remote refs to their local equivalents. | 378 # Local branch? We probably don't want to support, since DEPS should |
| 376 revision = 'refs/remotes/' + revision | 379 # always specify branches as they are in the upstream repo. |
| 377 rev_type = "branch" | 380 rev_type = "branch" |
| 378 else: | 381 else: |
| 379 # hash is also a tag, only make a distinction at checkout | 382 # hash is also a tag, only make a distinction at checkout |
| 380 rev_type = "hash" | 383 rev_type = "hash" |
| 381 | 384 |
| 382 mirror = self._GetMirror(url, options) | 385 mirror = self._GetMirror(url, options) |
| 383 if mirror: | 386 if mirror: |
| 384 url = mirror.mirror_path | 387 url = mirror.mirror_path |
| 385 | 388 |
| 386 if (not os.path.exists(self.checkout_path) or | 389 if (not os.path.exists(self.checkout_path) or |
| 387 (os.path.isdir(self.checkout_path) and | 390 (os.path.isdir(self.checkout_path) and |
| 388 not os.path.exists(os.path.join(self.checkout_path, '.git')))): | 391 not os.path.exists(os.path.join(self.checkout_path, '.git')))): |
| 389 if mirror: | 392 if mirror: |
| 390 self._UpdateMirror(mirror, options) | 393 self._UpdateMirror(mirror, options) |
| 391 try: | 394 try: |
| 392 self._Clone(revision, url, options) | 395 self._Clone(revision, url, options) |
| 393 except subprocess2.CalledProcessError: | 396 except subprocess2.CalledProcessError: |
| 394 self._DeleteOrMove(options.force) | 397 self._DeleteOrMove(options.force) |
| 395 self._Clone(revision, url, options) | 398 self._Clone(revision, url, options) |
| 396 if deps_revision and deps_revision.startswith('branch-heads/'): | |
| 397 deps_branch = deps_revision.replace('branch-heads/', '') | |
| 398 self._Capture(['branch', deps_branch, deps_revision]) | |
| 399 self._Checkout(options, deps_branch, quiet=True) | |
| 400 if file_list is not None: | 399 if file_list is not None: |
| 401 files = self._Capture(['ls-files']).splitlines() | 400 files = self._Capture(['ls-files']).splitlines() |
| 402 file_list.extend([os.path.join(self.checkout_path, f) for f in files]) | 401 file_list.extend([os.path.join(self.checkout_path, f) for f in files]) |
| 403 if not verbose: | 402 if not verbose: |
| 404 # Make the output a little prettier. It's nice to have some whitespace | 403 # Make the output a little prettier. It's nice to have some whitespace |
| 405 # between projects when cloning. | 404 # between projects when cloning. |
| 406 self.Print('') | 405 self.Print('') |
| 407 return self._Capture(['rev-parse', '--verify', 'HEAD']) | 406 return self._Capture(['rev-parse', '--verify', 'HEAD']) |
| 408 | 407 |
| 409 if not managed: | 408 if not managed: |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 444 | 443 |
| 445 # Cases: | 444 # Cases: |
| 446 # 0) HEAD is detached. Probably from our initial clone. | 445 # 0) HEAD is detached. Probably from our initial clone. |
| 447 # - make sure HEAD is contained by a named ref, then update. | 446 # - make sure HEAD is contained by a named ref, then update. |
| 448 # Cases 1-4. HEAD is a branch. | 447 # Cases 1-4. HEAD is a branch. |
| 449 # 1) current branch is not tracking a remote branch (could be git-svn) | 448 # 1) current branch is not tracking a remote branch (could be git-svn) |
| 450 # - try to rebase onto the new hash or branch | 449 # - try to rebase onto the new hash or branch |
| 451 # 2) current branch is tracking a remote branch with local committed | 450 # 2) current branch is tracking a remote branch with local committed |
| 452 # changes, but the DEPS file switched to point to a hash | 451 # changes, but the DEPS file switched to point to a hash |
| 453 # - rebase those changes on top of the hash | 452 # - rebase those changes on top of the hash |
| 454 # 3) current branch is tracking a remote branch w/or w/out changes, | 453 # 3) current branch is tracking a remote branch w/or w/out changes, and |
| 455 # no switch | 454 # no DEPS switch |
| 456 # - see if we can FF, if not, prompt the user for rebase, merge, or stop | 455 # - see if we can FF, if not, prompt the user for rebase, merge, or stop |
| 457 # 4) current branch is tracking a remote branch, switches to a different | 456 # 4) current branch is tracking a remote branch, but DEPS switches to a |
| 458 # remote branch | 457 # different remote branch, and |
| 459 # - exit | 458 # a) current branch has no local changes, and --force: |
| 459 # - checkout new branch |
| 460 # b) current branch has local changes, and --force and --reset: |
| 461 # - checkout new branch |
| 462 # c) otherwise exit |
| 460 | 463 |
| 461 # GetUpstreamBranch returns something like 'refs/remotes/origin/master' for | 464 # GetUpstreamBranch returns something like 'refs/remotes/origin/master' for |
| 462 # a tracking branch | 465 # a tracking branch |
| 463 # or 'master' if not a tracking branch (it's based on a specific rev/hash) | 466 # or 'master' if not a tracking branch (it's based on a specific rev/hash) |
| 464 # or it returns None if it couldn't find an upstream | 467 # or it returns None if it couldn't find an upstream |
| 465 if cur_branch is None: | 468 if cur_branch is None: |
| 466 upstream_branch = None | 469 upstream_branch = None |
| 467 current_type = "detached" | 470 current_type = "detached" |
| 468 logging.debug("Detached HEAD") | 471 logging.debug("Detached HEAD") |
| 469 else: | 472 else: |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 527 upstream_branch = revision | 530 upstream_branch = revision |
| 528 self._AttemptRebase(upstream_branch, files, options, | 531 self._AttemptRebase(upstream_branch, files, options, |
| 529 printed_path=printed_path, merge=options.merge) | 532 printed_path=printed_path, merge=options.merge) |
| 530 printed_path = True | 533 printed_path = True |
| 531 elif rev_type == 'hash': | 534 elif rev_type == 'hash': |
| 532 # case 2 | 535 # case 2 |
| 533 self._AttemptRebase(upstream_branch, files, options, | 536 self._AttemptRebase(upstream_branch, files, options, |
| 534 newbase=revision, printed_path=printed_path, | 537 newbase=revision, printed_path=printed_path, |
| 535 merge=options.merge) | 538 merge=options.merge) |
| 536 printed_path = True | 539 printed_path = True |
| 537 elif revision.replace('heads', 'remotes/' + self.remote) != upstream_branch: | 540 elif remote_ref and ''.join(remote_ref) != upstream_branch: |
| 538 # case 4 | 541 # case 4 |
| 539 new_base = revision.replace('heads', 'remotes/' + self.remote) | 542 new_base = ''.join(remote_ref) |
| 540 if not printed_path: | 543 if not printed_path: |
| 541 self.Print('_____ %s%s' % (self.relpath, rev_str), timestamp=False) | 544 self.Print('_____ %s%s' % (self.relpath, rev_str), timestamp=False) |
| 542 switch_error = ("Switching upstream branch from %s to %s\n" | 545 switch_error = ("Could not switch upstream branch from %s to %s\n" |
| 543 % (upstream_branch, new_base) + | 546 % (upstream_branch, new_base) + |
| 544 "Please merge or rebase manually:\n" + | 547 "Please use --force or merge or rebase manually:\n" + |
| 545 "cd %s; git rebase %s\n" % (self.checkout_path, new_base) + | 548 "cd %s; git rebase %s\n" % (self.checkout_path, new_base) + |
| 546 "OR git checkout -b <some new branch> %s" % new_base) | 549 "OR git checkout -b <some new branch> %s" % new_base) |
| 547 raise gclient_utils.Error(switch_error) | 550 force_switch = False |
| 551 if options.force: |
| 552 try: |
| 553 self._CheckClean(rev_str) |
| 554 # case 4a |
| 555 force_switch = True |
| 556 except gclient_utils.Error as e: |
| 557 if options.reset: |
| 558 # case 4b |
| 559 force_switch = True |
| 560 else: |
| 561 switch_error = '%s\n%s' % (e.message, switch_error) |
| 562 if force_switch: |
| 563 self.Print("Switching upstream branch from %s to %s" % |
| 564 (upstream_branch, new_base)) |
| 565 switch_branch = 'gclient_' + remote_ref[1] |
| 566 self._Capture(['branch', '-f', switch_branch, new_base]) |
| 567 self._Checkout(options, switch_branch, force=True, quiet=True) |
| 568 else: |
| 569 # case 4c |
| 570 raise gclient_utils.Error(switch_error) |
| 548 else: | 571 else: |
| 549 # case 3 - the default case | 572 # case 3 - the default case |
| 550 if files is not None: | 573 if files is not None: |
| 551 files = self._Capture(['diff', upstream_branch, '--name-only']).split() | 574 files = self._Capture(['diff', upstream_branch, '--name-only']).split() |
| 552 if verbose: | 575 if verbose: |
| 553 self.Print('Trying fast-forward merge to branch : %s' % upstream_branch) | 576 self.Print('Trying fast-forward merge to branch : %s' % upstream_branch) |
| 554 try: | 577 try: |
| 555 merge_args = ['merge'] | 578 merge_args = ['merge'] |
| 556 if options.merge: | 579 if options.merge: |
| 557 merge_args.append('--ff') | 580 merge_args.append('--ff') |
| (...skipping 305 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 863 except: | 886 except: |
| 864 traceback.print_exc(file=self.out_fh) | 887 traceback.print_exc(file=self.out_fh) |
| 865 raise | 888 raise |
| 866 finally: | 889 finally: |
| 867 if os.listdir(tmp_dir): | 890 if os.listdir(tmp_dir): |
| 868 self.Print('_____ removing non-empty tmp dir %s' % tmp_dir) | 891 self.Print('_____ removing non-empty tmp dir %s' % tmp_dir) |
| 869 gclient_utils.rmtree(tmp_dir) | 892 gclient_utils.rmtree(tmp_dir) |
| 870 if template_dir: | 893 if template_dir: |
| 871 gclient_utils.rmtree(template_dir) | 894 gclient_utils.rmtree(template_dir) |
| 872 self._UpdateBranchHeads(options, fetch=True) | 895 self._UpdateBranchHeads(options, fetch=True) |
| 873 self._Checkout(options, revision.replace('refs/heads/', ''), quiet=True) | 896 remote_ref = scm.GIT.RefToRemoteRef(revision, self.remote) |
| 897 self._Checkout(options, ''.join(remote_ref or revision), quiet=True) |
| 874 if self._GetCurrentBranch() is None: | 898 if self._GetCurrentBranch() is None: |
| 875 # Squelch git's very verbose detached HEAD warning and use our own | 899 # Squelch git's very verbose detached HEAD warning and use our own |
| 876 self.Print( | 900 self.Print( |
| 877 ('Checked out %s to a detached HEAD. Before making any commits\n' | 901 ('Checked out %s to a detached HEAD. Before making any commits\n' |
| 878 'in this repo, you should use \'git checkout <branch>\' to switch to\n' | 902 'in this repo, you should use \'git checkout <branch>\' to switch to\n' |
| 879 'an existing branch or use \'git checkout %s -b <branch>\' to\n' | 903 'an existing branch or use \'git checkout %s -b <branch>\' to\n' |
| 880 'create a new branch for your work.') % (revision, self.remote)) | 904 'create a new branch for your work.') % (revision, self.remote)) |
| 881 | 905 |
| 882 def _AskForData(self, prompt, options): | 906 def _AskForData(self, prompt, options): |
| 883 if options.jobs > 1: | 907 if options.jobs > 1: |
| (...skipping 692 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1576 new_command.append('--force') | 1600 new_command.append('--force') |
| 1577 if command[0] != 'checkout' and scm.SVN.AssertVersion('1.6')[0]: | 1601 if command[0] != 'checkout' and scm.SVN.AssertVersion('1.6')[0]: |
| 1578 new_command.extend(('--accept', 'theirs-conflict')) | 1602 new_command.extend(('--accept', 'theirs-conflict')) |
| 1579 elif options.manually_grab_svn_rev: | 1603 elif options.manually_grab_svn_rev: |
| 1580 new_command.append('--force') | 1604 new_command.append('--force') |
| 1581 if command[0] != 'checkout' and scm.SVN.AssertVersion('1.6')[0]: | 1605 if command[0] != 'checkout' and scm.SVN.AssertVersion('1.6')[0]: |
| 1582 new_command.extend(('--accept', 'postpone')) | 1606 new_command.extend(('--accept', 'postpone')) |
| 1583 elif command[0] != 'checkout' and scm.SVN.AssertVersion('1.6')[0]: | 1607 elif command[0] != 'checkout' and scm.SVN.AssertVersion('1.6')[0]: |
| 1584 new_command.extend(('--accept', 'postpone')) | 1608 new_command.extend(('--accept', 'postpone')) |
| 1585 return new_command | 1609 return new_command |
| OLD | NEW |