OLD | NEW |
1 # coding=utf8 | 1 # coding=utf8 |
2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | 2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. |
3 # Use of this source code is governed by a BSD-style license that can be | 3 # Use of this source code is governed by a BSD-style license that can be |
4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
5 """Manages a project checkout. | 5 """Manages a project checkout. |
6 | 6 |
7 Includes support for svn, git-svn and git. | 7 Includes support for svn, git-svn and git. |
8 """ | 8 """ |
9 | 9 |
10 import ConfigParser | 10 import ConfigParser |
(...skipping 536 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
547 except subprocess.CalledProcessError: | 547 except subprocess.CalledProcessError: |
548 return None | 548 return None |
549 # Ignore the '----' lines. | 549 # Ignore the '----' lines. |
550 return len([l for l in out.splitlines() if l.startswith('r')]) - 1 | 550 return len([l for l in out.splitlines() if l.startswith('r')]) - 1 |
551 | 551 |
552 | 552 |
553 class GitCheckout(CheckoutBase): | 553 class GitCheckout(CheckoutBase): |
554 """Manages a git checkout.""" | 554 """Manages a git checkout.""" |
555 def __init__(self, root_dir, project_name, remote_branch, git_url, | 555 def __init__(self, root_dir, project_name, remote_branch, git_url, |
556 commit_user, post_processors=None): | 556 commit_user, post_processors=None): |
557 assert git_url | |
558 assert commit_user | |
559 super(GitCheckout, self).__init__(root_dir, project_name, post_processors) | 557 super(GitCheckout, self).__init__(root_dir, project_name, post_processors) |
560 self.git_url = git_url | 558 self.git_url = git_url |
561 self.commit_user = commit_user | 559 self.commit_user = commit_user |
562 self.remote_branch = remote_branch | 560 self.remote_branch = remote_branch |
563 # The working branch where patches will be applied. It will track the | 561 # The working branch where patches will be applied. It will track the |
564 # remote branch. | 562 # remote branch. |
565 self.working_branch = 'working_branch' | 563 self.working_branch = 'working_branch' |
566 # There is no reason to not hardcode origin. | 564 # There is no reason to not hardcode origin. |
567 self.remote = 'origin' | 565 self.remote = 'origin' |
| 566 # There is no reason to not hardcode master. |
| 567 self.master_branch = 'master' |
568 | 568 |
569 def prepare(self, revision): | 569 def prepare(self, revision): |
570 """Resets the git repository in a clean state. | 570 """Resets the git repository in a clean state. |
571 | 571 |
572 Checks it out if not present and deletes the working branch. | 572 Checks it out if not present and deletes the working branch. |
573 """ | 573 """ |
574 assert self.remote_branch | 574 assert self.remote_branch |
| 575 assert self.git_url |
575 | 576 |
576 if not os.path.isdir(self.project_path): | 577 if not os.path.isdir(self.project_path): |
577 # Clone the repo if the directory is not present. | 578 # Clone the repo if the directory is not present. |
578 logging.info( | 579 logging.info( |
579 'Checking out %s in %s', self.project_name, self.project_path) | 580 'Checking out %s in %s', self.project_name, self.project_path) |
580 self._check_call_git( | 581 self._check_call_git( |
581 ['clone', self.git_url, '-b', self.remote_branch, self.project_path], | 582 ['clone', self.git_url, '-b', self.remote_branch, self.project_path], |
582 cwd=None, timeout=FETCH_TIMEOUT) | 583 cwd=None, timeout=FETCH_TIMEOUT) |
583 else: | 584 else: |
584 # Throw away all uncommitted changes in the existing checkout. | 585 # Throw away all uncommitted changes in the existing checkout. |
585 self._check_call_git(['checkout', self.remote_branch]) | 586 self._check_call_git(['checkout', self.remote_branch]) |
586 self._check_call_git( | 587 self._check_call_git( |
587 ['reset', '--hard', '--quiet', | 588 ['reset', '--hard', '--quiet', |
588 '%s/%s' % (self.remote, self.remote_branch)]) | 589 '%s/%s' % (self.remote, self.remote_branch)]) |
589 | 590 |
590 if revision: | 591 if revision: |
591 try: | 592 try: |
592 # Look if the commit hash already exist. If so, we can skip a | 593 # Look if the commit hash already exist. If so, we can skip a |
593 # 'git fetch' call. | 594 # 'git fetch' call. |
594 revision = self._check_output_git(['rev-parse', revision]) | 595 revision = self._check_output_git(['rev-parse', revision]) |
595 except subprocess.CalledProcessError: | 596 except subprocess.CalledProcessError: |
596 self._check_call_git( | 597 self._check_call_git( |
597 ['fetch', self.remote, self.remote_branch, '--quiet']) | 598 ['fetch', self.remote, self.remote_branch, '--quiet']) |
598 revision = self._check_output_git(['rev-parse', revision]) | 599 revision = self._check_output_git(['rev-parse', revision]) |
599 self._check_call_git(['checkout', '--force', '--quiet', revision]) | 600 self._check_call_git(['checkout', '--force', '--quiet', revision]) |
600 else: | 601 else: |
601 branches, active = self._branches() | 602 branches, active = self._branches() |
602 if active != 'master': | 603 if active != self.master_branch: |
603 self._check_call_git(['checkout', '--force', '--quiet', 'master']) | 604 self._check_call_git( |
| 605 ['checkout', '--force', '--quiet', self.master_branch]) |
604 self._sync_remote_branch() | 606 self._sync_remote_branch() |
605 | 607 |
606 if self.working_branch in branches: | 608 if self.working_branch in branches: |
607 self._call_git(['branch', '-D', self.working_branch]) | 609 self._call_git(['branch', '-D', self.working_branch]) |
608 return self._get_head_commit_hash() | 610 return self._get_head_commit_hash() |
609 | 611 |
610 def _sync_remote_branch(self): | 612 def _sync_remote_branch(self): |
611 """Syncs the remote branch.""" | 613 """Syncs the remote branch.""" |
612 # We do a 'git pull origin master:refs/remotes/origin/master' instead of | 614 # We do a 'git pull origin master:refs/remotes/origin/master' instead of |
613 # 'git pull origin master' because from the manpage for git-pull: | 615 # 'git pull origin master' because from the manpage for git-pull: |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
702 ' '.join(e.cmd), | 704 ' '.join(e.cmd), |
703 align_stdout(stdout), | 705 align_stdout(stdout), |
704 align_stdout([getattr(e, 'stdout', '')]))) | 706 align_stdout([getattr(e, 'stdout', '')]))) |
705 # Once all the patches are processed and added to the index, commit the | 707 # Once all the patches are processed and added to the index, commit the |
706 # index. | 708 # index. |
707 cmd = ['commit', '-m', 'Committed patch'] | 709 cmd = ['commit', '-m', 'Committed patch'] |
708 if verbose: | 710 if verbose: |
709 cmd.append('--verbose') | 711 cmd.append('--verbose') |
710 self._check_call_git(cmd) | 712 self._check_call_git(cmd) |
711 found_files = self._check_output_git( | 713 found_files = self._check_output_git( |
712 ['diff', '%s/%s' % (self.remote, self.remote_branch), | 714 ['diff', '%s/%s' % (self.remote, |
| 715 self.remote_branch or self.master_branch), |
713 '--name-only']).splitlines(False) | 716 '--name-only']).splitlines(False) |
714 assert sorted(patches.filenames) == sorted(found_files), ( | 717 assert sorted(patches.filenames) == sorted(found_files), ( |
715 sorted(patches.filenames), sorted(found_files)) | 718 sorted(patches.filenames), sorted(found_files)) |
716 | 719 |
717 def commit(self, commit_message, user): | 720 def commit(self, commit_message, user): |
718 """Commits, updates the commit message and pushes.""" | 721 """Commits, updates the commit message and pushes.""" |
| 722 assert self.commit_user |
719 assert isinstance(commit_message, unicode) | 723 assert isinstance(commit_message, unicode) |
720 current_branch = self._check_output_git( | 724 current_branch = self._check_output_git( |
721 ['rev-parse', '--abbrev-ref', 'HEAD']).strip() | 725 ['rev-parse', '--abbrev-ref', 'HEAD']).strip() |
722 assert current_branch == self.working_branch | 726 assert current_branch == self.working_branch |
723 | 727 |
724 commit_cmd = ['commit', '--amend', '-m', commit_message] | 728 commit_cmd = ['commit', '--amend', '-m', commit_message] |
725 if user and user != self.commit_user: | 729 if user and user != self.commit_user: |
726 # We do not have the first or last name of the user, grab the username | 730 # We do not have the first or last name of the user, grab the username |
727 # from the email and call it the original author's name. | 731 # from the email and call it the original author's name. |
728 # TODO(rmistry): Do not need the below if user is already in | 732 # TODO(rmistry): Do not need the below if user is already in |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
821 def revisions(self, rev1, rev2): | 825 def revisions(self, rev1, rev2): |
822 return self.checkout.revisions(rev1, rev2) | 826 return self.checkout.revisions(rev1, rev2) |
823 | 827 |
824 @property | 828 @property |
825 def project_name(self): | 829 def project_name(self): |
826 return self.checkout.project_name | 830 return self.checkout.project_name |
827 | 831 |
828 @property | 832 @property |
829 def project_path(self): | 833 def project_path(self): |
830 return self.checkout.project_path | 834 return self.checkout.project_path |
OLD | NEW |