blob: f2ca024f8aedc3b9144e20b75687f26bb95841db [file] [log] [blame]
Edward Lesmes98eda3f2019-08-12 21:09:53 +00001#!/usr/bin/env python
iannucci@chromium.orgc050a5b2014-03-26 06:18:50 +00002# Copyright 2014 The Chromium Authors. All rights reserved.
3# Use of this source code is governed by a BSD-style license that can be
4# found in the LICENSE file.
techtonik@gmail.comb14fccd2016-04-20 04:10:09 +00005"""
6Create new branch tracking origin/master by default.
7"""
8
iannucci@chromium.orgc050a5b2014-03-26 06:18:50 +00009import argparse
10import sys
11
Edward Lemur84101642020-02-21 21:40:34 +000012import git_common
iannucci@chromium.orgc050a5b2014-03-26 06:18:50 +000013import subprocess2
14
iannucci@chromium.orgc050a5b2014-03-26 06:18:50 +000015
Edward Lemur84101642020-02-21 21:40:34 +000016def create_new_branch(
17 branch_name, upstream_current=False, upstream=None, inject_current=False):
18 upstream = upstream or git_common.root()
19 try:
20 if inject_current:
21 below = git_common.current_branch()
22 if below is None:
23 raise Exception('no current branch')
24 above = git_common.upstream(below)
25 if above is None:
26 raise Exception('branch %s has no upstream' % (below))
27 git_common.run('checkout', '--track', above, '-b', branch_name)
28 git_common.run('branch', '--set-upstream-to', branch_name, below)
29 elif upstream_current:
30 git_common.run('checkout', '--track', '-b', branch_name)
31 else:
32 if upstream in git_common.tags():
33 # TODO(iannucci): ensure that basis_ref is an ancestor of HEAD?
34 git_common.run(
35 'checkout', '--no-track', '-b', branch_name,
36 git_common.hash_one(upstream))
37 git_common.set_config('branch.%s.remote' % branch_name, '.')
38 git_common.set_config('branch.%s.merge' % branch_name, upstream)
39 else:
40 # TODO(iannucci): Detect unclean workdir then stash+pop if we need to
41 # teleport to a conflicting portion of history?
42 git_common.run('checkout', '--track', upstream, '-b', branch_name)
43 git_common.get_or_create_merge_base(branch_name)
44 except subprocess2.CalledProcessError as cpe:
45 sys.stdout.write(cpe.stdout.decode('utf-8', 'replace'))
46 sys.stderr.write(cpe.stderr.decode('utf-8', 'replace'))
47 return 1
48 sys.stderr.write('Switched to branch %s.\n' % branch_name)
49 return 0
iannucci@chromium.orgc050a5b2014-03-26 06:18:50 +000050
51def main(args):
52 parser = argparse.ArgumentParser(
techtonik@gmail.comb14fccd2016-04-20 04:10:09 +000053 formatter_class=argparse.ArgumentDefaultsHelpFormatter,
54 description=__doc__,
iannucci@chromium.orgc050a5b2014-03-26 06:18:50 +000055 )
56 parser.add_argument('branch_name')
57 g = parser.add_mutually_exclusive_group()
pgervais@chromium.orgb9f27512014-08-08 15:52:33 +000058 g.add_argument('--upstream-current', '--upstream_current',
59 action='store_true',
iannucci@chromium.orgc050a5b2014-03-26 06:18:50 +000060 help='set upstream branch to current branch.')
Edward Lemur84101642020-02-21 21:40:34 +000061 g.add_argument('--upstream', metavar='REF',
iannucci@chromium.orgc050a5b2014-03-26 06:18:50 +000062 help='upstream branch (or tag) to track.')
Asanka Herath53a115e2018-04-12 19:07:37 -040063 g.add_argument('--inject-current', '--inject_current',
64 action='store_true',
65 help='new branch adopts current branch\'s upstream,' +
66 ' and new branch becomes current branch\'s upstream.')
iannucci@chromium.orgc050a5b2014-03-26 06:18:50 +000067 g.add_argument('--lkgr', action='store_const', const='lkgr', dest='upstream',
68 help='set basis ref for new branch to lkgr.')
69
70 opts = parser.parse_args(args)
71
Edward Lemur84101642020-02-21 21:40:34 +000072 return create_new_branch(
73 opts.branch_name, opts.upstream_current, opts.upstream,
74 opts.inject_current)
iannucci@chromium.orgc050a5b2014-03-26 06:18:50 +000075
76
77if __name__ == '__main__': # pragma: no cover
sbc@chromium.org013731e2015-02-26 18:28:43 +000078 try:
79 sys.exit(main(sys.argv[1:]))
80 except KeyboardInterrupt:
81 sys.stderr.write('interrupted\n')
82 sys.exit(1)