|
|
@@ -46,20 +46,44 @@ import static org.junit.Assert.assertEquals; |
|
|
|
import static org.junit.Assert.assertNull; |
|
|
|
|
|
|
|
import java.beans.Statement; |
|
|
|
import java.io.BufferedInputStream; |
|
|
|
import java.io.File; |
|
|
|
import java.io.FileNotFoundException; |
|
|
|
import java.io.FileOutputStream; |
|
|
|
import java.io.IOException; |
|
|
|
import java.io.InputStream; |
|
|
|
import java.io.OutputStream; |
|
|
|
import java.nio.file.Files; |
|
|
|
import java.util.Arrays; |
|
|
|
import java.util.Collections; |
|
|
|
import java.util.HashMap; |
|
|
|
import java.util.List; |
|
|
|
import java.util.Map; |
|
|
|
|
|
|
|
import org.apache.commons.compress.archivers.ArchiveEntry; |
|
|
|
import org.apache.commons.compress.archivers.ArchiveInputStream; |
|
|
|
import org.apache.commons.compress.archivers.tar.TarArchiveInputStream; |
|
|
|
import org.apache.commons.compress.archivers.zip.ZipArchiveInputStream; |
|
|
|
import org.apache.commons.compress.compressors.bzip2.BZip2CompressorInputStream; |
|
|
|
import org.apache.commons.compress.compressors.gzip.GzipCompressorInputStream; |
|
|
|
import org.apache.commons.compress.compressors.xz.XZCompressorInputStream; |
|
|
|
import org.eclipse.jgit.api.errors.AbortedByHookException; |
|
|
|
import org.eclipse.jgit.api.errors.ConcurrentRefUpdateException; |
|
|
|
import org.eclipse.jgit.api.errors.GitAPIException; |
|
|
|
import org.eclipse.jgit.api.errors.NoFilepatternException; |
|
|
|
import org.eclipse.jgit.api.errors.NoHeadException; |
|
|
|
import org.eclipse.jgit.api.errors.NoMessageException; |
|
|
|
import org.eclipse.jgit.api.errors.UnmergedPathsException; |
|
|
|
import org.eclipse.jgit.api.errors.WrongRepositoryStateException; |
|
|
|
import org.eclipse.jgit.archive.ArchiveFormats; |
|
|
|
import org.eclipse.jgit.errors.AmbiguousObjectException; |
|
|
|
import org.eclipse.jgit.errors.IncorrectObjectTypeException; |
|
|
|
import org.eclipse.jgit.junit.RepositoryTestCase; |
|
|
|
import org.eclipse.jgit.lib.FileMode; |
|
|
|
import org.eclipse.jgit.lib.ObjectId; |
|
|
|
import org.eclipse.jgit.lib.ObjectLoader; |
|
|
|
import org.eclipse.jgit.revwalk.RevCommit; |
|
|
|
import org.eclipse.jgit.util.IO; |
|
|
|
import org.eclipse.jgit.util.StringUtils; |
|
|
|
import org.junit.After; |
|
|
|
import org.junit.Before; |
|
|
@@ -67,9 +91,14 @@ import org.junit.Test; |
|
|
|
|
|
|
|
public class ArchiveCommandTest extends RepositoryTestCase { |
|
|
|
|
|
|
|
// archives store timestamp with 1 second resolution |
|
|
|
private static final int WAIT = 2000; |
|
|
|
private static final String UNEXPECTED_ARCHIVE_SIZE = "Unexpected archive size"; |
|
|
|
private static final String UNEXPECTED_FILE_CONTENTS = "Unexpected file contents"; |
|
|
|
private static final String UNEXPECTED_TREE_CONTENTS = "Unexpected tree contents"; |
|
|
|
private static final String UNEXPECTED_LAST_MODIFIED = |
|
|
|
"Unexpected lastModified mocked by MockSystemReader, truncated to 1 second"; |
|
|
|
private static final String UNEXPECTED_DIFFERENT_HASH = "Unexpected different hash"; |
|
|
|
|
|
|
|
private MockFormat format = null; |
|
|
|
|
|
|
@@ -77,25 +106,20 @@ public class ArchiveCommandTest extends RepositoryTestCase { |
|
|
|
public void setup() { |
|
|
|
format = new MockFormat(); |
|
|
|
ArchiveCommand.registerFormat(format.SUFFIXES.get(0), format); |
|
|
|
ArchiveFormats.registerAll(); |
|
|
|
} |
|
|
|
|
|
|
|
@Override |
|
|
|
@After |
|
|
|
public void tearDown() { |
|
|
|
ArchiveCommand.unregisterFormat(format.SUFFIXES.get(0)); |
|
|
|
ArchiveFormats.unregisterAll(); |
|
|
|
} |
|
|
|
|
|
|
|
@Test |
|
|
|
public void archiveHeadAllFiles() throws IOException, GitAPIException { |
|
|
|
try (Git git = new Git(db)) { |
|
|
|
writeTrashFile("file_1.txt", "content_1_1"); |
|
|
|
git.add().addFilepattern("file_1.txt").call(); |
|
|
|
git.commit().setMessage("create file").call(); |
|
|
|
|
|
|
|
writeTrashFile("file_1.txt", "content_1_2"); |
|
|
|
writeTrashFile("file_2.txt", "content_2_2"); |
|
|
|
git.add().addFilepattern(".").call(); |
|
|
|
git.commit().setMessage("updated file").call(); |
|
|
|
createTestContent(git); |
|
|
|
|
|
|
|
git.archive().setOutputStream(new MockOutputStream()) |
|
|
|
.setFormat(format.SUFFIXES.get(0)) |
|
|
@@ -190,6 +214,157 @@ public class ArchiveCommandTest extends RepositoryTestCase { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
@Test |
|
|
|
public void archiveHeadAllFilesTarTimestamps() throws Exception { |
|
|
|
try (Git git = new Git(db)) { |
|
|
|
createTestContent(git); |
|
|
|
String fmt = "tar"; |
|
|
|
File archive = new File(getTemporaryDirectory(), |
|
|
|
"archive." + format); |
|
|
|
archive(git, archive, fmt); |
|
|
|
ObjectId hash1 = ObjectId.fromRaw(IO.readFully(archive)); |
|
|
|
|
|
|
|
try (InputStream fi = Files.newInputStream(archive.toPath()); |
|
|
|
InputStream bi = new BufferedInputStream(fi); |
|
|
|
ArchiveInputStream o = new TarArchiveInputStream(bi)) { |
|
|
|
assertEntries(o); |
|
|
|
} |
|
|
|
|
|
|
|
Thread.sleep(WAIT); |
|
|
|
archive(git, archive, fmt); |
|
|
|
assertEquals(UNEXPECTED_DIFFERENT_HASH, hash1, |
|
|
|
ObjectId.fromRaw(IO.readFully(archive))); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
@Test |
|
|
|
public void archiveHeadAllFilesTgzTimestamps() throws Exception { |
|
|
|
try (Git git = new Git(db)) { |
|
|
|
createTestContent(git); |
|
|
|
String fmt = "tgz"; |
|
|
|
File archive = new File(getTemporaryDirectory(), |
|
|
|
"archive." + fmt); |
|
|
|
archive(git, archive, fmt); |
|
|
|
ObjectId hash1 = ObjectId.fromRaw(IO.readFully(archive)); |
|
|
|
|
|
|
|
try (InputStream fi = Files.newInputStream(archive.toPath()); |
|
|
|
InputStream bi = new BufferedInputStream(fi); |
|
|
|
InputStream gzi = new GzipCompressorInputStream(bi); |
|
|
|
ArchiveInputStream o = new TarArchiveInputStream(gzi)) { |
|
|
|
assertEntries(o); |
|
|
|
} |
|
|
|
|
|
|
|
Thread.sleep(WAIT); |
|
|
|
archive(git, archive, fmt); |
|
|
|
assertEquals(UNEXPECTED_DIFFERENT_HASH, hash1, |
|
|
|
ObjectId.fromRaw(IO.readFully(archive))); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
@Test |
|
|
|
public void archiveHeadAllFilesTbz2Timestamps() throws Exception { |
|
|
|
try (Git git = new Git(db)) { |
|
|
|
createTestContent(git); |
|
|
|
String fmt = "tbz2"; |
|
|
|
File archive = new File(getTemporaryDirectory(), |
|
|
|
"archive." + fmt); |
|
|
|
archive(git, archive, fmt); |
|
|
|
ObjectId hash1 = ObjectId.fromRaw(IO.readFully(archive)); |
|
|
|
|
|
|
|
try (InputStream fi = Files.newInputStream(archive.toPath()); |
|
|
|
InputStream bi = new BufferedInputStream(fi); |
|
|
|
InputStream gzi = new BZip2CompressorInputStream(bi); |
|
|
|
ArchiveInputStream o = new TarArchiveInputStream(gzi)) { |
|
|
|
assertEntries(o); |
|
|
|
} |
|
|
|
|
|
|
|
Thread.sleep(WAIT); |
|
|
|
archive(git, archive, fmt); |
|
|
|
assertEquals(UNEXPECTED_DIFFERENT_HASH, hash1, |
|
|
|
ObjectId.fromRaw(IO.readFully(archive))); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
@Test |
|
|
|
public void archiveHeadAllFilesTxzTimestamps() throws Exception { |
|
|
|
try (Git git = new Git(db)) { |
|
|
|
createTestContent(git); |
|
|
|
String fmt = "txz"; |
|
|
|
File archive = new File(getTemporaryDirectory(), "archive." + fmt); |
|
|
|
archive(git, archive, fmt); |
|
|
|
ObjectId hash1 = ObjectId.fromRaw(IO.readFully(archive)); |
|
|
|
|
|
|
|
try (InputStream fi = Files.newInputStream(archive.toPath()); |
|
|
|
InputStream bi = new BufferedInputStream(fi); |
|
|
|
InputStream gzi = new XZCompressorInputStream(bi); |
|
|
|
ArchiveInputStream o = new TarArchiveInputStream(gzi)) { |
|
|
|
assertEntries(o); |
|
|
|
} |
|
|
|
|
|
|
|
Thread.sleep(WAIT); |
|
|
|
archive(git, archive, fmt); |
|
|
|
assertEquals(UNEXPECTED_DIFFERENT_HASH, hash1, |
|
|
|
ObjectId.fromRaw(IO.readFully(archive))); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
@Test |
|
|
|
public void archiveHeadAllFilesZipTimestamps() throws Exception { |
|
|
|
try (Git git = new Git(db)) { |
|
|
|
createTestContent(git); |
|
|
|
String fmt = "zip"; |
|
|
|
File archive = new File(getTemporaryDirectory(), "archive." + fmt); |
|
|
|
archive(git, archive, fmt); |
|
|
|
ObjectId hash1 = ObjectId.fromRaw(IO.readFully(archive)); |
|
|
|
|
|
|
|
try (InputStream fi = Files.newInputStream(archive.toPath()); |
|
|
|
InputStream bi = new BufferedInputStream(fi); |
|
|
|
ArchiveInputStream o = new ZipArchiveInputStream(bi)) { |
|
|
|
assertEntries(o); |
|
|
|
} |
|
|
|
|
|
|
|
Thread.sleep(WAIT); |
|
|
|
archive(git, archive, fmt); |
|
|
|
assertEquals(UNEXPECTED_DIFFERENT_HASH, hash1, |
|
|
|
ObjectId.fromRaw(IO.readFully(archive))); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
private void createTestContent(Git git) throws IOException, GitAPIException, |
|
|
|
NoFilepatternException, NoHeadException, NoMessageException, |
|
|
|
UnmergedPathsException, ConcurrentRefUpdateException, |
|
|
|
WrongRepositoryStateException, AbortedByHookException { |
|
|
|
writeTrashFile("file_1.txt", "content_1_1"); |
|
|
|
git.add().addFilepattern("file_1.txt").call(); |
|
|
|
git.commit().setMessage("create file").call(); |
|
|
|
|
|
|
|
writeTrashFile("file_1.txt", "content_1_2"); |
|
|
|
writeTrashFile("file_2.txt", "content_2_2"); |
|
|
|
git.add().addFilepattern(".").call(); |
|
|
|
git.commit().setMessage("updated file").call(); |
|
|
|
} |
|
|
|
|
|
|
|
private static void archive(Git git, File archive, String fmt) |
|
|
|
throws GitAPIException, |
|
|
|
FileNotFoundException, AmbiguousObjectException, |
|
|
|
IncorrectObjectTypeException, IOException { |
|
|
|
git.archive().setOutputStream(new FileOutputStream(archive)) |
|
|
|
.setFormat(fmt) |
|
|
|
.setTree(git.getRepository().resolve("HEAD")).call(); |
|
|
|
} |
|
|
|
|
|
|
|
private static void assertEntries(ArchiveInputStream o) throws IOException { |
|
|
|
ArchiveEntry e; |
|
|
|
int n = 0; |
|
|
|
while ((e = o.getNextEntry()) != null) { |
|
|
|
n++; |
|
|
|
assertEquals(UNEXPECTED_LAST_MODIFIED, |
|
|
|
(1250379778668L / 1000L) * 1000L, |
|
|
|
e.getLastModifiedDate().getTime()); |
|
|
|
} |
|
|
|
assertEquals(UNEXPECTED_ARCHIVE_SIZE, 2, n); |
|
|
|
} |
|
|
|
|
|
|
|
private static class MockFormat |
|
|
|
implements ArchiveCommand.Format<MockOutputStream> { |
|
|
|
|