Add option --initial-branch/-b to InitCommand and the CLI init command. This is the first step to implement support for the new option init.defaultBranch. Both were added to git in release 2.28. See https://git-scm.com/docs/git-init#Documentation/git-init.txt--bltbranch-namegt Bug: 564794 Change-Id: Ia383b3f90b5549db80f99b2310450a7faf6bce4c Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>tags/v5.11.0.202102240950-m3
@@ -11,11 +11,14 @@ | |||
package org.eclipse.jgit.pgm; | |||
import static org.junit.Assert.assertArrayEquals; | |||
import static org.junit.Assert.assertEquals; | |||
import java.io.File; | |||
import org.eclipse.jgit.internal.storage.file.FileRepository; | |||
import org.eclipse.jgit.lib.CLIRepositoryTestCase; | |||
import org.eclipse.jgit.lib.Constants; | |||
import org.eclipse.jgit.lib.Repository; | |||
import org.junit.Rule; | |||
import org.junit.Test; | |||
import org.junit.rules.TemporaryFolder; | |||
@@ -54,4 +57,22 @@ public class InitTest extends CLIRepositoryTestCase { | |||
assertArrayEquals(expecteds, result); | |||
} | |||
@Test | |||
public void testInitDirectoryInitialBranch() throws Exception { | |||
File workDirectory = tempFolder.getRoot(); | |||
File gitDirectory = new File(workDirectory, Constants.DOT_GIT); | |||
String[] result = execute( | |||
"git init -b main '" + workDirectory.getCanonicalPath() + "'"); | |||
String[] expecteds = new String[] { | |||
"Initialized empty Git repository in " | |||
+ gitDirectory.getCanonicalPath(), | |||
"" }; | |||
assertArrayEquals(expecteds, result); | |||
try (Repository repo = new FileRepository(gitDirectory)) { | |||
assertEquals("refs/heads/main", repo.getFullBranch()); | |||
} | |||
} | |||
} |
@@ -432,6 +432,7 @@ usage_updateRef=reference to update | |||
usage_updateRemoteRefsFromAnotherRepository=Update remote refs from another repository | |||
usage_useNameInsteadOfOriginToTrackUpstream=use <name> instead of 'origin' to track upstream | |||
usage_checkoutBranchAfterClone=check out named branch instead of remote's HEAD | |||
usage_initialBranch=initial branch in the newly created repository (default 'master') | |||
usage_viewCommitHistory=View commit history | |||
usage_orphan=Create a new orphan branch. The first commit made on this new branch will have no parents and it will be the root of a new history totally disconnected from other branches and commits. | |||
usernameFor=Username for {0}: |
@@ -24,6 +24,7 @@ import org.eclipse.jgit.api.InitCommand; | |||
import org.eclipse.jgit.api.errors.GitAPIException; | |||
import org.eclipse.jgit.lib.Repository; | |||
import org.eclipse.jgit.pgm.internal.CLIText; | |||
import org.eclipse.jgit.util.StringUtils; | |||
import org.kohsuke.args4j.Argument; | |||
import org.kohsuke.args4j.Option; | |||
@@ -32,6 +33,10 @@ class Init extends TextBuiltin { | |||
@Option(name = "--bare", usage = "usage_CreateABareRepository") | |||
private boolean bare; | |||
@Option(name = "--initial-branch", aliases = { "-b" }, | |||
metaVar = "metaVar_branchName", usage = "usage_initialBranch") | |||
private String branch; | |||
@Argument(index = 0, metaVar = "metaVar_directory") | |||
private String directory; | |||
@@ -54,6 +59,9 @@ class Init extends TextBuiltin { | |||
} | |||
Repository repository; | |||
try { | |||
if (!StringUtils.isEmptyOrNull(branch)) { | |||
command.setInitialBranch(branch); | |||
} | |||
repository = command.call().getRepository(); | |||
outw.println(MessageFormat.format( | |||
CLIText.get().initializedEmptyGitRepositoryIn, |
@@ -9,6 +9,7 @@ | |||
*/ | |||
package org.eclipse.jgit.api; | |||
import static org.junit.Assert.assertEquals; | |||
import static org.junit.Assert.assertNotNull; | |||
import static org.junit.Assert.assertNull; | |||
import static org.junit.Assert.assertTrue; | |||
@@ -42,7 +43,23 @@ public class InitCommandTest extends RepositoryTestCase { | |||
InitCommand command = new InitCommand(); | |||
command.setDirectory(directory); | |||
try (Git git = command.call()) { | |||
assertNotNull(git.getRepository()); | |||
Repository r = git.getRepository(); | |||
assertNotNull(r); | |||
assertEquals("refs/heads/master", r.getFullBranch()); | |||
} | |||
} | |||
@Test | |||
public void testInitRepositoryMainInitialBranch() | |||
throws IOException, JGitInternalException, GitAPIException { | |||
File directory = createTempDirectory("testInitRepository"); | |||
InitCommand command = new InitCommand(); | |||
command.setDirectory(directory); | |||
command.setInitialBranch("main"); | |||
try (Git git = command.call()) { | |||
Repository r = git.getRepository(); | |||
assertNotNull(r); | |||
assertEquals("refs/heads/main", r.getFullBranch()); | |||
} | |||
} | |||
@@ -72,6 +89,23 @@ public class InitCommandTest extends RepositoryTestCase { | |||
Repository repository = git.getRepository(); | |||
assertNotNull(repository); | |||
assertTrue(repository.isBare()); | |||
assertEquals("refs/heads/master", repository.getFullBranch()); | |||
} | |||
} | |||
@Test | |||
public void testInitBareRepositoryMainInitialBranch() | |||
throws IOException, JGitInternalException, GitAPIException { | |||
File directory = createTempDirectory("testInitBareRepository"); | |||
InitCommand command = new InitCommand(); | |||
command.setDirectory(directory); | |||
command.setBare(true); | |||
command.setInitialBranch("main"); | |||
try (Git git = command.call()) { | |||
Repository repository = git.getRepository(); | |||
assertNotNull(repository); | |||
assertTrue(repository.isBare()); | |||
assertEquals("refs/heads/main", repository.getFullBranch()); | |||
} | |||
} | |||
@@ -15,6 +15,7 @@ import java.text.MessageFormat; | |||
import java.util.concurrent.Callable; | |||
import org.eclipse.jgit.api.errors.GitAPIException; | |||
import org.eclipse.jgit.api.errors.InvalidRefNameException; | |||
import org.eclipse.jgit.api.errors.JGitInternalException; | |||
import org.eclipse.jgit.internal.JGitText; | |||
import org.eclipse.jgit.lib.Constants; | |||
@@ -38,6 +39,8 @@ public class InitCommand implements Callable<Git> { | |||
private FS fs; | |||
private String initialBranch = Constants.MASTER; | |||
/** | |||
* {@inheritDoc} | |||
* <p> | |||
@@ -87,6 +90,7 @@ public class InitCommand implements Callable<Git> { | |||
builder.setWorkTree(new File(dStr)); | |||
} | |||
} | |||
builder.setInitialBranch(initialBranch); | |||
Repository repository = builder.build(); | |||
if (!repository.getObjectDatabase().exists()) | |||
repository.create(bare); | |||
@@ -184,4 +188,23 @@ public class InitCommand implements Callable<Git> { | |||
this.fs = fs; | |||
return this; | |||
} | |||
/** | |||
* Set the initial branch of the new repository. If not specified | |||
* ({@code null} or empty), fall back to the default name (currently | |||
* master). | |||
* | |||
* @param branch | |||
* initial branch name of the new repository | |||
* @return {@code this} | |||
* @throws InvalidRefNameException | |||
* if the branch name is not valid | |||
* | |||
* @since 5.11 | |||
*/ | |||
public InitCommand setInitialBranch(String branch) | |||
throws InvalidRefNameException { | |||
this.initialBranch = branch; | |||
return this; | |||
} | |||
} |
@@ -243,7 +243,7 @@ public class FileRepository extends Repository { | |||
RefUpdate head = updateRef(Constants.HEAD); | |||
head.disableRefLog(); | |||
head.link(Constants.R_HEADS + Constants.MASTER); | |||
head.link(Constants.R_HEADS + getInitialBranch()); | |||
final boolean fileMode; | |||
if (getFS().supportsExecute()) { |
@@ -28,6 +28,8 @@ import java.util.Collection; | |||
import java.util.LinkedList; | |||
import java.util.List; | |||
import org.eclipse.jgit.annotations.NonNull; | |||
import org.eclipse.jgit.api.errors.InvalidRefNameException; | |||
import org.eclipse.jgit.errors.ConfigInvalidException; | |||
import org.eclipse.jgit.errors.RepositoryNotFoundException; | |||
import org.eclipse.jgit.internal.JGitText; | |||
@@ -38,6 +40,7 @@ import org.eclipse.jgit.storage.file.FileRepositoryBuilder; | |||
import org.eclipse.jgit.util.FS; | |||
import org.eclipse.jgit.util.IO; | |||
import org.eclipse.jgit.util.RawParseUtils; | |||
import org.eclipse.jgit.util.StringUtils; | |||
import org.eclipse.jgit.util.SystemReader; | |||
/** | |||
@@ -107,6 +110,8 @@ public class BaseRepositoryBuilder<B extends BaseRepositoryBuilder, R extends Re | |||
private File workTree; | |||
private String initialBranch = Constants.MASTER; | |||
/** Directories limiting the search for a Git repository. */ | |||
private List<File> ceilingDirectories; | |||
@@ -349,6 +354,43 @@ public class BaseRepositoryBuilder<B extends BaseRepositoryBuilder, R extends Re | |||
return indexFile; | |||
} | |||
/** | |||
* Set the initial branch of the new repository. If not specified | |||
* ({@code null} or empty), fall back to the default name (currently | |||
* master). | |||
* | |||
* @param branch | |||
* initial branch name of the new repository. If {@code null} or | |||
* empty the configured default branch will be used. | |||
* @return {@code this} | |||
* @throws InvalidRefNameException | |||
* if the branch name is not valid | |||
* | |||
* @since 5.11 | |||
*/ | |||
public B setInitialBranch(String branch) throws InvalidRefNameException { | |||
if (StringUtils.isEmptyOrNull(branch)) { | |||
this.initialBranch = Constants.MASTER; | |||
} else { | |||
if (!Repository.isValidRefName(Constants.R_HEADS + branch)) { | |||
throw new InvalidRefNameException(MessageFormat | |||
.format(JGitText.get().branchNameInvalid, branch)); | |||
} | |||
this.initialBranch = branch; | |||
} | |||
return self(); | |||
} | |||
/** | |||
* Get the initial branch of the new repository. | |||
* | |||
* @return the initial branch of the new repository. | |||
* @since 5.11 | |||
*/ | |||
public @NonNull String getInitialBranch() { | |||
return initialBranch; | |||
} | |||
/** | |||
* Read standard Git environment variables and configure from those. | |||
* <p> |
@@ -127,6 +127,8 @@ public abstract class Repository implements AutoCloseable { | |||
/** If not bare, the index file caching the working file states. */ | |||
private final File indexFile; | |||
private final String initialBranch; | |||
/** | |||
* Initialize a new repository instance. | |||
* | |||
@@ -138,6 +140,7 @@ public abstract class Repository implements AutoCloseable { | |||
fs = options.getFS(); | |||
workTree = options.getWorkTree(); | |||
indexFile = options.getIndexFile(); | |||
initialBranch = options.getInitialBranch(); | |||
} | |||
/** | |||
@@ -1033,6 +1036,16 @@ public abstract class Repository implements AutoCloseable { | |||
return null; | |||
} | |||
/** | |||
* Get the initial branch name of a new repository | |||
* | |||
* @return the initial branch name of a new repository | |||
* @since 5.11 | |||
*/ | |||
protected @NonNull String getInitialBranch() { | |||
return initialBranch; | |||
} | |||
/** | |||
* Objects known to exist but not expressed by {@link #getAllRefs()}. | |||
* <p> |