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 d12e5fc0e..80a0250de 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 @@ -44,6 +44,7 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import java.io.BufferedReader; @@ -800,6 +801,53 @@ public void testRecordSubmoduleLabels() throws Exception { } } + @Test + public void testRecordShallowRecommendation() 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) + .setRecommendShallow(true) + .call(); + // Clone it + File directory = createTempDirectory("testBareRepo"); + try (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("Recording shallow configuration should work", "true", + c.getString("submodule", "shallow-please", "shallow")); + assertNull("Recording non shallow configuration should work", + c.getString("submodule", "non-shallow", "shallow")); + } + } + } + @Test public void testRemoteRevision() throws Exception { StringBuilder xmlContent = new StringBuilder(); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/ManifestParser.java b/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/ManifestParser.java index 796b422bb..2370ae14c 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/ManifestParser.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/ManifestParser.java @@ -192,6 +192,8 @@ public void startElement( attributes.getValue("revision"), //$NON-NLS-1$ attributes.getValue("remote"), //$NON-NLS-1$ attributes.getValue("groups")); //$NON-NLS-1$ + currentProject.setRecommendShallow( + attributes.getValue("clone-depth")); //$NON-NLS-1$ } else if ("remote".equals(qName)) { //$NON-NLS-1$ String alias = attributes.getValue("alias"); //$NON-NLS-1$ String fetch = attributes.getValue("fetch"); //$NON-NLS-1$ 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 6f682ee98..ef634f3d6 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/RepoCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/RepoCommand.java @@ -113,6 +113,7 @@ public class RepoCommand extends GitCommand { private String targetBranch = Constants.HEAD; private boolean recordRemoteBranch = false; private boolean recordSubmoduleLabels = false; + private boolean recordShallowSubmodules = false; private PersonIdent author; private RemoteReader callback; private InputStream inputStream; @@ -362,6 +363,21 @@ public RepoCommand setRecordSubmoduleLabels(boolean enable) { return this; } + /** + * Set whether the clone-depth field should be recorded as a shallow + * recommendation in .gitmodules. + *

+ * Not implemented for non-bare repositories. + * + * @param enable Whether to record the shallow recommendation. + * @return this command + * @since 4.4 + */ + public RepoCommand setRecommendShallow(boolean enable) { + this.recordShallowSubmodules = enable; + return this; + } + /** * The progress monitor associated with the clone operation. By default, * this is set to NullProgressMonitor @@ -471,7 +487,8 @@ public RevCommit call() throws GitAPIException { proj.getPath(), proj.getRevision(), proj.getCopyFiles(), - proj.getGroups()); + proj.getGroups(), + proj.getRecommendShallow()); } } catch (GitAPIException | IOException e) { throw new ManifestErrorException(e); @@ -512,6 +529,16 @@ public RevCommit call() throws GitAPIException { cfg.setString("submodule", name, "branch", //$NON-NLS-1$ //$NON-NLS-2$ proj.getRevision()); } + + if (recordShallowSubmodules && proj.getRecommendShallow() != null) { + // The shallow recommendation is losing information. + // As the repo manifests stores the recommended + // depth in the 'clone-depth' field, while + // git core only uses a binary 'shallow = true/false' + // hint, we'll map any depth to 'shallow = true' + cfg.setBoolean("submodule", name, "shallow", //$NON-NLS-1$ //$NON-NLS-2$ + true); + } } if (recordSubmoduleLabels) { StringBuilder rec = new StringBuilder(); @@ -616,10 +643,10 @@ public RevCommit call() throws GitAPIException { } private void addSubmodule(String url, String name, String revision, - List copyfiles, Set groups) + List copyfiles, Set groups, String recommendShallow) throws GitAPIException, IOException { if (repo.isBare()) { - RepoProject proj = new RepoProject(url, name, revision, null, groups); + RepoProject proj = new RepoProject(url, name, revision, null, groups, recommendShallow); proj.addCopyFiles(copyfiles); bareProjects.add(proj); } else { diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/RepoProject.java b/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/RepoProject.java index 1b251368d..bcc7ffc21 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/RepoProject.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/RepoProject.java @@ -70,6 +70,7 @@ public class RepoProject implements Comparable { private final String remote; private final Set groups; private final List copyfiles; + private String recommendShallow; private String url; private String defaultRevision; @@ -138,7 +139,8 @@ public void copy() throws IOException { * @since 4.4 */ public RepoProject(String name, String path, String revision, - String remote, Set groups) { + String remote, Set groups, + String recommendShallow) { if (name == null) { throw new NullPointerException(); } @@ -150,6 +152,7 @@ public RepoProject(String name, String path, String revision, this.revision = revision; this.remote = remote; this.groups = groups; + this.recommendShallow = recommendShallow; copyfiles = new ArrayList(); } @@ -167,7 +170,7 @@ public RepoProject(String name, String path, String revision, */ public RepoProject(String name, String path, String revision, String remote, String groups) { - this(name, path, revision, remote, new HashSet()); + this(name, path, revision, remote, new HashSet(), null); if (groups != null && groups.length() > 0) this.setGroups(groups); } @@ -281,6 +284,25 @@ public Set getGroups() { return groups; } + /** + * Return the recommendation for shallowness. + * + * @return the String of "clone-depth" + * @since 4.4 + */ + public String getRecommendShallow() { + return recommendShallow; + } + + /** + * Sets the recommendation for shallowness. + * + * @since 4.4 + */ + public void setRecommendShallow(String recommendShallow) { + this.recommendShallow = recommendShallow; + } + /** * Add a copy file configuration. *