Chromium Code Reviews| 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 from distutils.version import LooseVersion | 10 from distutils.version import LooseVersion |
| (...skipping 2070 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2081 """Fetches pending_ref, cherry-picks current HEAD on top of it, pushes. | 2081 """Fetches pending_ref, cherry-picks current HEAD on top of it, pushes. |
| 2082 | 2082 |
| 2083 Returns: | 2083 Returns: |
| 2084 (retcode of last operation, output log of last operation). | 2084 (retcode of last operation, output log of last operation). |
| 2085 """ | 2085 """ |
| 2086 assert pending_ref.startswith('refs/'), pending_ref | 2086 assert pending_ref.startswith('refs/'), pending_ref |
| 2087 local_pending_ref = 'refs/git-cl/' + pending_ref[len('refs/'):] | 2087 local_pending_ref = 'refs/git-cl/' + pending_ref[len('refs/'):] |
| 2088 cherry = RunGit(['rev-parse', 'HEAD']).strip() | 2088 cherry = RunGit(['rev-parse', 'HEAD']).strip() |
| 2089 code = 0 | 2089 code = 0 |
| 2090 out = '' | 2090 out = '' |
| 2091 attempt = 0 | 2091 max_attempts = 3 |
| 2092 while attempt < 5: | 2092 attempts_left = max_attempts |
| 2093 attempt += 1 | 2093 while attempts_left: |
| 2094 if attempts_left != max_attempts: | |
| 2095 print 'Retrying, %d attempts left...' % (attempts_left - 1,) | |
| 2096 attempts_left -= 1 | |
| 2094 | 2097 |
| 2095 # Fetch. Retry fetch errors. | 2098 # Fetch. Retry fetch errors. |
| 2099 print 'Fetching pending ref %s...' % pending_ref | |
| 2096 code, out = RunGitWithCode( | 2100 code, out = RunGitWithCode( |
| 2097 ['retry', 'fetch', remote, '+%s:%s' % (pending_ref, local_pending_ref)], | 2101 ['retry', 'fetch', remote, '+%s:%s' % (pending_ref, local_pending_ref)]) |
| 2098 suppress_stderr=True) | |
| 2099 if code: | 2102 if code: |
| 2103 print 'Fetch failed with exit code %d.' % code | |
| 2104 if out.strip(): | |
| 2105 print out.strip() | |
| 2100 continue | 2106 continue |
| 2101 | 2107 |
| 2102 # Try to cherry pick. Abort on merge conflicts. | 2108 # Try to cherry pick. Abort on merge conflicts. |
| 2109 print 'Cherry-picking commit on top of pending ref...' | |
| 2103 RunGitWithCode(['checkout', local_pending_ref], suppress_stderr=True) | 2110 RunGitWithCode(['checkout', local_pending_ref], suppress_stderr=True) |
| 2104 code, out = RunGitWithCode(['cherry-pick', cherry], suppress_stderr=True) | 2111 code, out = RunGitWithCode(['cherry-pick', cherry]) |
| 2105 if code: | 2112 if code: |
| 2106 print ( | 2113 print ( |
| 2107 'Your patch doesn\'t apply cleanly to upstream ref \'%s\', ' | 2114 'Your patch doesn\'t apply cleanly to ref \'%s\', ' |
| 2108 'the following files have merge conflicts:' % upstream_ref) | 2115 'the following files have merge conflicts:' % pending_ref) |
| 2109 print RunGit(['diff', '--name-status', '--diff-filter=U']).strip() | 2116 print RunGit(['diff', '--name-status', '--diff-filter=U']).strip() |
| 2110 print 'Please rebase your patch and try again.' | 2117 print 'Please rebase your patch and try again.' |
| 2111 RunGitWithCode(['cherry-pick', '--abort'], suppress_stderr=True) | 2118 RunGitWithCode(['cherry-pick', '--abort']) |
| 2112 return code, out | 2119 return code, out |
| 2113 | 2120 |
| 2114 # Applied cleanly, try to push now. Retry on error (flake or non-ff push). | 2121 # Applied cleanly, try to push now. Retry on error (flake or non-ff push). |
| 2122 print 'Pushing commit to %s... It can take a while.' % pending_ref | |
| 2115 code, out = RunGitWithCode( | 2123 code, out = RunGitWithCode( |
| 2116 ['retry', 'push', '--porcelain', remote, 'HEAD:%s' % pending_ref]) | 2124 ['retry', 'push', '--porcelain', remote, 'HEAD:%s' % pending_ref]) |
| 2117 if code == 0: | 2125 if code == 0: |
| 2118 # Success. | 2126 # Success. |
| 2119 return code, out | 2127 return code, out |
| 2120 | 2128 |
| 2129 print 'Push failed with exit code %d.' % code | |
| 2130 if out.strip(): | |
| 2131 print out.strip() | |
|
Vadim Sh.
2014/08/26 21:12:05
that was the most crucial missing part, for whatev
| |
| 2132 if IsFatalPushFailure(out): | |
| 2133 print ( | |
| 2134 'Fatal push error. Make sure your .netrc credentials and git ' | |
| 2135 'user.email are correct and you have push access to the repo.') | |
| 2136 return code, out | |
| 2137 | |
| 2138 print 'All attempts to push to pending ref failed.' | |
| 2121 return code, out | 2139 return code, out |
| 2122 | 2140 |
| 2123 | 2141 |
| 2142 def IsFatalPushFailure(push_stdout): | |
| 2143 """True if retrying push won't help.""" | |
| 2144 return '(prohibited by Gerrit)' in push_stdout | |
| 2145 | |
| 2146 | |
| 2124 @subcommand.usage('[upstream branch to apply against]') | 2147 @subcommand.usage('[upstream branch to apply against]') |
| 2125 def CMDdcommit(parser, args): | 2148 def CMDdcommit(parser, args): |
| 2126 """Commits the current changelist via git-svn.""" | 2149 """Commits the current changelist via git-svn.""" |
| 2127 if not settings.GetIsGitSvn(): | 2150 if not settings.GetIsGitSvn(): |
| 2128 message = """This doesn't appear to be an SVN repository. | 2151 message = """This doesn't appear to be an SVN repository. |
| 2129 If your project has a git mirror with an upstream SVN master, you probably need | 2152 If your project has a git mirror with an upstream SVN master, you probably need |
| 2130 to run 'git svn init', see your project's git mirror documentation. | 2153 to run 'git svn init', see your project's git mirror documentation. |
| 2131 If your project has a true writeable upstream repository, you probably want | 2154 If your project has a true writeable upstream repository, you probably want |
| 2132 to run 'git cl land' instead. | 2155 to run 'git cl land' instead. |
| 2133 Choose wisely, if you get this wrong, your commit might appear to succeed but | 2156 Choose wisely, if you get this wrong, your commit might appear to succeed but |
| (...skipping 608 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2742 ('AppEngine is misbehaving and returned HTTP %d, again. Keep faith ' | 2765 ('AppEngine is misbehaving and returned HTTP %d, again. Keep faith ' |
| 2743 'and retry or visit go/isgaeup.\n%s') % (e.code, str(e))) | 2766 'and retry or visit go/isgaeup.\n%s') % (e.code, str(e))) |
| 2744 | 2767 |
| 2745 | 2768 |
| 2746 if __name__ == '__main__': | 2769 if __name__ == '__main__': |
| 2747 # These affect sys.stdout so do it outside of main() to simplify mocks in | 2770 # These affect sys.stdout so do it outside of main() to simplify mocks in |
| 2748 # unit testing. | 2771 # unit testing. |
| 2749 fix_encoding.fix_encoding() | 2772 fix_encoding.fix_encoding() |
| 2750 colorama.init() | 2773 colorama.init() |
| 2751 sys.exit(main(sys.argv[1:])) | 2774 sys.exit(main(sys.argv[1:])) |
| OLD | NEW |