diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheCheckout.java b/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheCheckout.java index bbaed3766..fdc89cd54 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheCheckout.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheCheckout.java @@ -3,41 +3,14 @@ * Copyright (C) 2008, Robin Rosenberg * Copyright (C) 2008, Roger C. Soares * Copyright (C) 2006, Shawn O. Pearce - * Copyright (C) 2010, Chrisian Halstrick and - * other copyright owners as documented in the project's IP log. + * Copyright (C) 2010, Chrisian Halstrick + * Copyright (C) 2019-2020, Andre Bossert * * 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 + * terms of the Eclipse Distribution License v. 1.0 which is available at + * https://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. + * SPDX-License-Identifier: BSD-3-Clause */ package org.eclipse.jgit.dircache; @@ -1504,29 +1477,9 @@ public class DirCacheCheckout { File tmpFile = File.createTempFile( "._" + name, null, parentDir); //$NON-NLS-1$ - EolStreamType nonNullEolStreamType; - if (checkoutMetadata.eolStreamType != null) { - nonNullEolStreamType = checkoutMetadata.eolStreamType; - } else if (opt.getAutoCRLF() == AutoCRLF.TRUE) { - nonNullEolStreamType = EolStreamType.AUTO_CRLF; - } else { - nonNullEolStreamType = EolStreamType.DIRECT; - } - try (OutputStream channel = EolStreamTypeUtil.wrapOutputStream( - new FileOutputStream(tmpFile), nonNullEolStreamType)) { - if (checkoutMetadata.smudgeFilterCommand != null) { - if (FilterCommandRegistry - .isRegistered(checkoutMetadata.smudgeFilterCommand)) { - runBuiltinFilterCommand(repo, checkoutMetadata, ol, - channel); - } else { - runExternalFilterCommand(repo, entry, checkoutMetadata, ol, - fs, channel); - } - } else { - ol.copyTo(channel); - } - } + getContent(repo, entry.getPathString(), checkoutMetadata, ol, opt, + new FileOutputStream(tmpFile)); + // The entry needs to correspond to the on-disk filesize. If the content // was filtered (either by autocrlf handling or smudge filters) ask the // filesystem again for the length. Otherwise the objectloader knows the @@ -1565,11 +1518,69 @@ public class DirCacheCheckout { entry.setLastModified(fs.lastModifiedInstant(f)); } + /** + * Return filtered content for a specific object (blob). EOL handling and + * smudge-filter handling are applied in the same way as it would be done + * during a checkout. + * + * @param repo + * the repository + * @param path + * the path used to determine the correct filters for the object + * @param checkoutMetadata + * containing + *
    + *
  • smudgeFilterCommand to be run for smudging the object
  • + *
  • eolStreamType used for stream conversion (can be + * null)
  • + *
+ * @param ol + * the object loader to read raw content of the object + * @param opt + * the working tree options where only 'core.autocrlf' is used + * for EOL handling if 'checkoutMetadata.eolStreamType' is not + * valid + * @param os + * the output stream the filtered content is written to. The + * caller is responsible to close the stream. + * @throws IOException + * + * @since 5.7 + */ + public static void getContent(Repository repo, String path, + CheckoutMetadata checkoutMetadata, ObjectLoader ol, + WorkingTreeOptions opt, OutputStream os) + throws IOException { + EolStreamType nonNullEolStreamType; + if (checkoutMetadata.eolStreamType != null) { + nonNullEolStreamType = checkoutMetadata.eolStreamType; + } else if (opt.getAutoCRLF() == AutoCRLF.TRUE) { + nonNullEolStreamType = EolStreamType.AUTO_CRLF; + } else { + nonNullEolStreamType = EolStreamType.DIRECT; + } + try (OutputStream channel = EolStreamTypeUtil.wrapOutputStream( + os, nonNullEolStreamType)) { + if (checkoutMetadata.smudgeFilterCommand != null) { + if (FilterCommandRegistry + .isRegistered(checkoutMetadata.smudgeFilterCommand)) { + runBuiltinFilterCommand(repo, checkoutMetadata, ol, + channel); + } else { + runExternalFilterCommand(repo, path, checkoutMetadata, ol, + channel); + } + } else { + ol.copyTo(channel); + } + } + } + // Run an external filter command - private static void runExternalFilterCommand(Repository repo, - DirCacheEntry entry, - CheckoutMetadata checkoutMetadata, ObjectLoader ol, FS fs, + private static void runExternalFilterCommand(Repository repo, String path, + CheckoutMetadata checkoutMetadata, ObjectLoader ol, OutputStream channel) throws IOException { + FS fs = repo.getFS(); ProcessBuilder filterProcessBuilder = fs.runInShell( checkoutMetadata.smudgeFilterCommand, new String[0]); filterProcessBuilder.directory(repo.getWorkTree()); @@ -1588,12 +1599,12 @@ public class DirCacheCheckout { } catch (IOException | InterruptedException e) { throw new IOException(new FilterFailedException(e, checkoutMetadata.smudgeFilterCommand, - entry.getPathString())); + path)); } if (rc != 0) { throw new IOException(new FilterFailedException(rc, checkoutMetadata.smudgeFilterCommand, - entry.getPathString(), + path, result.getStdout().toByteArray(MAX_EXCEPTION_TEXT_SIZE), RawParseUtils.decode(result.getStderr() .toByteArray(MAX_EXCEPTION_TEXT_SIZE))));