| 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 |