diff options
5 files changed, 115 insertions, 1 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 87137b475f..816094aef9 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 @@ -338,6 +338,99 @@ public class ArchiveTest extends CLIRepositoryTestCase { assertArrayEquals(expect, actual); } + private void commitBazAndFooSlashBar() throws Exception { + writeTrashFile("baz", "a file"); + writeTrashFile("foo/bar", "another file"); + git.add().addFilepattern("baz").call(); + git.add().addFilepattern("foo").call(); + git.commit().setMessage("sample commit").call(); + } + + @Test + public void testArchivePrefixOption() throws Exception { + commitBazAndFooSlashBar(); + byte[] result = CLIGitCommand.rawExecute( + "git archive --prefix=x/ --format=zip master", db); + String[] expect = { "x/baz", "x/foo/bar" }; + String[] actual = listZipEntries(result); + + Arrays.sort(expect); + Arrays.sort(actual); + assertArrayEquals(expect, actual); + } + + @Test + public void testTarPrefixOption() throws Exception { + commitBazAndFooSlashBar(); + byte[] result = CLIGitCommand.rawExecute( + "git archive --prefix=x/ --format=tar master", db); + String[] expect = { "x/baz", "x/foo/bar" }; + String[] actual = listTarEntries(result); + + Arrays.sort(expect); + Arrays.sort(actual); + assertArrayEquals(expect, actual); + } + + private void commitFoo() throws Exception { + writeTrashFile("foo", "a file"); + git.add().addFilepattern("foo").call(); + git.commit().setMessage("boring commit").call(); + } + + @Test + public void testPrefixDoesNotNormalizeDoubleSlash() throws Exception { + commitFoo(); + byte[] result = CLIGitCommand.rawExecute( + "git archive --prefix=x// --format=zip master", db); + String[] expect = { "x//foo" }; + assertArrayEquals(expect, listZipEntries(result)); + } + + @Test + public void testPrefixDoesNotNormalizeDoubleSlashInTar() throws Exception { + commitFoo(); + final byte[] result = CLIGitCommand.rawExecute( // + "git archive --prefix=x// --format=tar master", db); + String[] expect = { "x//foo" }; + assertArrayEquals(expect, listTarEntries(result)); + } + + /** + * The prefix passed to "git archive" need not end with '/'. + * In practice it is not very common to have a nonempty prefix + * that does not name a directory (and hence end with /), but + * since git has historically supported other prefixes, we do, + * too. + * + * @throws Exception + */ + @Test + public void testPrefixWithoutTrailingSlash() throws Exception { + commitBazAndFooSlashBar(); + byte[] result = CLIGitCommand.rawExecute( + "git archive --prefix=my- --format=zip master", db); + String[] expect = { "my-baz", "my-foo/bar" }; + String[] actual = listZipEntries(result); + + Arrays.sort(expect); + Arrays.sort(actual); + assertArrayEquals(expect, actual); + } + + @Test + public void testTarPrefixWithoutTrailingSlash() throws Exception { + commitBazAndFooSlashBar(); + final byte[] result = CLIGitCommand.rawExecute( // + "git archive --prefix=my- --format=tar master", db); + String[] expect = { "my-baz", "my-foo/bar" }; + 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"); 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 d23f378993..1d2a8971f7 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 @@ -74,6 +74,7 @@ mergeWentWellStoppedBeforeCommitting=Automatic merge went well; stopped before c metaVar_DAG=DAG metaVar_KEY=KEY metaVar_archiveFormat=format +metaVar_archivePrefix=prefix/ metaVar_arg=ARG metaVar_author=AUTHOR metaVar_base=base @@ -229,6 +230,7 @@ usage_approveDestructionOfRepository=approve destruction of repository usage_archive=zip up files from the named tree usage_archiveFormat=archive format. Currently supported formats: 'tar', 'zip', 'tgz', 'tbz2', 'txz' usage_archiveOutput=output file to write the archive to +usage_archivePrefix=string to prepend to each pathname in the archive usage_blameLongRevision=show long revision usage_blameRange=annotate only the given range usage_blameRawTimestamp=show raw timestamp diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Archive.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Archive.java index 7b88a94345..80bb9ec9df 100644 --- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Archive.java +++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Archive.java @@ -69,6 +69,9 @@ class Archive extends TextBuiltin { @Option(name = "--format", metaVar = "metaVar_archiveFormat", usage = "usage_archiveFormat") private String format; + @Option(name = "--prefix", metaVar = "metaVar_archivePrefix", usage = "usage_archivePrefix") + private String prefix; + @Option(name = "--output", aliases = { "-o" }, metaVar = "metaVar_file", usage = "usage_archiveOutput") private String output; @@ -88,6 +91,7 @@ class Archive extends TextBuiltin { ArchiveCommand cmd = new Git(db).archive() .setTree(tree) .setFormat(format) + .setPrefix(prefix) .setOutputStream(stream); if (output != null) cmd.setFilename(output); diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/internal/CLIText.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/internal/CLIText.java index a51313ae1e..c42e5fb59d 100644 --- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/internal/CLIText.java +++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/internal/CLIText.java @@ -143,6 +143,7 @@ public class CLIText extends TranslationBundle { /***/ public String mergeWentWellStoppedBeforeCommitting; /***/ public String metaVar_KEY; /***/ public String metaVar_archiveFormat; + /***/ public String metaVar_archivePrefix; /***/ public String metaVar_arg; /***/ public String metaVar_author; /***/ public String metaVar_bucket; 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 42d0f6512d..c17330e6f1 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/ArchiveCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/ArchiveCommand.java @@ -250,6 +250,7 @@ public class ArchiveCommand extends GitCommand<OutputStream> { private OutputStream out; private ObjectId tree; + private String prefix; private String format; /** Filename suffix, for automatically choosing a format. */ @@ -264,6 +265,7 @@ public class ArchiveCommand extends GitCommand<OutputStream> { } private <T extends Closeable> OutputStream writeArchive(Format<T> fmt) { + final String pfx = prefix == null ? "" : prefix; final TreeWalk walk = new TreeWalk(repo); try { final T outa = fmt.createArchiveOutputStream(out); @@ -275,7 +277,7 @@ public class ArchiveCommand extends GitCommand<OutputStream> { walk.reset(rw.parseTree(tree)); walk.setRecursive(true); while (walk.next()) { - final String name = walk.getPathString(); + final String name = pfx + walk.getPathString(); final FileMode mode = walk.getFileMode(0); if (mode == FileMode.TREE) @@ -330,6 +332,18 @@ public class ArchiveCommand extends GitCommand<OutputStream> { } /** + * @param prefix + * string prefixed to filenames in archive (e.g., "master/"). + * null means to not use any leading prefix. + * @return this + * @since 3.3 + */ + public ArchiveCommand setPrefix(String prefix) { + this.prefix = prefix; + return this; + } + + /** * Set the intended filename for the produced archive. Currently the only * effect is to determine the default archive format when none is specified * with {@link #setFormat(String)}. |