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 # Copyright (C) 2008 Evan Martin <martine@danga.com> | 6 # Copyright (C) 2008 Evan Martin <martine@danga.com> |
7 | 7 |
8 """A git-command for integrating reviews on Rietveld.""" | 8 """A git-command for integrating reviews on Rietveld.""" |
9 | 9 |
10 import difflib | 10 import difflib |
| 11 from distutils.version import LooseVersion |
11 import json | 12 import json |
12 import logging | 13 import logging |
13 import optparse | 14 import optparse |
14 import os | 15 import os |
15 import re | 16 import re |
16 import stat | 17 import stat |
17 import sys | 18 import sys |
18 import textwrap | 19 import textwrap |
19 import urllib2 | 20 import urllib2 |
20 import urlparse | 21 import urlparse |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
81 out, code = subprocess2.communicate(['git'] + args, | 82 out, code = subprocess2.communicate(['git'] + args, |
82 env=env, | 83 env=env, |
83 stdout=subprocess2.PIPE) | 84 stdout=subprocess2.PIPE) |
84 return code, out[0] | 85 return code, out[0] |
85 except ValueError: | 86 except ValueError: |
86 # When the subprocess fails, it returns None. That triggers a ValueError | 87 # When the subprocess fails, it returns None. That triggers a ValueError |
87 # when trying to unpack the return value into (out, code). | 88 # when trying to unpack the return value into (out, code). |
88 return 1, '' | 89 return 1, '' |
89 | 90 |
90 | 91 |
| 92 def IsGitVersionAtLeast(min_version): |
| 93 PREFIX='git version ' |
| 94 version = RunGit(['--version']).strip() |
| 95 return (version.startswith(PREFIX) and |
| 96 LooseVersion(version[len(PREFIX):]) >= LooseVersion(min_version)) |
| 97 |
| 98 |
91 def usage(more): | 99 def usage(more): |
92 def hook(fn): | 100 def hook(fn): |
93 fn.usage_more = more | 101 fn.usage_more = more |
94 return fn | 102 return fn |
95 return hook | 103 return hook |
96 | 104 |
97 | 105 |
98 def ask_for_data(prompt): | 106 def ask_for_data(prompt): |
99 try: | 107 try: |
100 return raw_input(prompt) | 108 return raw_input(prompt) |
(...skipping 1606 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1707 | 1715 |
1708 | 1716 |
1709 @usage('<patch url or issue id>') | 1717 @usage('<patch url or issue id>') |
1710 def CMDpatch(parser, args): | 1718 def CMDpatch(parser, args): |
1711 """patch in a code review""" | 1719 """patch in a code review""" |
1712 parser.add_option('-b', dest='newbranch', | 1720 parser.add_option('-b', dest='newbranch', |
1713 help='create a new branch off trunk for the patch') | 1721 help='create a new branch off trunk for the patch') |
1714 parser.add_option('-f', action='store_true', dest='force', | 1722 parser.add_option('-f', action='store_true', dest='force', |
1715 help='with -b, clobber any existing branch') | 1723 help='with -b, clobber any existing branch') |
1716 parser.add_option('--reject', action='store_true', dest='reject', | 1724 parser.add_option('--reject', action='store_true', dest='reject', |
1717 help='allow failed patches and spew .rej files') | 1725 help='failed patches spew .rej files rather than ' |
| 1726 'attempting a 3-way merge') |
1718 parser.add_option('-n', '--no-commit', action='store_true', dest='nocommit', | 1727 parser.add_option('-n', '--no-commit', action='store_true', dest='nocommit', |
1719 help="don't commit after patch applies") | 1728 help="don't commit after patch applies") |
1720 (options, args) = parser.parse_args(args) | 1729 (options, args) = parser.parse_args(args) |
1721 if len(args) != 1: | 1730 if len(args) != 1: |
1722 parser.print_help() | 1731 parser.print_help() |
1723 return 1 | 1732 return 1 |
1724 issue_arg = args[0] | 1733 issue_arg = args[0] |
1725 | 1734 |
1726 # TODO(maruel): Use apply_issue.py | 1735 # TODO(maruel): Use apply_issue.py |
1727 # TODO(ukai): use gerrit-cherry-pick for gerrit repository? | 1736 # TODO(ukai): use gerrit-cherry-pick for gerrit repository? |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1769 env = os.environ.copy() | 1778 env = os.environ.copy() |
1770 # 'cat' is a magical git string that disables pagers on all platforms. | 1779 # 'cat' is a magical git string that disables pagers on all platforms. |
1771 env['GIT_PAGER'] = 'cat' | 1780 env['GIT_PAGER'] = 'cat' |
1772 | 1781 |
1773 # We use "git apply" to apply the patch instead of "patch" so that we can | 1782 # We use "git apply" to apply the patch instead of "patch" so that we can |
1774 # pick up file adds. | 1783 # pick up file adds. |
1775 # The --index flag means: also insert into the index (so we catch adds). | 1784 # The --index flag means: also insert into the index (so we catch adds). |
1776 cmd = ['git', 'apply', '--index', '-p0'] | 1785 cmd = ['git', 'apply', '--index', '-p0'] |
1777 if options.reject: | 1786 if options.reject: |
1778 cmd.append('--reject') | 1787 cmd.append('--reject') |
| 1788 elif IsGitVersionAtLeast('1.7.12'): |
| 1789 cmd.append('--3way') |
1779 try: | 1790 try: |
1780 subprocess2.check_call(cmd, env=env, | 1791 subprocess2.check_call(cmd, env=env, |
1781 stdin=patch_data, stdout=subprocess2.VOID) | 1792 stdin=patch_data, stdout=subprocess2.VOID) |
1782 except subprocess2.CalledProcessError: | 1793 except subprocess2.CalledProcessError: |
1783 DieWithError('Failed to apply the patch') | 1794 DieWithError('Failed to apply the patch') |
1784 | 1795 |
1785 # If we had an issue, commit the current state and register the issue. | 1796 # If we had an issue, commit the current state and register the issue. |
1786 if not options.nocommit: | 1797 if not options.nocommit: |
1787 RunGit(['commit', '-m', 'patch from issue %s' % issue]) | 1798 RunGit(['commit', '-m', 'patch from issue %s' % issue]) |
1788 cl = Changelist() | 1799 cl = Changelist() |
(...skipping 377 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2166 GenUsage(parser, 'help') | 2177 GenUsage(parser, 'help') |
2167 return CMDhelp(parser, argv) | 2178 return CMDhelp(parser, argv) |
2168 | 2179 |
2169 | 2180 |
2170 if __name__ == '__main__': | 2181 if __name__ == '__main__': |
2171 # These affect sys.stdout so do it outside of main() to simplify mocks in | 2182 # These affect sys.stdout so do it outside of main() to simplify mocks in |
2172 # unit testing. | 2183 # unit testing. |
2173 fix_encoding.fix_encoding() | 2184 fix_encoding.fix_encoding() |
2174 colorama.init() | 2185 colorama.init() |
2175 sys.exit(main(sys.argv[1:])) | 2186 sys.exit(main(sys.argv[1:])) |
OLD | NEW |