blob: adc6d293a35580ef2a5874d1ff813d41497bb347 [file] [log] [blame]
Mike Frysingerf6013762019-06-13 02:30:51 -04001# -*- coding:utf-8 -*-
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -07002#
3# Copyright (C) 2008 The Android Open Source Project
4#
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9# http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16
Sarah Owenscecd1d82012-11-01 22:59:27 -070017from __future__ import print_function
Simran Basib9a1b732015-08-20 12:19:28 -070018import os
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -070019import sys
Simran Basib9a1b732015-08-20 12:19:28 -070020
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -070021from command import Command
Zac Livingston9ead97b2017-06-13 08:29:04 -060022from git_config import IsImmutable
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -070023from git_command import git
Simran Basib9a1b732015-08-20 12:19:28 -070024import gitc_utils
Shawn O. Pearce0f0dfa32009-04-18 14:53:39 -070025from progress import Progress
Simran Basib9a1b732015-08-20 12:19:28 -070026from project import SyncBuffer
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -070027
David Pursehouse819827a2020-02-12 15:20:19 +090028
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -070029class Start(Command):
30 common = True
31 helpSummary = "Start a new branch for development"
32 helpUsage = """
Ficus Kirkpatrick6f6cd772009-04-22 17:27:12 -070033%prog <newbranchname> [--all | <project>...]
Shawn O. Pearce06e556d2009-04-18 11:19:01 -070034"""
35 helpDescription = """
36'%prog' begins a new branch of development, starting from the
37revision specified in the manifest.
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -070038"""
39
Ficus Kirkpatrick6f6cd772009-04-22 17:27:12 -070040 def _Options(self, p):
41 p.add_option('--all',
42 dest='all', action='store_true',
43 help='begin branch in all projects')
Theodore Dubois60fdc5c2019-07-30 12:14:25 -070044 p.add_option('-r', '--rev', '--revision', dest='revision',
45 help='point branch at this revision instead of upstream')
46 p.add_option('--head', dest='revision', action='store_const', const='HEAD',
47 help='abbreviation for --rev HEAD')
Ficus Kirkpatrick6f6cd772009-04-22 17:27:12 -070048
Mike Frysingerae6cb082019-08-27 01:10:59 -040049 def ValidateOptions(self, opt, args):
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -070050 if not args:
51 self.Usage()
52
53 nb = args[0]
54 if not git.check_ref_format('heads/%s' % nb):
Mike Frysingerae6cb082019-08-27 01:10:59 -040055 self.OptionParser.error("'%s' is not a valid name" % nb)
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -070056
Mike Frysingerae6cb082019-08-27 01:10:59 -040057 def Execute(self, opt, args):
58 nb = args[0]
Shawn O. Pearce0a389e92009-04-10 16:21:18 -070059 err = []
Ficus Kirkpatrick6f6cd772009-04-22 17:27:12 -070060 projects = []
61 if not opt.all:
62 projects = args[1:]
63 if len(projects) < 1:
David Pursehouse54a4e602020-02-12 14:31:05 +090064 projects = ['.'] # start it in the local project by default
Ficus Kirkpatrick6f6cd772009-04-22 17:27:12 -070065
Dan Willemsen04197a52015-10-07 16:53:10 -070066 all_projects = self.GetProjects(projects,
67 missing_ok=bool(self.gitc_manifest))
68
69 # This must happen after we find all_projects, since GetProjects may need
70 # the local directory, which will disappear once we save the GITC manifest.
Simran Basib9a1b732015-08-20 12:19:28 -070071 if self.gitc_manifest:
Dan Willemsen04197a52015-10-07 16:53:10 -070072 gitc_projects = self.GetProjects(projects, manifest=self.gitc_manifest,
73 missing_ok=True)
74 for project in gitc_projects:
Simran Basib9a1b732015-08-20 12:19:28 -070075 if project.old_revision:
76 project.already_synced = True
77 else:
78 project.already_synced = False
79 project.old_revision = project.revisionExpr
Simran Basib9a1b732015-08-20 12:19:28 -070080 project.revisionExpr = None
81 # Save the GITC manifest.
82 gitc_utils.save_manifest(self.gitc_manifest)
Shawn O. Pearce0f0dfa32009-04-18 14:53:39 -070083
Dan Willemsen04197a52015-10-07 16:53:10 -070084 # Make sure we have a valid CWD
85 if not os.path.exists(os.getcwd()):
86 os.chdir(self.manifest.topdir)
87
David Pursehouse8a68ff92012-09-24 12:15:13 +090088 pm = Progress('Starting %s' % nb, len(all_projects))
89 for project in all_projects:
Shawn O. Pearce0f0dfa32009-04-18 14:53:39 -070090 pm.update()
Dan Willemsen5ea32d12015-09-08 13:27:20 -070091
Simran Basib9a1b732015-08-20 12:19:28 -070092 if self.gitc_manifest:
Dan Willemsen5ea32d12015-09-08 13:27:20 -070093 gitc_project = self.gitc_manifest.paths[project.relpath]
94 # Sync projects that have not been opened.
Simran Basib9a1b732015-08-20 12:19:28 -070095 if not gitc_project.already_synced:
96 proj_localdir = os.path.join(self.gitc_manifest.gitc_client_dir,
97 project.relpath)
98 project.worktree = proj_localdir
99 if not os.path.exists(proj_localdir):
100 os.makedirs(proj_localdir)
101 project.Sync_NetworkHalf()
102 sync_buf = SyncBuffer(self.manifest.manifestProject.config)
103 project.Sync_LocalHalf(sync_buf)
Dan Willemsen5ea32d12015-09-08 13:27:20 -0700104 project.revisionId = gitc_project.old_revision
Simran Basib9a1b732015-08-20 12:19:28 -0700105
Zac Livingston9ead97b2017-06-13 08:29:04 -0600106 # If the current revision is immutable, such as a SHA1, a tag or
107 # a change, then we can't push back to it. Substitute with
108 # dest_branch, if defined; or with manifest default revision instead.
Simran Basib9a1b732015-08-20 12:19:28 -0700109 branch_merge = ''
Zac Livingston9ead97b2017-06-13 08:29:04 -0600110 if IsImmutable(project.revisionExpr):
Max Liu5fb8ed22014-06-23 14:48:16 +0800111 if project.dest_branch:
Simran Basib9a1b732015-08-20 12:19:28 -0700112 branch_merge = project.dest_branch
Max Liu5fb8ed22014-06-23 14:48:16 +0800113 else:
Simran Basib9a1b732015-08-20 12:19:28 -0700114 branch_merge = self.manifest.default.revisionExpr
Dan Willemsen5ea32d12015-09-08 13:27:20 -0700115
Theodore Dubois60fdc5c2019-07-30 12:14:25 -0700116 if not project.StartBranch(
David Pursehouseabdf7502020-02-12 14:58:39 +0900117 nb, branch_merge=branch_merge, revision=opt.revision):
Shawn O. Pearce0a389e92009-04-10 16:21:18 -0700118 err.append(project)
Shawn O. Pearce0f0dfa32009-04-18 14:53:39 -0700119 pm.end()
Shawn O. Pearce0a389e92009-04-10 16:21:18 -0700120
121 if err:
Shawn O. Pearce0a389e92009-04-10 16:21:18 -0700122 for p in err:
Sarah Owenscecd1d82012-11-01 22:59:27 -0700123 print("error: %s/: cannot start %s" % (p.relpath, nb),
124 file=sys.stderr)
Shawn O. Pearce0a389e92009-04-10 16:21:18 -0700125 sys.exit(1)