| OLD | NEW |
| 1 #!/usr/bin/python | 1 #!/usr/bin/python |
| 2 # git-cl -- a git-command for integrating reviews on Rietveld | 2 # git-cl -- a git-command for integrating reviews on Rietveld |
| 3 # Copyright (C) 2008 Evan Martin <martine@danga.com> | 3 # Copyright (C) 2008 Evan Martin <martine@danga.com> |
| 4 | 4 |
| 5 import errno | 5 import errno |
| 6 import logging | 6 import logging |
| 7 import optparse | 7 import optparse |
| 8 import os | 8 import os |
| 9 import re | 9 import re |
| 10 import subprocess | 10 import subprocess |
| (...skipping 11 matching lines...) Expand all Loading... |
| 22 try: | 22 try: |
| 23 # Add the parent directory in case it's a depot_tools checkout. | 23 # Add the parent directory in case it's a depot_tools checkout. |
| 24 depot_tools_path = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) | 24 depot_tools_path = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) |
| 25 sys.path.append(depot_tools_path) | 25 sys.path.append(depot_tools_path) |
| 26 import breakpad | 26 import breakpad |
| 27 except ImportError: | 27 except ImportError: |
| 28 pass | 28 pass |
| 29 | 29 |
| 30 DEFAULT_SERVER = 'http://codereview.appspot.com' | 30 DEFAULT_SERVER = 'http://codereview.appspot.com' |
| 31 PREDCOMMIT_HOOK = '.git/hooks/pre-cl-dcommit' | 31 PREDCOMMIT_HOOK = '.git/hooks/pre-cl-dcommit' |
| 32 POSTUPSTREAM_HOOK_PATTERN = '.git/hooks/post-cl-%s' |
| 32 PREUPLOAD_HOOK = '.git/hooks/pre-cl-upload' | 33 PREUPLOAD_HOOK = '.git/hooks/pre-cl-upload' |
| 33 DESCRIPTION_BACKUP_FILE = '~/.git_cl_description_backup' | 34 DESCRIPTION_BACKUP_FILE = '~/.git_cl_description_backup' |
| 34 | 35 |
| 35 def DieWithError(message): | 36 def DieWithError(message): |
| 36 print >>sys.stderr, message | 37 print >>sys.stderr, message |
| 37 sys.exit(1) | 38 sys.exit(1) |
| 38 | 39 |
| 39 | 40 |
| 40 def Popen(cmd, **kwargs): | 41 def Popen(cmd, **kwargs): |
| 41 """Wrapper for subprocess.Popen() that logs and watch for cygwin issues""" | 42 """Wrapper for subprocess.Popen() that logs and watch for cygwin issues""" |
| (...skipping 924 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 966 # We might be in a directory that's present in this branch but not in the | 967 # We might be in a directory that's present in this branch but not in the |
| 967 # trunk. Move up to the top of the tree so that git commands that expect a | 968 # trunk. Move up to the top of the tree so that git commands that expect a |
| 968 # valid CWD won't fail after we check out the merge branch. | 969 # valid CWD won't fail after we check out the merge branch. |
| 969 rel_base_path = RunGit(['rev-parse', '--show-cdup']).strip() | 970 rel_base_path = RunGit(['rev-parse', '--show-cdup']).strip() |
| 970 if rel_base_path: | 971 if rel_base_path: |
| 971 os.chdir(rel_base_path) | 972 os.chdir(rel_base_path) |
| 972 | 973 |
| 973 # Stuff our change into the merge branch. | 974 # Stuff our change into the merge branch. |
| 974 # We wrap in a try...finally block so if anything goes wrong, | 975 # We wrap in a try...finally block so if anything goes wrong, |
| 975 # we clean up the branches. | 976 # we clean up the branches. |
| 977 retcode = -1 |
| 976 try: | 978 try: |
| 977 RunGit(['checkout', '-q', '-b', MERGE_BRANCH, base_branch]) | 979 RunGit(['checkout', '-q', '-b', MERGE_BRANCH, base_branch]) |
| 978 RunGit(['merge', '--squash', cl.GetBranchRef()]) | 980 RunGit(['merge', '--squash', cl.GetBranchRef()]) |
| 979 if options.contributor: | 981 if options.contributor: |
| 980 RunGit(['commit', '--author', options.contributor, '-m', description]) | 982 RunGit(['commit', '--author', options.contributor, '-m', description]) |
| 981 else: | 983 else: |
| 982 RunGit(['commit', '-m', description]) | 984 RunGit(['commit', '-m', description]) |
| 983 if cmd == 'push': | 985 if cmd == 'push': |
| 984 # push the merge branch. | 986 # push the merge branch. |
| 985 remote, branch = cl.FetchUpstreamTuple() | 987 remote, branch = cl.FetchUpstreamTuple() |
| 986 retcode, output = RunGitWithCode( | 988 retcode, output = RunGitWithCode( |
| 987 ['push', '--porcelain', remote, 'HEAD:%s' % branch]) | 989 ['push', '--porcelain', remote, 'HEAD:%s' % branch]) |
| 988 logging.debug(output) | 990 logging.debug(output) |
| 989 else: | 991 else: |
| 990 # dcommit the merge branch. | 992 # dcommit the merge branch. |
| 991 output = RunGit(['svn', 'dcommit', '--no-rebase']) | 993 retcode, output = RunGitWithCode(['svn', 'dcommit', '--no-rebase']) |
| 992 finally: | 994 finally: |
| 993 # And then swap back to the original branch and clean up. | 995 # And then swap back to the original branch and clean up. |
| 994 RunGit(['checkout', '-q', cl.GetBranch()]) | 996 RunGit(['checkout', '-q', cl.GetBranch()]) |
| 995 RunGit(['branch', '-D', MERGE_BRANCH]) | 997 RunGit(['branch', '-D', MERGE_BRANCH]) |
| 996 | 998 |
| 997 if cl.GetIssue(): | 999 if cl.GetIssue(): |
| 998 if cmd == 'dcommit' and 'Committed r' in output: | 1000 if cmd == 'dcommit' and 'Committed r' in output: |
| 999 revision = re.match('.*?\nCommitted r(\\d+)', output, re.DOTALL).group(1) | 1001 revision = re.match('.*?\nCommitted r(\\d+)', output, re.DOTALL).group(1) |
| 1000 elif cmd == 'push' and retcode == 0: | 1002 elif cmd == 'push' and retcode == 0: |
| 1001 revision = output.splitlines()[1].split('\t')[2].split('..')[1] | 1003 revision = output.splitlines()[1].split('\t')[2].split('..')[1] |
| 1002 else: | 1004 else: |
| 1003 return 1 | 1005 return 1 |
| 1004 viewvc_url = settings.GetViewVCUrl() | 1006 viewvc_url = settings.GetViewVCUrl() |
| 1005 if viewvc_url and revision: | 1007 if viewvc_url and revision: |
| 1006 cl.description += ('\n\nCommitted: ' + viewvc_url + revision) | 1008 cl.description += ('\n\nCommitted: ' + viewvc_url + revision) |
| 1007 print ('Closing issue ' | 1009 print ('Closing issue ' |
| 1008 '(you may be prompted for your codereview password)...') | 1010 '(you may be prompted for your codereview password)...') |
| 1009 cl.CloseIssue() | 1011 cl.CloseIssue() |
| 1010 cl.SetIssue(0) | 1012 cl.SetIssue(0) |
| 1013 |
| 1014 if retcode == 0: |
| 1015 hook = POSTUPSTREAM_HOOK_PATTERN % cmd |
| 1016 RunHook(hook, upstream_branch=base_branch, error_ok=True) |
| 1017 |
| 1011 return 0 | 1018 return 0 |
| 1012 | 1019 |
| 1013 | 1020 |
| 1014 @usage('[upstream branch to apply against]') | 1021 @usage('[upstream branch to apply against]') |
| 1015 def CMDdcommit(parser, args): | 1022 def CMDdcommit(parser, args): |
| 1016 """commit the current changelist via git-svn""" | 1023 """commit the current changelist via git-svn""" |
| 1017 if not settings.GetIsGitSvn(): | 1024 if not settings.GetIsGitSvn(): |
| 1018 print('This doesn\'t appear to be an SVN repository.') | 1025 print('This doesn\'t appear to be an SVN repository.') |
| 1019 print('Are you sure you didn\'t mean \'git cl push\'?') | 1026 print('Are you sure you didn\'t mean \'git cl push\'?') |
| 1020 raw_input('[Press enter to dcommit or ctrl-C to quit]') | 1027 raw_input('[Press enter to dcommit or ctrl-C to quit]') |
| (...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1247 ('AppEngine is misbehaving and returned HTTP %d, again. Keep faith ' | 1254 ('AppEngine is misbehaving and returned HTTP %d, again. Keep faith ' |
| 1248 'and retry or visit go/isgaeup.\n%s') % (e.code, str(e))) | 1255 'and retry or visit go/isgaeup.\n%s') % (e.code, str(e))) |
| 1249 | 1256 |
| 1250 # Not a known command. Default to help. | 1257 # Not a known command. Default to help. |
| 1251 GenUsage(parser, 'help') | 1258 GenUsage(parser, 'help') |
| 1252 return CMDhelp(parser, argv) | 1259 return CMDhelp(parser, argv) |
| 1253 | 1260 |
| 1254 | 1261 |
| 1255 if __name__ == '__main__': | 1262 if __name__ == '__main__': |
| 1256 sys.exit(main(sys.argv[1:])) | 1263 sys.exit(main(sys.argv[1:])) |
| OLD | NEW |