blob: 898b023f09fa7eb7e5f2da734f7aa1b99b8ac6cc [file] [log] [blame]
Dave Borowitz1b46d672014-10-02 09:18:19 -07001#!/usr/bin/python
2# Copyright (C) 2014 The Android Open Source Project
3#
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8# http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
15
16from __future__ import print_function
17
18import argparse
19import collections
20import os
21import subprocess
22import sys
23
24
25def get_config(name):
26 args = ['git', 'config', '--get', name]
27 p = subprocess.Popen(args, stdout=subprocess.PIPE)
28 out, _ = p.communicate()
29 ret = p.poll()
30 if ret not in (0, 1):
31 raise subprocess.CalledProcessError(ret, ' '.join(args), output=out)
32 return out.strip()
33
34
35def deref(name):
36 p = subprocess.Popen(
37 ['git', 'rev-parse', '--symbolic-full-name', name],
38 stdout=subprocess.PIPE, stderr=subprocess.PIPE)
39 out, _ = p.communicate()
40 return out.strip()
41
42
43def main(argv):
44 p = argparse.ArgumentParser(description='Push changes to Gerrit for review')
45 p.add_argument('-r', '--remote', default='', metavar='REMOTE',
46 help='remote name or URL to push to')
47 p.add_argument('-b', '--branch', default='', metavar='BRANCH',
48 help='remote branch name, refs/for/BRANCH')
49 p.add_argument('reviewers', nargs='*', metavar='REVIEWER',
50 help='reviewer names or aliases')
51 p.add_argument('-t', '--topic', default='', metavar='TOPIC',
52 help='topic for new changes')
53 p.add_argument('--dry-run', action='store_true',
54 help='dry run, print git command and exit')
55 args = p.parse_args()
56
57 if not args.remote or not args.branch:
58 hp = 'refs/heads/'
59 upstream = deref('HEAD')
60 while upstream.startswith(hp):
61 upstream = deref(upstream[len(hp):] + '@{u}')
62
63 rp = 'refs/remotes/'
64 if upstream.startswith(rp):
65 def_remote, def_branch = upstream[len(rp):].split('/', 1)
66 else:
67 def_remote, def_branch = 'origin', 'master'
68 args.remote = args.remote or def_remote
69 args.branch = args.branch or def_branch
70
71 opts = collections.defaultdict(list)
72 opts['r'].extend((get_config('reviewer.' + r) or r) for r in args.reviewers)
73 if args.topic:
74 opts['topic'].append(args.topic)
75 opts_str = ','.join('%s=%s' % (k, v) for k in opts for v in opts[k])
76 if opts_str:
77 opts_str = '%' + opts_str
78
79 git_args = ['git', 'push', args.remote,
80 'HEAD:refs/for/%s%s' % (args.branch, opts_str)]
81 if args.dry_run:
82 print(' '.join(git_args))
83 return 0
84 os.execvp('git', git_args)
85
86
87if __name__ == '__main__':
88 sys.exit(main(sys.argv))