blob: 7684b6d7013c18c9a3019fb5f796edc887cb263d [file] [log] [blame]
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -07001# Copyright (C) 2008 The Android Open Source Project
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7# http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14
Simran Basib9a1b732015-08-20 12:19:28 -070015import os
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -070016import sys
Simran Basib9a1b732015-08-20 12:19:28 -070017
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -070018from command import Command
Zac Livingston9ead97b2017-06-13 08:29:04 -060019from git_config import IsImmutable
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -070020from git_command import git
Simran Basib9a1b732015-08-20 12:19:28 -070021import gitc_utils
Shawn O. Pearce0f0dfa32009-04-18 14:53:39 -070022from progress import Progress
Simran Basib9a1b732015-08-20 12:19:28 -070023from project import SyncBuffer
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -070024
David Pursehouse819827a2020-02-12 15:20:19 +090025
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -070026class Start(Command):
27 common = True
28 helpSummary = "Start a new branch for development"
29 helpUsage = """
Ficus Kirkpatrick6f6cd772009-04-22 17:27:12 -070030%prog <newbranchname> [--all | <project>...]
Shawn O. Pearce06e556d2009-04-18 11:19:01 -070031"""
32 helpDescription = """
33'%prog' begins a new branch of development, starting from the
34revision specified in the manifest.
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -070035"""
36
Ficus Kirkpatrick6f6cd772009-04-22 17:27:12 -070037 def _Options(self, p):
38 p.add_option('--all',
39 dest='all', action='store_true',
40 help='begin branch in all projects')
Theodore Dubois60fdc5c2019-07-30 12:14:25 -070041 p.add_option('-r', '--rev', '--revision', dest='revision',
42 help='point branch at this revision instead of upstream')
43 p.add_option('--head', dest='revision', action='store_const', const='HEAD',
44 help='abbreviation for --rev HEAD')
Ficus Kirkpatrick6f6cd772009-04-22 17:27:12 -070045
Mike Frysingerae6cb082019-08-27 01:10:59 -040046 def ValidateOptions(self, opt, args):
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -070047 if not args:
48 self.Usage()
49
50 nb = args[0]
51 if not git.check_ref_format('heads/%s' % nb):
Mike Frysingerae6cb082019-08-27 01:10:59 -040052 self.OptionParser.error("'%s' is not a valid name" % nb)
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -070053
Mike Frysingerae6cb082019-08-27 01:10:59 -040054 def Execute(self, opt, args):
55 nb = args[0]
Shawn O. Pearce0a389e92009-04-10 16:21:18 -070056 err = []
Ficus Kirkpatrick6f6cd772009-04-22 17:27:12 -070057 projects = []
58 if not opt.all:
59 projects = args[1:]
60 if len(projects) < 1:
David Pursehouse54a4e602020-02-12 14:31:05 +090061 projects = ['.'] # start it in the local project by default
Ficus Kirkpatrick6f6cd772009-04-22 17:27:12 -070062
Dan Willemsen04197a52015-10-07 16:53:10 -070063 all_projects = self.GetProjects(projects,
64 missing_ok=bool(self.gitc_manifest))
65
66 # This must happen after we find all_projects, since GetProjects may need
67 # the local directory, which will disappear once we save the GITC manifest.
Simran Basib9a1b732015-08-20 12:19:28 -070068 if self.gitc_manifest:
Dan Willemsen04197a52015-10-07 16:53:10 -070069 gitc_projects = self.GetProjects(projects, manifest=self.gitc_manifest,
70 missing_ok=True)
71 for project in gitc_projects:
Simran Basib9a1b732015-08-20 12:19:28 -070072 if project.old_revision:
73 project.already_synced = True
74 else:
75 project.already_synced = False
76 project.old_revision = project.revisionExpr
Simran Basib9a1b732015-08-20 12:19:28 -070077 project.revisionExpr = None
78 # Save the GITC manifest.
79 gitc_utils.save_manifest(self.gitc_manifest)
Shawn O. Pearce0f0dfa32009-04-18 14:53:39 -070080
Dan Willemsen04197a52015-10-07 16:53:10 -070081 # Make sure we have a valid CWD
82 if not os.path.exists(os.getcwd()):
83 os.chdir(self.manifest.topdir)
84
David Pursehouse8a68ff92012-09-24 12:15:13 +090085 pm = Progress('Starting %s' % nb, len(all_projects))
86 for project in all_projects:
Shawn O. Pearce0f0dfa32009-04-18 14:53:39 -070087 pm.update()
Dan Willemsen5ea32d12015-09-08 13:27:20 -070088
Simran Basib9a1b732015-08-20 12:19:28 -070089 if self.gitc_manifest:
Dan Willemsen5ea32d12015-09-08 13:27:20 -070090 gitc_project = self.gitc_manifest.paths[project.relpath]
91 # Sync projects that have not been opened.
Simran Basib9a1b732015-08-20 12:19:28 -070092 if not gitc_project.already_synced:
93 proj_localdir = os.path.join(self.gitc_manifest.gitc_client_dir,
94 project.relpath)
95 project.worktree = proj_localdir
96 if not os.path.exists(proj_localdir):
97 os.makedirs(proj_localdir)
98 project.Sync_NetworkHalf()
99 sync_buf = SyncBuffer(self.manifest.manifestProject.config)
100 project.Sync_LocalHalf(sync_buf)
Dan Willemsen5ea32d12015-09-08 13:27:20 -0700101 project.revisionId = gitc_project.old_revision
Simran Basib9a1b732015-08-20 12:19:28 -0700102
Zac Livingston9ead97b2017-06-13 08:29:04 -0600103 # If the current revision is immutable, such as a SHA1, a tag or
104 # a change, then we can't push back to it. Substitute with
105 # dest_branch, if defined; or with manifest default revision instead.
Simran Basib9a1b732015-08-20 12:19:28 -0700106 branch_merge = ''
Zac Livingston9ead97b2017-06-13 08:29:04 -0600107 if IsImmutable(project.revisionExpr):
Max Liu5fb8ed22014-06-23 14:48:16 +0800108 if project.dest_branch:
Simran Basib9a1b732015-08-20 12:19:28 -0700109 branch_merge = project.dest_branch
Max Liu5fb8ed22014-06-23 14:48:16 +0800110 else:
Simran Basib9a1b732015-08-20 12:19:28 -0700111 branch_merge = self.manifest.default.revisionExpr
Dan Willemsen5ea32d12015-09-08 13:27:20 -0700112
Theodore Dubois60fdc5c2019-07-30 12:14:25 -0700113 if not project.StartBranch(
David Pursehouseabdf7502020-02-12 14:58:39 +0900114 nb, branch_merge=branch_merge, revision=opt.revision):
Shawn O. Pearce0a389e92009-04-10 16:21:18 -0700115 err.append(project)
Shawn O. Pearce0f0dfa32009-04-18 14:53:39 -0700116 pm.end()
Shawn O. Pearce0a389e92009-04-10 16:21:18 -0700117
118 if err:
Shawn O. Pearce0a389e92009-04-10 16:21:18 -0700119 for p in err:
Sarah Owenscecd1d82012-11-01 22:59:27 -0700120 print("error: %s/: cannot start %s" % (p.relpath, nb),
121 file=sys.stderr)
Shawn O. Pearce0a389e92009-04-10 16:21:18 -0700122 sys.exit(1)