aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJonathan Nieder2013-11-01 23:28:58 (EDT)
committerJonathan Nieder2013-12-27 12:02:53 (EST)
commit8a4cf2e0f8e3b02de7f925e8cb831780a8206c0b (patch)
treec5e4419fa2f59073d06887f107a07ccc7860d2cf
parent2ecc27db9297e0dd9f4113699deeadd575731106 (diff)
downloadjgit-8a4cf2e0f8e3b02de7f925e8cb831780a8206c0b.zip
jgit-8a4cf2e0f8e3b02de7f925e8cb831780a8206c0b.tar.gz
jgit-8a4cf2e0f8e3b02de7f925e8cb831780a8206c0b.tar.bz2
archive: Use an empty directory for submodulesrefs/changes/49/17949/7
When encountering a submodule entry, "jgit archive" tries to write its content verbatim as an entry to the archive, which fails with a JGitInternalException wrapping a MissingObjectException because the submodule repository commits are typically not part of the superproject. When a subproject is available (for example because it has been checked out as a subdirectory of a superproject worktree), it would be nice to recurse into it and make one archive recording the state of the entire project. Unfortunately sometimes the subproject is not available or it can be hard to find (e.g., it can be on another server). Even when some subprojects are available, "jgit archive" should not produce different output for the same tree depending on which subprojects it has easy access to, so there is no obvious good default behavior that recurses without relying on access to all subprojects. Instead, replace each submodule entry with a placeholder empty directory. "git archive" does the same. Change-Id: I1295086037b77fc948b3f93c21d47341e25483e5 Signed-off-by: Jonathan Nieder <jrn@google.com>
-rw-r--r--org.eclipse.jgit.pgm.test/tst/org/eclipse/jgit/pgm/ArchiveTest.java40
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/api/ArchiveCommand.java13
2 files changed, 50 insertions, 3 deletions
diff --git a/org.eclipse.jgit.pgm.test/tst/org/eclipse/jgit/pgm/ArchiveTest.java b/org.eclipse.jgit.pgm.test/tst/org/eclipse/jgit/pgm/ArchiveTest.java
index 30f875c..cf22ca2 100644
--- a/org.eclipse.jgit.pgm.test/tst/org/eclipse/jgit/pgm/ArchiveTest.java
+++ b/org.eclipse.jgit.pgm.test/tst/org/eclipse/jgit/pgm/ArchiveTest.java
@@ -433,6 +433,46 @@ public class ArchiveTest extends CLIRepositoryTestCase {
}
@Test
+ public void testArchiveIncludesSubmoduleDirectory() throws Exception {
+ writeTrashFile("a", "a file with content!");
+ writeTrashFile("c", "after submodule");
+ git.add().addFilepattern("a").call();
+ git.add().addFilepattern("c").call();
+ git.commit().setMessage("initial commit").call();
+ git.submoduleAdd().setURI("./.").setPath("b").call().close();
+ git.commit().setMessage("add submodule").call();
+
+ final byte[] result = CLIGitCommand.rawExecute( //
+ "git archive --format=zip master", db);
+ String[] expect = { ".gitmodules", "a", "b/", "c" };
+ String[] actual = listZipEntries(result);
+
+ Arrays.sort(expect);
+ Arrays.sort(actual);
+ assertArrayEquals(expect, actual);
+ }
+
+ @Test
+ public void testTarIncludesSubmoduleDirectory() throws Exception {
+ writeTrashFile("a", "a file with content!");
+ writeTrashFile("c", "after submodule");
+ git.add().addFilepattern("a").call();
+ git.add().addFilepattern("c").call();
+ git.commit().setMessage("initial commit").call();
+ git.submoduleAdd().setURI("./.").setPath("b").call().close();
+ git.commit().setMessage("add submodule").call();
+
+ final byte[] result = CLIGitCommand.rawExecute( //
+ "git archive --format=tar master", db);
+ String[] expect = { ".gitmodules", "a", "b/", "c" };
+ String[] actual = listTarEntries(result);
+
+ Arrays.sort(expect);
+ Arrays.sort(actual);
+ assertArrayEquals(expect, actual);
+ }
+
+ @Test
public void testArchivePreservesMode() throws Exception {
writeTrashFile("plain", "a file with content");
writeTrashFile("executable", "an executable file");
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/ArchiveCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/ArchiveCommand.java
index 2e6b50a..ed91ae2 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/ArchiveCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/ArchiveCommand.java
@@ -279,11 +279,18 @@ public class ArchiveCommand extends GitCommand<OutputStream> {
walk.reset(rw.parseTree(tree));
while (walk.next()) {
final String name = pfx + walk.getPathString();
- final FileMode mode = walk.getFileMode(0);
+ FileMode mode = walk.getFileMode(0);
- if (walk.isSubtree()) {
- fmt.putEntry(outa, name + "/", mode, null);
+ if (walk.isSubtree())
walk.enterSubtree();
+
+ if (mode == FileMode.GITLINK)
+ // TODO(jrn): Take a callback to recurse
+ // into submodules.
+ mode = FileMode.TREE;
+
+ if (mode == FileMode.TREE) {
+ fmt.putEntry(outa, name + "/", mode, null);
continue;
}
walk.getObjectId(idBuf, 0);