package org.eclipse.jgit.pgm;
import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.fail;
+import static org.junit.Assume.assumeNoException;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.io.IOException;
+import java.io.OutputStream;
import java.lang.String;
import java.util.ArrayList;
import java.util.zip.ZipInputStream;
import org.eclipse.jgit.api.Git;
+import org.eclipse.jgit.dircache.DirCache;
import org.eclipse.jgit.lib.CLIRepositoryTestCase;
+import org.eclipse.jgit.lib.FileMode;
import org.eclipse.jgit.pgm.CLIGitCommand;
import org.junit.Before;
import org.junit.Ignore;
assertArrayEquals(expect, actual);
}
+ @Test
+ public void testArchivePreservesMode() throws Exception {
+ writeTrashFile("plain", "a file with content");
+ writeTrashFile("executable", "an executable file");
+ writeTrashFile("symlink", "plain");
+ git.add().addFilepattern("plain").call();
+ git.add().addFilepattern("executable").call();
+ git.add().addFilepattern("symlink").call();
+
+ DirCache cache = db.lockDirCache();
+ cache.getEntry("executable").setFileMode(FileMode.EXECUTABLE_FILE);
+ cache.getEntry("symlink").setFileMode(FileMode.SYMLINK);
+ cache.write();
+ cache.commit();
+ cache.unlock();
+
+ git.commit().setMessage("three files with different modes").call();
+
+ final byte[] zipData = CLIGitCommand.rawExecute( //
+ "git archive master", db);
+ writeRaw("zip-with-modes.zip", zipData);
+ assertContainsEntryWithMode("zip-with-modes.zip", "-rw-", "plain");
+ assertContainsEntryWithMode("zip-with-modes.zip", "-rwx", "executable");
+ assertContainsEntryWithMode("zip-with-modes.zip", "l", "symlink");
+ }
+
@Test
public void testArchivePreservesContent() throws Exception {
final String payload = "“The quick brown fox jumps over the lazy dog!”";
zipEntryContent(result, "xyzzy"));
}
+ private void assertContainsEntryWithMode(String zipFilename, String mode, String name) //
+ throws Exception {
+ final File cwd = db.getWorkTree();
+ final ProcessBuilder procBuilder = new ProcessBuilder("zipinfo", zipFilename) //
+ .directory(cwd) //
+ .redirectErrorStream(true);
+ Process proc = null;
+ try {
+ proc = procBuilder.start();
+ } catch (IOException e) {
+ // On machines without a "zipinfo" command, let the test pass.
+ assumeNoException(e);
+ }
+
+ proc.getOutputStream().close();
+ final BufferedReader reader = new BufferedReader( //
+ new InputStreamReader(proc.getInputStream(), "UTF-8"));
+ try {
+ String line;
+ while ((line = reader.readLine()) != null)
+ if (line.startsWith(mode) && line.endsWith(name))
+ // found it!
+ return;
+ fail("expected entry " + name + " with mode " + mode + " but found none");
+ } finally {
+ proc.getOutputStream().close();
+ proc.destroy();
+ }
+ }
+
+ private void writeRaw(String filename, byte[] data) //
+ throws IOException {
+ final File path = new File(db.getWorkTree(), filename);
+ final OutputStream out = new FileOutputStream(path);
+ try {
+ out.write(data);
+ } finally {
+ out.close();
+ }
+ }
+
private static String[] listZipEntries(byte[] zipData) throws IOException {
final List<String> l = new ArrayList<String>();
final ZipInputStream in = new ZipInputStream( //
final ZipArchiveEntry entry = new ZipArchiveEntry(name);
final ObjectLoader loader = reader.open(idBuf);
entry.setSize(loader.getSize());
- out.putArchiveEntry(entry);
- loader.copyTo(out);
- out.closeArchiveEntry();
- if (mode != FileMode.REGULAR_FILE)
+ if (mode == FileMode.REGULAR_FILE)
+ ; // ok
+ else if (mode == FileMode.EXECUTABLE_FILE ||
+ mode == FileMode.SYMLINK)
+ entry.setUnixMode(mode.getBits());
+ else
System.err.println(MessageFormat.format( //
CLIText.get().archiveEntryModeIgnored, //
name));
+
+ out.putArchiveEntry(entry);
+ loader.copyTo(out);
+ out.closeArchiveEntry();
}
out.close();