Attempts to write entries with too-long filenames currently error out: $ jgit.pgm/target/jgit archive HEAD >test.tar java.lang.RuntimeException: file name 'org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/resolver/DefaultReceivePackFactory.java' is too long ( > 100 bytes) at org.apache.commons.compress.archivers.tar.TarArchiveOutputStream.putArchiveEntry(TarArchiveOutputStream.java:288) at org.eclipse.jgit.archive.TarFormat.putEntry(TarFormat.java:92) at org.eclipse.jgit.archive.TarFormat.putEntry(TarFormat.java:62) at org.eclipse.jgit.api.ArchiveCommand.writeArchive(ArchiveCommand.java:293) at org.eclipse.jgit.api.ArchiveCommand.call(ArchiveCommand.java:322) at org.eclipse.jgit.pgm.Archive.run(Archive.java:97) at org.eclipse.jgit.pgm.TextBuiltin.execute(TextBuiltin.java:174) at org.eclipse.jgit.pgm.Main.execute(Main.java:213) at org.eclipse.jgit.pgm.Main.run(Main.java:121) at org.eclipse.jgit.pgm.Main.main(Main.java:95) That's because the default longFileMode is LONGFILE_ERROR, which throws an exception for filenames longer than 100 characters. Switch to LONGFILE_POSIX. While at it, handle large files and filenames with strange encodings, too. This requires commons compress 1.4, which introduced support for large files and POSIX long filenames. Change-Id: I04d5427eec0968b129f55d7a4c6021039a494828tags/v3.1.0.201309270735-rc1
Bundle-Vendor: %provider_name | Bundle-Vendor: %provider_name | ||||
Bundle-Localization: plugin | Bundle-Localization: plugin | ||||
Bundle-RequiredExecutionEnvironment: J2SE-1.5 | Bundle-RequiredExecutionEnvironment: J2SE-1.5 | ||||
Import-Package: org.apache.commons.compress.archivers;version="[1.3,2.0)", | |||||
org.apache.commons.compress.archivers.tar;version="[1.3,2.0)", | |||||
org.apache.commons.compress.archivers.zip;version="[1.3,2.0)", | |||||
org.apache.commons.compress.compressors.bzip2;version="[1.3,2.0)", | |||||
org.apache.commons.compress.compressors.gzip;version="[1.3,2.0)", | |||||
org.apache.commons.compress.compressors.xz;version="[1.3,2.0)", | |||||
Import-Package: org.apache.commons.compress.archivers;version="[1.4,2.0)", | |||||
org.apache.commons.compress.archivers.tar;version="[1.4,2.0)", | |||||
org.apache.commons.compress.archivers.zip;version="[1.4,2.0)", | |||||
org.apache.commons.compress.compressors.bzip2;version="[1.4,2.0)", | |||||
org.apache.commons.compress.compressors.gzip;version="[1.4,2.0)", | |||||
org.apache.commons.compress.compressors.xz;version="[1.4,2.0)", | |||||
org.eclipse.jgit.api;version="[3.0.0,3.1.0)", | org.eclipse.jgit.api;version="[3.0.0,3.1.0)", | ||||
org.eclipse.jgit.lib;version="[3.0.0,3.1.0)", | org.eclipse.jgit.lib;version="[3.0.0,3.1.0)", | ||||
org.osgi.framework;version="[1.3.0,2.0.0)" | org.osgi.framework;version="[1.3.0,2.0.0)" |
import org.eclipse.jgit.lib.ObjectLoader; | import org.eclipse.jgit.lib.ObjectLoader; | ||||
/** | /** | ||||
* Unix TAR format (ustar + old GNU long filename extension). | |||||
* Unix TAR format (ustar + some PAX extensions). | |||||
*/ | */ | ||||
public class TarFormat implements ArchiveCommand.Format<ArchiveOutputStream> { | public class TarFormat implements ArchiveCommand.Format<ArchiveOutputStream> { | ||||
public ArchiveOutputStream createArchiveOutputStream(OutputStream s) { | public ArchiveOutputStream createArchiveOutputStream(OutputStream s) { | ||||
return new TarArchiveOutputStream(s); | |||||
TarArchiveOutputStream out = new TarArchiveOutputStream(s, "UTF-8"); //$NON-NLS-1$ | |||||
out.setLongFileMode(TarArchiveOutputStream.LONGFILE_POSIX); | |||||
out.setBigNumberMode(TarArchiveOutputStream.BIGNUMBER_POSIX); | |||||
return out; | |||||
} | } | ||||
public void putEntry(ArchiveOutputStream out, | public void putEntry(ArchiveOutputStream out, |
assertTarContainsEntry("with-modes.tar", "l", "symlink -> plain"); | assertTarContainsEntry("with-modes.tar", "l", "symlink -> plain"); | ||||
} | } | ||||
@Test | |||||
public void testArchiveWithLongFilename() throws Exception { | |||||
String filename = "1234567890"; | |||||
for (int i = 0; i < 20; i++) | |||||
filename = filename + "/1234567890"; | |||||
writeTrashFile(filename, "file with long path"); | |||||
git.add().addFilepattern("1234567890").call(); | |||||
git.commit().setMessage("file with long name").call(); | |||||
final byte[] result = CLIGitCommand.rawExecute( // | |||||
"git archive HEAD", db); | |||||
assertArrayEquals(new String[] { filename }, | |||||
listZipEntries(result)); | |||||
} | |||||
@Test | |||||
public void testTarWithLongFilename() throws Exception { | |||||
String filename = "1234567890"; | |||||
for (int i = 0; i < 20; i++) | |||||
filename = filename + "/1234567890"; | |||||
writeTrashFile(filename, "file with long path"); | |||||
git.add().addFilepattern("1234567890").call(); | |||||
git.commit().setMessage("file with long name").call(); | |||||
final byte[] result = CLIGitCommand.rawExecute( // | |||||
"git archive --format=tar HEAD", db); | |||||
assertArrayEquals(new String[] { filename }, | |||||
listTarEntries(result)); | |||||
} | |||||
@Test | @Test | ||||
public void testArchivePreservesContent() throws Exception { | public void testArchivePreservesContent() throws Exception { | ||||
final String payload = "“The quick brown fox jumps over the lazy dog!”"; | final String payload = "“The quick brown fox jumps over the lazy dog!”"; |