Support multiple branches creation in 'create-project'

In case if a project has some kind of waterfall automerging
a->b->c it is convenient to create all these branches at the
project creation time.

e.g. '.. gerrit create-project -b master -b foo -b bar ...'

Change-Id: Iec418985caa89197825cd4fc292bede787bf9786
This commit is contained in:
Anatol Pomazau
2012-05-03 11:43:22 -07:00
parent 058604b548
commit a54b03dd1c
5 changed files with 49 additions and 27 deletions

View File

@@ -19,7 +19,7 @@ SYNOPSIS
[--use-signed-off-by | --so] [--use-signed-off-by | --so]
[--use-content-merge] [--use-content-merge]
[--require-change-id | --id] [--require-change-id | --id]
[--branch <REF> | -b <REF>] [[--branch <REF> | -b <REF>] ...]
[--empty-commit] [--empty-commit]
{ <NAME> | --name <NAME> } { <NAME> | --name <NAME> }
@@ -59,8 +59,11 @@ OPTIONS
--branch:: --branch::
-b:: -b::
Name of the initial branch in the newly created project. Name of the initial branch(es) in the newly created project.
Defaults to 'master'. Several branches can be specified on the command line.
If several branches are specified then the first one becomes HEAD
of the project. If none branches are specified then default value
('master') is used.
--owner:: --owner::
-o:: -o::

View File

@@ -28,6 +28,8 @@ import com.google.inject.assistedinject.Assisted;
import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.lib.Constants;
import java.util.Collections;
public class CreateProjectHandler extends Handler<VoidResult> { public class CreateProjectHandler extends Handler<VoidResult> {
interface Factory { interface Factory {
@@ -74,7 +76,7 @@ public class CreateProjectHandler extends Handler<VoidResult> {
} }
args.projectDescription = ""; args.projectDescription = "";
args.submitType = SubmitType.MERGE_IF_NECESSARY; args.submitType = SubmitType.MERGE_IF_NECESSARY;
args.branch = Constants.MASTER; args.branch = Collections.emptyList();
args.createEmptyCommit = emptyCommit; args.createEmptyCommit = emptyCommit;
args.permissionsOnly = permissionsOnly; args.permissionsOnly = permissionsOnly;

View File

@@ -51,6 +51,8 @@ import org.slf4j.LoggerFactory;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set; import java.util.Set;
@@ -101,7 +103,7 @@ public class CreateProject {
try { try {
final String head = final String head =
createProjectArgs.permissionsOnly ? GitRepositoryManager.REF_CONFIG createProjectArgs.permissionsOnly ? GitRepositoryManager.REF_CONFIG
: createProjectArgs.branch; : createProjectArgs.branch.get(0);
final Repository repo = repoManager.createRepository(nameKey); final Repository repo = repoManager.createRepository(nameKey);
try { try {
NewProjectCreatedListener.Event event = new NewProjectCreatedListener.Event() { NewProjectCreatedListener.Event event = new NewProjectCreatedListener.Event() {
@@ -127,7 +129,7 @@ public class CreateProject {
if (!createProjectArgs.permissionsOnly if (!createProjectArgs.permissionsOnly
&& createProjectArgs.createEmptyCommit) { && createProjectArgs.createEmptyCommit) {
createEmptyCommit(repo, nameKey, createProjectArgs.branch); createEmptyCommits(repo, nameKey, createProjectArgs.branch);
} }
} finally { } finally {
repo.close(); repo.close();
@@ -235,20 +237,32 @@ public class CreateProject {
new ArrayList<AccountGroup.UUID>(projectOwnerGroups); new ArrayList<AccountGroup.UUID>(projectOwnerGroups);
} }
while (createProjectArgs.branch.startsWith("/")) { List<String> transformedBranches = new ArrayList<String>();
createProjectArgs.branch = createProjectArgs.branch.substring(1); if (createProjectArgs.branch == null ||
createProjectArgs.branch.isEmpty()) {
createProjectArgs.branch = Collections.singletonList(Constants.MASTER);
} }
if (!createProjectArgs.branch.startsWith(Constants.R_HEADS)) { for (String branch : createProjectArgs.branch) {
createProjectArgs.branch = Constants.R_HEADS + createProjectArgs.branch; while (branch.startsWith("/")) {
} branch = branch.substring(1);
if (!Repository.isValidRefName(createProjectArgs.branch)) { }
throw new ProjectCreationFailedException(String.format( if (!branch.startsWith(Constants.R_HEADS)) {
"Branch \"%s\" is not a valid name.", createProjectArgs.branch)); branch = Constants.R_HEADS + branch;
}
if (!Repository.isValidRefName(branch)) {
throw new ProjectCreationFailedException(String.format(
"Branch \"%s\" is not a valid name.", branch));
}
if (!transformedBranches.contains(branch)) {
transformedBranches.add(branch);
}
} }
createProjectArgs.branch = transformedBranches;
} }
private void createEmptyCommit(final Repository repo, private void createEmptyCommits(final Repository repo,
final Project.NameKey project, final String ref) throws IOException { final Project.NameKey project, final List<String> refs)
throws IOException {
ObjectInserter oi = repo.newObjectInserter(); ObjectInserter oi = repo.newObjectInserter();
try { try {
CommitBuilder cb = new CommitBuilder(); CommitBuilder cb = new CommitBuilder();
@@ -260,15 +274,18 @@ public class CreateProject {
ObjectId id = oi.insert(cb); ObjectId id = oi.insert(cb);
oi.flush(); oi.flush();
RefUpdate ru = repo.updateRef(Constants.HEAD); for (String ref : refs) {
ru.setNewObjectId(id); RefUpdate ru = repo.updateRef(ref);
final Result result = ru.update(); ru.setNewObjectId(id);
switch (result) { final Result result = ru.update();
case NEW: switch (result) {
referenceUpdated.fire(project, ref); case NEW:
break; referenceUpdated.fire(project, ref);
default: { break;
throw new IOException(result.name()); default: {
throw new IOException(String.format(
"Failed to create ref \"%s\": %s", ref, result.name()));
}
} }
} }
} catch (IOException e) { } catch (IOException e) {

View File

@@ -30,7 +30,7 @@ public class CreateProjectArgs {
public boolean contributorAgreements; public boolean contributorAgreements;
public boolean signedOffBy; public boolean signedOffBy;
public boolean permissionsOnly; public boolean permissionsOnly;
public String branch; public List<String> branch;
public boolean contentMerge; public boolean contentMerge;
public boolean changeIdRequired; public boolean changeIdRequired;
public boolean createEmptyCommit; public boolean createEmptyCommit;

View File

@@ -79,7 +79,7 @@ final class CreateProjectCommand extends SshCommand {
@Option(name = "--branch", aliases = {"-b"}, metaVar = "BRANCH", usage = "initial branch name\n" @Option(name = "--branch", aliases = {"-b"}, metaVar = "BRANCH", usage = "initial branch name\n"
+ "(default: master)") + "(default: master)")
private String branch = Constants.MASTER; private List<String> branch;
@Option(name = "--empty-commit", usage = "to create initial empty commit") @Option(name = "--empty-commit", usage = "to create initial empty commit")
private boolean createEmptyCommit; private boolean createEmptyCommit;