From a54b03dd1c5fa1ab16f3cde8730f715a06ef3c07 Mon Sep 17 00:00:00 2001 From: Anatol Pomazau Date: Thu, 3 May 2012 11:43:22 -0700 Subject: [PATCH] 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 --- Documentation/cmd-create-project.txt | 9 ++- .../rpc/project/CreateProjectHandler.java | 4 +- .../gerrit/server/project/CreateProject.java | 59 ++++++++++++------- .../server/project/CreateProjectArgs.java | 2 +- .../sshd/commands/CreateProjectCommand.java | 2 +- 5 files changed, 49 insertions(+), 27 deletions(-) diff --git a/Documentation/cmd-create-project.txt b/Documentation/cmd-create-project.txt index 85d1a924ab..02aa078835 100644 --- a/Documentation/cmd-create-project.txt +++ b/Documentation/cmd-create-project.txt @@ -19,7 +19,7 @@ SYNOPSIS [--use-signed-off-by | --so] [--use-content-merge] [--require-change-id | --id] - [--branch | -b ] + [[--branch | -b ] ...] [--empty-commit] { | --name } @@ -59,8 +59,11 @@ OPTIONS --branch:: -b:: - Name of the initial branch in the newly created project. - Defaults to 'master'. + Name of the initial branch(es) in the newly created project. + 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:: -o:: diff --git a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/project/CreateProjectHandler.java b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/project/CreateProjectHandler.java index 039a301fc8..e0a2f9c59f 100644 --- a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/project/CreateProjectHandler.java +++ b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/project/CreateProjectHandler.java @@ -28,6 +28,8 @@ import com.google.inject.assistedinject.Assisted; import org.eclipse.jgit.lib.Constants; +import java.util.Collections; + public class CreateProjectHandler extends Handler { interface Factory { @@ -74,7 +76,7 @@ public class CreateProjectHandler extends Handler { } args.projectDescription = ""; args.submitType = SubmitType.MERGE_IF_NECESSARY; - args.branch = Constants.MASTER; + args.branch = Collections.emptyList(); args.createEmptyCommit = emptyCommit; args.permissionsOnly = permissionsOnly; diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/project/CreateProject.java b/gerrit-server/src/main/java/com/google/gerrit/server/project/CreateProject.java index 577a92dd84..2b08353da8 100644 --- a/gerrit-server/src/main/java/com/google/gerrit/server/project/CreateProject.java +++ b/gerrit-server/src/main/java/com/google/gerrit/server/project/CreateProject.java @@ -51,6 +51,8 @@ import org.slf4j.LoggerFactory; import java.io.IOException; import java.util.ArrayList; +import java.util.Collections; +import java.util.List; import java.util.Set; @@ -101,7 +103,7 @@ public class CreateProject { try { final String head = createProjectArgs.permissionsOnly ? GitRepositoryManager.REF_CONFIG - : createProjectArgs.branch; + : createProjectArgs.branch.get(0); final Repository repo = repoManager.createRepository(nameKey); try { NewProjectCreatedListener.Event event = new NewProjectCreatedListener.Event() { @@ -127,7 +129,7 @@ public class CreateProject { if (!createProjectArgs.permissionsOnly && createProjectArgs.createEmptyCommit) { - createEmptyCommit(repo, nameKey, createProjectArgs.branch); + createEmptyCommits(repo, nameKey, createProjectArgs.branch); } } finally { repo.close(); @@ -235,20 +237,32 @@ public class CreateProject { new ArrayList(projectOwnerGroups); } - while (createProjectArgs.branch.startsWith("/")) { - createProjectArgs.branch = createProjectArgs.branch.substring(1); + List transformedBranches = new ArrayList(); + if (createProjectArgs.branch == null || + createProjectArgs.branch.isEmpty()) { + createProjectArgs.branch = Collections.singletonList(Constants.MASTER); } - if (!createProjectArgs.branch.startsWith(Constants.R_HEADS)) { - createProjectArgs.branch = Constants.R_HEADS + createProjectArgs.branch; - } - if (!Repository.isValidRefName(createProjectArgs.branch)) { - throw new ProjectCreationFailedException(String.format( - "Branch \"%s\" is not a valid name.", createProjectArgs.branch)); + for (String branch : createProjectArgs.branch) { + while (branch.startsWith("/")) { + branch = branch.substring(1); + } + if (!branch.startsWith(Constants.R_HEADS)) { + 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, - final Project.NameKey project, final String ref) throws IOException { + private void createEmptyCommits(final Repository repo, + final Project.NameKey project, final List refs) + throws IOException { ObjectInserter oi = repo.newObjectInserter(); try { CommitBuilder cb = new CommitBuilder(); @@ -260,15 +274,18 @@ public class CreateProject { ObjectId id = oi.insert(cb); oi.flush(); - RefUpdate ru = repo.updateRef(Constants.HEAD); - ru.setNewObjectId(id); - final Result result = ru.update(); - switch (result) { - case NEW: - referenceUpdated.fire(project, ref); - break; - default: { - throw new IOException(result.name()); + for (String ref : refs) { + RefUpdate ru = repo.updateRef(ref); + ru.setNewObjectId(id); + final Result result = ru.update(); + switch (result) { + case NEW: + referenceUpdated.fire(project, ref); + break; + default: { + throw new IOException(String.format( + "Failed to create ref \"%s\": %s", ref, result.name())); + } } } } catch (IOException e) { diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/project/CreateProjectArgs.java b/gerrit-server/src/main/java/com/google/gerrit/server/project/CreateProjectArgs.java index 98adf8598e..2dee4f4976 100644 --- a/gerrit-server/src/main/java/com/google/gerrit/server/project/CreateProjectArgs.java +++ b/gerrit-server/src/main/java/com/google/gerrit/server/project/CreateProjectArgs.java @@ -30,7 +30,7 @@ public class CreateProjectArgs { public boolean contributorAgreements; public boolean signedOffBy; public boolean permissionsOnly; - public String branch; + public List branch; public boolean contentMerge; public boolean changeIdRequired; public boolean createEmptyCommit; diff --git a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/CreateProjectCommand.java b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/CreateProjectCommand.java index 1f5bc6f442..8e307b9bfb 100644 --- a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/CreateProjectCommand.java +++ b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/CreateProjectCommand.java @@ -79,7 +79,7 @@ final class CreateProjectCommand extends SshCommand { @Option(name = "--branch", aliases = {"-b"}, metaVar = "BRANCH", usage = "initial branch name\n" + "(default: master)") - private String branch = Constants.MASTER; + private List branch; @Option(name = "--empty-commit", usage = "to create initial empty commit") private boolean createEmptyCommit;