OLD | NEW |
1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
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 | 5 |
6 """Client-side script to send a try job to the try server. It communicates to | 6 """Client-side script to send a try job to the try server. It communicates to |
7 the try server by either writting to a svn/git repository or by directly | 7 the try server by either writting to a svn/git repository or by directly |
8 connecting to the server by HTTP. | 8 connecting to the server by HTTP. |
9 """ | 9 """ |
10 | 10 |
(...skipping 593 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
604 if scm.GIT.IsWorkTreeDirty(patch_dir): | 604 if scm.GIT.IsWorkTreeDirty(patch_dir): |
605 logging.info('Work dir is dirty: hard reset!') | 605 logging.info('Work dir is dirty: hard reset!') |
606 scm.GIT.Capture(['reset', '--hard'], cwd=patch_dir) | 606 scm.GIT.Capture(['reset', '--hard'], cwd=patch_dir) |
607 logging.info('Updating patch repo') | 607 logging.info('Updating patch repo') |
608 scm.GIT.Capture(['pull', 'origin', 'master'], cwd=patch_dir) | 608 scm.GIT.Capture(['pull', 'origin', 'master'], cwd=patch_dir) |
609 | 609 |
610 return os.path.abspath(patch_dir) | 610 return os.path.abspath(patch_dir) |
611 | 611 |
612 | 612 |
613 def _SendChangeGit(bot_spec, options): | 613 def _SendChangeGit(bot_spec, options): |
614 """Send a change to the try server by committing a diff file to a GIT repo""" | 614 """Sends a change to the try server by committing a diff file to a GIT repo. |
| 615 |
| 616 Creates a temp orphan branch, commits patch.diff, creates a ref pointing to |
| 617 that commit, deletes the temp branch, checks master out, adds 'ref' file |
| 618 containing the name of the new ref, pushes master and the ref to the origin. |
| 619 |
| 620 TODO: instead of creating a temp branch, use git-commit-tree. |
| 621 """ |
| 622 |
615 if not options.git_repo: | 623 if not options.git_repo: |
616 raise NoTryServerAccess('Please use the --git_repo option to specify the ' | 624 raise NoTryServerAccess('Please use the --git_repo option to specify the ' |
617 'try server git repository to connect to.') | 625 'try server git repository to connect to.') |
618 | 626 |
619 values = _ParseSendChangeOptions(bot_spec, options) | 627 values = _ParseSendChangeOptions(bot_spec, options) |
620 comment_subject = '%s.%s' % (options.user, options.name) | 628 comment_subject = '%s.%s' % (options.user, options.name) |
621 comment_body = ''.join("%s=%s\n" % (k, v) for k, v in values) | 629 comment_body = ''.join("%s=%s\n" % (k, v) for k, v in values) |
622 description = '%s\n\n%s' % (comment_subject, comment_body) | 630 description = '%s\n\n%s' % (comment_subject, comment_body) |
623 logging.info('Sending by GIT') | 631 logging.info('Sending by GIT') |
624 logging.info(description) | 632 logging.info(description) |
625 logging.info(options.git_repo) | 633 logging.info(options.git_repo) |
626 logging.info(options.diff) | 634 logging.info(options.diff) |
627 if options.dry_run: | 635 if options.dry_run: |
628 return | 636 return |
629 | 637 |
630 patch_dir = _GetPatchGitRepo(options.git_repo) | 638 patch_dir = _GetPatchGitRepo(options.git_repo) |
631 def patch_git(*args): | 639 def patch_git(*args): |
632 return scm.GIT.Capture(list(args), cwd=patch_dir) | 640 return scm.GIT.Capture(list(args), cwd=patch_dir) |
633 def add_and_commit(filename, comment_filename): | 641 def add_and_commit(filename, comment_filename): |
634 patch_git('add', filename) | 642 patch_git('add', filename) |
635 patch_git('commit', '-F', comment_filename) | 643 patch_git('commit', '-F', comment_filename) |
636 | 644 |
637 assert scm.GIT.IsInsideWorkTree(patch_dir) | 645 assert scm.GIT.IsInsideWorkTree(patch_dir) |
638 assert not scm.GIT.IsWorkTreeDirty(patch_dir) | 646 assert not scm.GIT.IsWorkTreeDirty(patch_dir) |
639 | 647 |
640 with _PrepareDescriptionAndPatchFiles(description, options) as ( | 648 with _PrepareDescriptionAndPatchFiles(description, options) as ( |
641 patch_filename, description_filename): | 649 patch_filename, description_filename): |
642 logging.info('Committing patch') | 650 logging.info('Committing patch') |
643 target_branch = 'refs/patches/%s/%s' % ( | 651 |
| 652 temp_branch = 'tmp_patch' |
| 653 target_ref = 'refs/patches/%s/%s' % ( |
644 Escape(options.user), | 654 Escape(options.user), |
645 os.path.basename(patch_filename).replace(' ','_')) | 655 os.path.basename(patch_filename).replace(' ','_')) |
646 target_filename = os.path.join(patch_dir, 'patch.diff') | 656 target_filename = os.path.join(patch_dir, 'patch.diff') |
647 branch_file = os.path.join(patch_dir, GIT_BRANCH_FILE) | 657 branch_file = os.path.join(patch_dir, GIT_BRANCH_FILE) |
| 658 |
| 659 patch_git('checkout', 'master') |
648 try: | 660 try: |
| 661 # Try deleting an existing temp branch, if any. |
| 662 try: |
| 663 patch_git('branch', '-D', temp_branch) |
| 664 logging.debug('Deleted an existing temp branch.') |
| 665 except subprocess2.CalledProcessError: |
| 666 pass |
649 # Create a new branch and put the patch there. | 667 # Create a new branch and put the patch there. |
650 patch_git('checkout', '--orphan', target_branch) | 668 patch_git('checkout', '--orphan', temp_branch) |
651 patch_git('reset') | 669 patch_git('reset') |
652 patch_git('clean', '-f') | 670 patch_git('clean', '-f') |
653 shutil.copyfile(patch_filename, target_filename) | 671 shutil.copyfile(patch_filename, target_filename) |
654 add_and_commit(target_filename, description_filename) | 672 add_and_commit(target_filename, description_filename) |
655 assert not scm.GIT.IsWorkTreeDirty(patch_dir) | 673 assert not scm.GIT.IsWorkTreeDirty(patch_dir) |
656 | 674 |
657 # Update the branch file in the master | 675 # Create a ref and point it to the commit referenced by temp_branch. |
| 676 patch_git('update-ref', target_ref, temp_branch) |
| 677 |
| 678 # Delete the temp ref. |
658 patch_git('checkout', 'master') | 679 patch_git('checkout', 'master') |
| 680 patch_git('branch', '-D', temp_branch) |
659 | 681 |
| 682 # Update the branch file in the master. |
660 def update_branch(): | 683 def update_branch(): |
661 with open(branch_file, 'w') as f: | 684 with open(branch_file, 'w') as f: |
662 f.write(target_branch) | 685 f.write(target_ref) |
663 add_and_commit(branch_file, description_filename) | 686 add_and_commit(branch_file, description_filename) |
664 | 687 |
665 update_branch() | 688 update_branch() |
666 | 689 |
667 # Push master and target_branch to origin. | 690 # Push master and target_ref to origin. |
668 logging.info('Pushing patch') | 691 logging.info('Pushing patch') |
669 for attempt in xrange(_GIT_PUSH_ATTEMPTS): | 692 for attempt in xrange(_GIT_PUSH_ATTEMPTS): |
670 try: | 693 try: |
671 patch_git('push', 'origin', 'master', target_branch) | 694 patch_git('push', 'origin', 'master', target_ref) |
672 except subprocess2.CalledProcessError as e: | 695 except subprocess2.CalledProcessError as e: |
673 is_last = attempt == _GIT_PUSH_ATTEMPTS - 1 | 696 is_last = attempt == _GIT_PUSH_ATTEMPTS - 1 |
674 if is_last: | 697 if is_last: |
675 raise NoTryServerAccess(str(e)) | 698 raise NoTryServerAccess(str(e)) |
676 # Fetch, reset, update branch file again. | 699 # Fetch, reset, update branch file again. |
677 patch_git('fetch', 'origin') | 700 patch_git('fetch', 'origin') |
678 patch_git('reset', '--hard', 'origin/master') | 701 patch_git('reset', '--hard', 'origin/master') |
679 update_branch() | 702 update_branch() |
680 except subprocess2.CalledProcessError, e: | 703 except subprocess2.CalledProcessError, e: |
681 # Restore state. | 704 # Restore state. |
(...skipping 439 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1121 return 1 | 1144 return 1 |
1122 except (gclient_utils.Error, subprocess2.CalledProcessError), e: | 1145 except (gclient_utils.Error, subprocess2.CalledProcessError), e: |
1123 print >> sys.stderr, e | 1146 print >> sys.stderr, e |
1124 return 1 | 1147 return 1 |
1125 return 0 | 1148 return 0 |
1126 | 1149 |
1127 | 1150 |
1128 if __name__ == "__main__": | 1151 if __name__ == "__main__": |
1129 fix_encoding.fix_encoding() | 1152 fix_encoding.fix_encoding() |
1130 sys.exit(TryChange(None, None, False)) | 1153 sys.exit(TryChange(None, None, False)) |
OLD | NEW |