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");
private OutputStream out;
private ObjectId tree;
+ private String prefix;
private String format;
/** Filename suffix, for automatically choosing a format. */
}
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);
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)
return this;
}
+ /**
+ * @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