From 1448ec37f9141d16da28151289e3d590c89fc739 Mon Sep 17 00:00:00 2001 From: Naoki Takezoe Date: Thu, 29 Dec 2016 13:47:17 +0900 Subject: [PATCH] Set commit time to ZipArchiveEntry Archived zip files for a same commit have different MD5 hash because mdate and mdate in the header of zip entries are not specified. In this case, Commons Compress sets an archived time. In the original git implementation, it's set a commit time: https://github.com/git/git/blob/e2b2d6a172b76d44cb7b1ddb12ea5bfac9613a44/archive.c#L378 By this fix, archive command sets the commit time to ZipArchiveEntry when RevCommit is given as an archiving target. Change-Id: I30dd8710e910cdf42d57742f8709e9803930a123 Signed-off-by: Naoki Takezoe Signed-off-by: David Pursehouse Signed-off-by: Matthias Sohn --- org.eclipse.jgit.archive/META-INF/MANIFEST.MF | 1 + .../org/eclipse/jgit/archive/TarFormat.java | 13 +++++++ .../org/eclipse/jgit/archive/Tbz2Format.java | 15 +++++++- .../org/eclipse/jgit/archive/TgzFormat.java | 15 +++++++- .../org/eclipse/jgit/archive/TxzFormat.java | 15 +++++++- .../org/eclipse/jgit/archive/ZipFormat.java | 20 ++++++++++ .../eclipse/jgit/api/ArchiveCommandTest.java | 10 +++++ org.eclipse.jgit/.settings/.api_filters | 8 ++++ .../org/eclipse/jgit/api/ArchiveCommand.java | 37 ++++++++++++++++--- 9 files changed, 126 insertions(+), 8 deletions(-) diff --git a/org.eclipse.jgit.archive/META-INF/MANIFEST.MF b/org.eclipse.jgit.archive/META-INF/MANIFEST.MF index b477de5f0..53c9b595c 100644 --- a/org.eclipse.jgit.archive/META-INF/MANIFEST.MF +++ b/org.eclipse.jgit.archive/META-INF/MANIFEST.MF @@ -15,6 +15,7 @@ Import-Package: org.apache.commons.compress.archivers;version="[1.4,2.0)", org.eclipse.jgit.api;version="[4.7.0,4.8.0)", org.eclipse.jgit.lib;version="[4.7.0,4.8.0)", org.eclipse.jgit.nls;version="[4.7.0,4.8.0)", + org.eclipse.jgit.revwalk;version="[4.7.0,4.8.0)", org.eclipse.jgit.util;version="[4.7.0,4.8.0)", org.osgi.framework;version="[1.3.0,2.0.0)" Bundle-ActivationPolicy: lazy diff --git a/org.eclipse.jgit.archive/src/org/eclipse/jgit/archive/TarFormat.java b/org.eclipse.jgit.archive/src/org/eclipse/jgit/archive/TarFormat.java index d56cb35d9..900f024bf 100644 --- a/org.eclipse.jgit.archive/src/org/eclipse/jgit/archive/TarFormat.java +++ b/org.eclipse.jgit.archive/src/org/eclipse/jgit/archive/TarFormat.java @@ -57,6 +57,7 @@ import org.eclipse.jgit.api.ArchiveCommand; import org.eclipse.jgit.archive.internal.ArchiveText; import org.eclipse.jgit.lib.FileMode; +import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.lib.ObjectLoader; /** @@ -84,9 +85,21 @@ public ArchiveOutputStream createArchiveOutputStream(OutputStream s, return applyFormatOptions(out, o); } + @Deprecated + @Override public void putEntry(ArchiveOutputStream out, String path, FileMode mode, ObjectLoader loader) throws IOException { + putEntry(out, null, path, mode,loader); + } + + /** + * @since 4.7 + */ + @Override + public void putEntry(ArchiveOutputStream out, + ObjectId tree, String path, FileMode mode, ObjectLoader loader) + throws IOException { if (mode == FileMode.SYMLINK) { final TarArchiveEntry entry = new TarArchiveEntry( path, TarConstants.LF_SYMLINK); diff --git a/org.eclipse.jgit.archive/src/org/eclipse/jgit/archive/Tbz2Format.java b/org.eclipse.jgit.archive/src/org/eclipse/jgit/archive/Tbz2Format.java index f3ab4da43..bba029363 100644 --- a/org.eclipse.jgit.archive/src/org/eclipse/jgit/archive/Tbz2Format.java +++ b/org.eclipse.jgit.archive/src/org/eclipse/jgit/archive/Tbz2Format.java @@ -53,6 +53,7 @@ import org.apache.commons.compress.compressors.bzip2.BZip2CompressorOutputStream; import org.eclipse.jgit.api.ArchiveCommand; import org.eclipse.jgit.lib.FileMode; +import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.lib.ObjectLoader; /** @@ -80,10 +81,22 @@ public ArchiveOutputStream createArchiveOutputStream(OutputStream s, return tarFormat.createArchiveOutputStream(out, o); } + @Deprecated + @Override public void putEntry(ArchiveOutputStream out, String path, FileMode mode, ObjectLoader loader) throws IOException { - tarFormat.putEntry(out, path, mode, loader); + putEntry(out, null, path, mode,loader); + } + + /** + * @since 4.7 + */ + @Override + public void putEntry(ArchiveOutputStream out, + ObjectId tree, String path, FileMode mode, ObjectLoader loader) + throws IOException { + tarFormat.putEntry(out, tree, path, mode, loader); } public Iterable suffixes() { diff --git a/org.eclipse.jgit.archive/src/org/eclipse/jgit/archive/TgzFormat.java b/org.eclipse.jgit.archive/src/org/eclipse/jgit/archive/TgzFormat.java index 06f09a488..b6bf3ff66 100644 --- a/org.eclipse.jgit.archive/src/org/eclipse/jgit/archive/TgzFormat.java +++ b/org.eclipse.jgit.archive/src/org/eclipse/jgit/archive/TgzFormat.java @@ -53,6 +53,7 @@ import org.apache.commons.compress.compressors.gzip.GzipCompressorOutputStream; import org.eclipse.jgit.api.ArchiveCommand; import org.eclipse.jgit.lib.FileMode; +import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.lib.ObjectLoader; /** @@ -80,10 +81,22 @@ public ArchiveOutputStream createArchiveOutputStream(OutputStream s, return tarFormat.createArchiveOutputStream(out, o); } + @Deprecated + @Override public void putEntry(ArchiveOutputStream out, String path, FileMode mode, ObjectLoader loader) throws IOException { - tarFormat.putEntry(out, path, mode, loader); + putEntry(out, null, path, mode,loader); + } + + /** + * @since 4.7 + */ + @Override + public void putEntry(ArchiveOutputStream out, + ObjectId tree, String path, FileMode mode, ObjectLoader loader) + throws IOException { + tarFormat.putEntry(out, tree, path, mode, loader); } public Iterable suffixes() { diff --git a/org.eclipse.jgit.archive/src/org/eclipse/jgit/archive/TxzFormat.java b/org.eclipse.jgit.archive/src/org/eclipse/jgit/archive/TxzFormat.java index 14839353d..76d934f21 100644 --- a/org.eclipse.jgit.archive/src/org/eclipse/jgit/archive/TxzFormat.java +++ b/org.eclipse.jgit.archive/src/org/eclipse/jgit/archive/TxzFormat.java @@ -53,6 +53,7 @@ import org.apache.commons.compress.compressors.xz.XZCompressorOutputStream; import org.eclipse.jgit.api.ArchiveCommand; import org.eclipse.jgit.lib.FileMode; +import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.lib.ObjectLoader; /** @@ -80,10 +81,22 @@ public ArchiveOutputStream createArchiveOutputStream(OutputStream s, return tarFormat.createArchiveOutputStream(out, o); } + @Deprecated + @Override public void putEntry(ArchiveOutputStream out, String path, FileMode mode, ObjectLoader loader) throws IOException { - tarFormat.putEntry(out, path, mode, loader); + putEntry(out, null, path, mode,loader); + } + + /** + * @since 4.7 + */ + @Override + public void putEntry(ArchiveOutputStream out, + ObjectId tree, String path, FileMode mode, ObjectLoader loader) + throws IOException { + tarFormat.putEntry(out, tree, path, mode, loader); } public Iterable suffixes() { diff --git a/org.eclipse.jgit.archive/src/org/eclipse/jgit/archive/ZipFormat.java b/org.eclipse.jgit.archive/src/org/eclipse/jgit/archive/ZipFormat.java index 0e1b2536f..dfbf2ee62 100644 --- a/org.eclipse.jgit.archive/src/org/eclipse/jgit/archive/ZipFormat.java +++ b/org.eclipse.jgit.archive/src/org/eclipse/jgit/archive/ZipFormat.java @@ -56,7 +56,9 @@ import org.eclipse.jgit.api.ArchiveCommand; import org.eclipse.jgit.archive.internal.ArchiveText; import org.eclipse.jgit.lib.FileMode; +import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.lib.ObjectLoader; +import org.eclipse.jgit.revwalk.RevCommit; /** * PKWARE's ZIP format. @@ -80,9 +82,21 @@ public ArchiveOutputStream createArchiveOutputStream(OutputStream s, return applyFormatOptions(new ZipArchiveOutputStream(s), o); } + @Deprecated + @Override public void putEntry(ArchiveOutputStream out, String path, FileMode mode, ObjectLoader loader) throws IOException { + putEntry(out, null, path, mode,loader); + } + + /** + * @since 4.7 + */ + @Override + public void putEntry(ArchiveOutputStream out, + ObjectId tree, String path, FileMode mode, ObjectLoader loader) + throws IOException { // ZipArchiveEntry detects directories by checking // for '/' at the end of the filename. if (path.endsWith("/") && mode != FileMode.TREE) //$NON-NLS-1$ @@ -92,6 +106,12 @@ public void putEntry(ArchiveOutputStream out, path = path + "/"; //$NON-NLS-1$ final ZipArchiveEntry entry = new ZipArchiveEntry(path); + + if(tree instanceof RevCommit){ + long commitTime = ((RevCommit) tree).getCommitTime(); + entry.setTime(commitTime); + } + if (mode == FileMode.TREE) { out.putArchiveEntry(entry); out.closeArchiveEntry(); diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/ArchiveCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/ArchiveCommandTest.java index fc8df42e2..54d58eca4 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/ArchiveCommandTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/ArchiveCommandTest.java @@ -57,6 +57,7 @@ import org.eclipse.jgit.api.errors.GitAPIException; 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.StringUtils; @@ -203,12 +204,14 @@ private String getByPath(String path) { private final List SUFFIXES = Collections .unmodifiableList(Arrays.asList(".mck")); + @Override public MockOutputStream createArchiveOutputStream(OutputStream s) throws IOException { return createArchiveOutputStream(s, Collections. emptyMap()); } + @Override public MockOutputStream createArchiveOutputStream(OutputStream s, Map o) throws IOException { for (Map.Entry p : o.entrySet()) { @@ -224,11 +227,18 @@ public MockOutputStream createArchiveOutputStream(OutputStream s, return new MockOutputStream(); } + @Override public void putEntry(MockOutputStream out, String path, FileMode mode, ObjectLoader loader) { + putEntry(out, null, path, mode, loader); + } + + @Override + public void putEntry(MockOutputStream out, ObjectId tree, String path, FileMode mode, ObjectLoader loader) { String content = mode != FileMode.TREE ? new String(loader.getBytes()) : null; entries.put(path, content); } + @Override public Iterable suffixes() { return SUFFIXES; } diff --git a/org.eclipse.jgit/.settings/.api_filters b/org.eclipse.jgit/.settings/.api_filters index fa8a9cf9a..418fed612 100644 --- a/org.eclipse.jgit/.settings/.api_filters +++ b/org.eclipse.jgit/.settings/.api_filters @@ -1,5 +1,13 @@ + + + + + + + + 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 8543bd5f6..6c7dca5c2 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/ArchiveCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/ArchiveCommand.java @@ -162,8 +162,8 @@ T createArchiveOutputStream(OutputStream s, Map o) * @param out * archive object from createArchiveOutputStream * @param path - * full filename relative to the root of the archive - * (with trailing '/' for directories) + * full filename relative to the root of the archive (with + * trailing '/' for directories) * @param mode * mode (for example FileMode.REGULAR_FILE or * FileMode.SYMLINK) @@ -171,9 +171,36 @@ T createArchiveOutputStream(OutputStream s, Map o) * blob object with data for this entry (null for * directories) * @throws IOException - * thrown by the underlying output stream for I/O errors + * thrown by the underlying output stream for I/O errors + * @deprecated use + * {@link #putEntry(Closeable, ObjectId, String, FileMode, ObjectLoader)} + * instead */ + @Deprecated void putEntry(T out, String path, FileMode mode, + ObjectLoader loader) throws IOException; + + /** + * Write an entry to an archive. + * + * @param out + * archive object from createArchiveOutputStream + * @param tree + * the tag, commit, or tree object to produce an archive for + * @param path + * full filename relative to the root of the archive (with + * trailing '/' for directories) + * @param mode + * mode (for example FileMode.REGULAR_FILE or + * FileMode.SYMLINK) + * @param loader + * blob object with data for this entry (null for + * directories) + * @throws IOException + * thrown by the underlying output stream for I/O errors + * @since 4.7 + */ + void putEntry(T out, ObjectId tree, String path, FileMode mode, ObjectLoader loader) throws IOException; /** @@ -389,11 +416,11 @@ private OutputStream writeArchive(Format fmt) { mode = FileMode.TREE; if (mode == FileMode.TREE) { - fmt.putEntry(outa, name + "/", mode, null); //$NON-NLS-1$ + fmt.putEntry(outa, tree, name + "/", mode, null); //$NON-NLS-1$ continue; } walk.getObjectId(idBuf, 0); - fmt.putEntry(outa, name, mode, reader.open(idBuf)); + fmt.putEntry(outa, tree, name, mode, reader.open(idBuf)); } outa.close(); return out;