diff options
author | Jonathan Nieder <jrn@google.com> | 2013-12-27 08:55:39 -0800 |
---|---|---|
committer | Jonathan Nieder <jrn@google.com> | 2013-12-27 08:55:39 -0800 |
commit | 2ecc27db9297e0dd9f4113699deeadd575731106 (patch) | |
tree | b6e9cc336a072b0b7c129dcab87471402d00c035 /org.eclipse.jgit.archive/src/org | |
parent | f2abbd0ea99aed638ca098e336f60f52bc923237 (diff) | |
download | jgit-2ecc27db9297e0dd9f4113699deeadd575731106.tar.gz jgit-2ecc27db9297e0dd9f4113699deeadd575731106.zip |
archive: Include entries for directories
Entries for directories are optional and mostly wasted space in most
archive formats (except as a place to hang ownership and filesystem
permissions), but "git archive" includes them. Follow suit.
This will make it easier in a later change to include empty
directories as placeholders for missing submodules.
Change-Id: I1810c686bcc9eb4d73498e4d3e763e18787b088a
Signed-off-by: Jonathan Nieder <jrn@google.com>
Diffstat (limited to 'org.eclipse.jgit.archive/src/org')
3 files changed, 103 insertions, 6 deletions
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 23f4beda14..7e1c9cc907 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 @@ -47,12 +47,14 @@ import java.io.OutputStream; import java.util.Arrays; import java.util.Collections; import java.util.List; +import java.text.MessageFormat; import org.apache.commons.compress.archivers.ArchiveOutputStream; import org.apache.commons.compress.archivers.tar.TarArchiveEntry; import org.apache.commons.compress.archivers.tar.TarArchiveOutputStream; import org.apache.commons.compress.archivers.tar.TarConstants; import org.eclipse.jgit.api.ArchiveCommand; +import org.eclipse.jgit.archive.internal.ArchiveText; import org.eclipse.jgit.lib.FileMode; import org.eclipse.jgit.lib.ObjectLoader; @@ -83,13 +85,29 @@ public class TarFormat implements ArchiveCommand.Format<ArchiveOutputStream> { return; } + // TarArchiveEntry detects directories by checking + // for '/' at the end of the filename. + if (path.endsWith("/") && mode != FileMode.TREE) + throw new IllegalArgumentException(MessageFormat.format( + ArchiveText.get().pathDoesNotMatchMode, path, mode)); + if (!path.endsWith("/") && mode == FileMode.TREE) + path = path + "/"; + final TarArchiveEntry entry = new TarArchiveEntry(path); - if (mode == FileMode.REGULAR_FILE || - mode == FileMode.EXECUTABLE_FILE) { + if (mode == FileMode.TREE) { + out.putArchiveEntry(entry); + out.closeArchiveEntry(); + return; + } + + if (mode == FileMode.REGULAR_FILE) { + // ok + } else if (mode == FileMode.EXECUTABLE_FILE) { entry.setMode(mode.getBits()); } else { - // TODO(jrn): Let the caller know the tree contained - // an entry with unsupported mode (e.g., a submodule). + // Unsupported mode (e.g., GITLINK). + throw new IllegalArgumentException(MessageFormat.format( + ArchiveText.get().unsupportedMode, mode)); } entry.setSize(loader.getSize()); out.putArchiveEntry(entry); 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 00c962bc98..1a3765ec19 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 @@ -44,6 +44,7 @@ package org.eclipse.jgit.archive; import java.io.IOException; import java.io.OutputStream; +import java.text.MessageFormat; import java.util.Arrays; import java.util.Collections; import java.util.List; @@ -52,6 +53,7 @@ import org.apache.commons.compress.archivers.ArchiveOutputStream; import org.apache.commons.compress.archivers.zip.ZipArchiveEntry; import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream; import org.eclipse.jgit.api.ArchiveCommand; +import org.eclipse.jgit.archive.internal.ArchiveText; import org.eclipse.jgit.lib.FileMode; import org.eclipse.jgit.lib.ObjectLoader; @@ -69,7 +71,20 @@ public class ZipFormat implements ArchiveCommand.Format<ArchiveOutputStream> { public void putEntry(ArchiveOutputStream out, 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) + throw new IllegalArgumentException(MessageFormat.format( + ArchiveText.get().pathDoesNotMatchMode, path, mode)); + if (!path.endsWith("/") && mode == FileMode.TREE) + path = path + "/"; + final ZipArchiveEntry entry = new ZipArchiveEntry(path); + if (mode == FileMode.TREE) { + out.putArchiveEntry(entry); + out.closeArchiveEntry(); + return; + } if (mode == FileMode.REGULAR_FILE) { // ok @@ -77,8 +92,9 @@ public class ZipFormat implements ArchiveCommand.Format<ArchiveOutputStream> { || mode == FileMode.SYMLINK) { entry.setUnixMode(mode.getBits()); } else { - // TODO(jrn): Let the caller know the tree contained - // an entry with unsupported mode (e.g., a submodule). + // Unsupported mode (e.g., GITLINK). + throw new IllegalArgumentException(MessageFormat.format( + ArchiveText.get().unsupportedMode, mode)); } entry.setSize(loader.getSize()); out.putArchiveEntry(entry); diff --git a/org.eclipse.jgit.archive/src/org/eclipse/jgit/archive/internal/ArchiveText.java b/org.eclipse.jgit.archive/src/org/eclipse/jgit/archive/internal/ArchiveText.java new file mode 100644 index 0000000000..edadf1c81d --- /dev/null +++ b/org.eclipse.jgit.archive/src/org/eclipse/jgit/archive/internal/ArchiveText.java @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2013, Google Inc. + * and other copyright owners as documented in the project's IP log. + * + * This program and the accompanying materials are made available + * under the terms of the Eclipse Distribution License v1.0 which + * accompanies this distribution, is reproduced below, and is + * available at http://www.eclipse.org/org/documents/edl-v10.php + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * - Neither the name of the Eclipse Foundation, Inc. nor the + * names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package org.eclipse.jgit.archive.internal; + +import org.eclipse.jgit.nls.NLS; +import org.eclipse.jgit.nls.TranslationBundle; + +/** + * Translation bundle for archivers + */ +public class ArchiveText extends TranslationBundle { + /** + * @return an instance of this translation bundle + */ + public static ArchiveText get() { + return NLS.getBundleFor(ArchiveText.class); + } + + // @formatter:off + /***/ public String pathDoesNotMatchMode; + /***/ public String unsupportedMode; +} |