diff --git a/org.eclipse.jgit.pgm/resources/org/eclipse/jgit/pgm/internal/CLIText.properties b/org.eclipse.jgit.pgm/resources/org/eclipse/jgit/pgm/internal/CLIText.properties index f7591fd80..64afdad51 100644 --- a/org.eclipse.jgit.pgm/resources/org/eclipse/jgit/pgm/internal/CLIText.properties +++ b/org.eclipse.jgit.pgm/resources/org/eclipse/jgit/pgm/internal/CLIText.properties @@ -192,6 +192,7 @@ untrackedFiles=Untracked files: updating=Updating {0}..{1} usage_Aggressive=This option will cause gc to more aggressively optimize the repository at the expense of taking much more time usage_bareClone=Make a bare Git repository. That is, instead of creating [DIRECTORY] and placing the administrative files in [DIRECTORY]/.git, make the [DIRECTORY] itself the $GIT_DIR. +usage_branches=Set branch field in .gitmodules usage_Blame=Show what revision and author last modified each line usage_CommandLineClientForamazonsS3Service=Command line client for Amazon's S3 service usage_CommitAll=commit all modified and deleted files diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Repo.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Repo.java index 9b191e679..db88008e1 100644 --- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Repo.java +++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Repo.java @@ -58,12 +58,16 @@ class Repo extends TextBuiltin { @Argument(required = true, usage = "usage_pathToXml") private String path; + @Option(name = "--record-remote-branch", usage = "usage_branches") + private boolean branches; + @Override protected void run() throws Exception { new RepoCommand(db) .setURI(uri) .setPath(path) .setGroups(groups) + .setRecordRemoteBranch(branches) .call(); } } diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/gitrepo/RepoCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/gitrepo/RepoCommandTest.java index 66e725643..c6c7ea0eb 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/gitrepo/RepoCommandTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/gitrepo/RepoCommandTest.java @@ -56,6 +56,8 @@ import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.lib.Repository; +import org.eclipse.jgit.storage.file.FileBasedConfig; +import org.eclipse.jgit.util.FS; import org.junit.Test; public class RepoCommandTest extends RepositoryTestCase { @@ -692,6 +694,49 @@ public void testTargetBranch() throws Exception { } } + @Test + public void testRecordRemoteBranch() throws Exception { + try ( + Repository remoteDb = createBareRepository(); + Repository tempDb = createWorkRepository()) { + StringBuilder xmlContent = new StringBuilder(); + xmlContent + .append("\n") + .append("") + .append("") + .append("") + .append("") + .append("") + .append(""); + JGitTestUtil.writeTrashFile(tempDb, "manifest.xml", + xmlContent.toString()); + + RepoCommand command = new RepoCommand(remoteDb); + command.setPath(tempDb.getWorkTree().getAbsolutePath() + "/manifest.xml") + .setURI(rootUri) + .setRecordRemoteBranch(true) + .call(); + // Clone it + File directory = createTempDirectory("testBareRepo"); + Repository localDb = Git.cloneRepository().setDirectory(directory) + .setURI(remoteDb.getDirectory().toURI().toString()).call() + .getRepository(); + // The .gitmodules file should exist + File gitmodules = new File(localDb.getWorkTree(), ".gitmodules"); + assertTrue("The .gitmodules file should exist", gitmodules.exists()); + FileBasedConfig c = new FileBasedConfig(gitmodules, FS.DETECTED); + c.load(); + assertEquals("standard branches work", "master", + c.getString("submodule", "with-branch", "branch")); + assertEquals("long branches work", "refs/heads/master", + c.getString("submodule", "with-long-branch", "branch")); + } + } + private void resolveRelativeUris() { // Find the longest common prefix ends with "/" as rootUri. defaultUri = defaultDb.getDirectory().toURI().toString(); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/RepoCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/RepoCommand.java index 790f4db67..d298331f5 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/RepoCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/RepoCommand.java @@ -106,6 +106,7 @@ public class RepoCommand extends GitCommand { private String groups; private String branch; private String targetBranch = Constants.HEAD; + private boolean recordRemoteBranch = false; private PersonIdent author; private RemoteReader callback; private InputStream inputStream; @@ -313,6 +314,30 @@ public RepoCommand setTargetBranch(String branch) { return this; } + /** + * Set whether the branch name should be recorded in .gitmodules + *

+ * Submodule entries in .gitmodules can include a "branch" field + * to indicate what remote branch each submodule tracks. + *

+ * That field is used by "git submodule update --remote" to update + * to the tip of the tracked branch when asked and by Gerrit to + * update the superproject when a change on that branch is merged. + *

+ * Subprojects that request a specific commit or tag will not have + * a branch name recorded. + *

+ * Not implemented for non-bare repositories. + * + * @param record Whether to record the branch name + * @return this command + * @since 4.2 + */ + public RepoCommand setRecordRemoteBranch(boolean update) { + this.recordRemoteBranch = update; + return this; + } + /** * The progress monitor associated with the clone operation. By default, * this is set to NullProgressMonitor @@ -429,10 +454,14 @@ public RevCommit call() throws GitAPIException { // create gitlink DirCacheEntry dcEntry = new DirCacheEntry(name); ObjectId objectId; - if (ObjectId.isId(proj.getRevision())) + if (ObjectId.isId(proj.getRevision())) { objectId = ObjectId.fromString(proj.getRevision()); - else { + } else { objectId = callback.sha1(nameUri, proj.getRevision()); + if (recordRemoteBranch) + // can be branch or tag + cfg.setString("submodule", name, "branch", //$NON-NLS-1$ //$NON-NLS-2$ + proj.getRevision()); } if (objectId == null) throw new RemoteUnavailableException(nameUri);