diff options
Diffstat (limited to 'org.eclipse.jgit/src')
4 files changed, 124 insertions, 16 deletions
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/FileTreeIterator.java b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/FileTreeIterator.java index 0130cf97ec..06f53c2f3b 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/FileTreeIterator.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/FileTreeIterator.java @@ -211,13 +211,7 @@ public class FileTreeIterator extends WorkingTreeIterator { } private Entry[] entries() { - final File[] all = directory.listFiles(); - if (all == null) - return EOF; - final Entry[] r = new Entry[all.length]; - for (int i = 0; i < r.length; i++) - r[i] = new FileEntry(all[i], fs, fileModeStrategy); - return r; + return fs.list(directory, fileModeStrategy); } /** @@ -246,7 +240,7 @@ public class FileTreeIterator extends WorkingTreeIterator { * * @since 4.3 */ - static public class DefaultFileModeStrategy implements FileModeStrategy { + public static class DefaultFileModeStrategy implements FileModeStrategy { /** * a singleton instance of the default FileModeStrategy */ @@ -279,7 +273,7 @@ public class FileTreeIterator extends WorkingTreeIterator { * * @since 4.3 */ - static public class NoGitlinksStrategy implements FileModeStrategy { + public static class NoGitlinksStrategy implements FileModeStrategy { /** * a singleton instance of the default FileModeStrategy @@ -304,7 +298,7 @@ public class FileTreeIterator extends WorkingTreeIterator { /** * Wrapper for a standard Java IO file */ - static public class FileEntry extends Entry { + public static class FileEntry extends Entry { private final FileMode mode; private FS.Attributes attributes; @@ -343,6 +337,29 @@ public class FileTreeIterator extends WorkingTreeIterator { mode = fileModeStrategy.getMode(f, attributes); } + /** + * Create a new file entry given the specified FileModeStrategy + * + * @param f + * file + * @param fs + * file system + * @param attributes + * of the file + * @param fileModeStrategy + * the strategy to use when determining the FileMode of a + * file; controls gitlinks etc. + * + * @since 5.0 + */ + public FileEntry(File f, FS fs, FS.Attributes attributes, + FileModeStrategy fileModeStrategy) { + this.fs = fs; + this.attributes = attributes; + f = fs.normalize(f); + mode = fileModeStrategy.getMode(f, attributes); + } + @Override public FileMode getMode() { return mode; @@ -365,12 +382,12 @@ public class FileTreeIterator extends WorkingTreeIterator { @Override public InputStream openInputStream() throws IOException { - if (fs.isSymLink(getFile())) + if (attributes.isSymbolicLink()) { return new ByteArrayInputStream(fs.readSymLink(getFile()) - .getBytes( - Constants.CHARACTER_ENCODING)); - else + .getBytes(Constants.CHARACTER_ENCODING)); + } else { return new FileInputStream(getFile()); + } } /** diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/WorkingTreeIterator.java b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/WorkingTreeIterator.java index e6566939f8..cb68cee7bd 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/WorkingTreeIterator.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/WorkingTreeIterator.java @@ -1165,8 +1165,12 @@ public abstract class WorkingTreeIterator extends AbstractTreeIterator { return contentDigest.digest(); } - /** A single entry within a working directory tree. */ - protected static abstract class Entry { + /** + * A single entry within a working directory tree. + * + * @since 5.0 + */ + public static abstract class Entry { byte[] encodedName; int encodedNameLen; diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/FS.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/FS.java index a2756e845c..27a437f4f5 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/util/FS.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/FS.java @@ -71,6 +71,9 @@ import org.eclipse.jgit.errors.CommandFailedException; import org.eclipse.jgit.internal.JGitText; import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.lib.Repository; +import org.eclipse.jgit.treewalk.FileTreeIterator.FileEntry; +import org.eclipse.jgit.treewalk.FileTreeIterator.FileModeStrategy; +import org.eclipse.jgit.treewalk.WorkingTreeIterator.Entry; import org.eclipse.jgit.util.ProcessResult.Status; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -82,6 +85,14 @@ public abstract class FS { private static final Logger LOG = LoggerFactory.getLogger(FS.class); /** + * An empty array of entries, suitable as a return value for + * {@link #list(File, FileModeStrategy)}. + * + * @since 5.0 + */ + protected static final Entry[] NO_ENTRIES = {}; + + /** * This class creates FS instances. It will be overridden by a Java7 variant * if such can be detected in {@link #detect(Boolean)}. * @@ -887,6 +898,29 @@ public abstract class FS { } /** + * Enumerates children of a directory. + * + * @param directory + * to get the children of + * @param fileModeStrategy + * to use to calculate the git mode of a child + * @return an array of entries for the children + * + * @since 5.0 + */ + public Entry[] list(File directory, FileModeStrategy fileModeStrategy) { + final File[] all = directory.listFiles(); + if (all == null) { + return NO_ENTRIES; + } + final Entry[] result = new Entry[all.length]; + for (int i = 0; i < result.length; i++) { + result[i] = new FileEntry(all[i], this, fileModeStrategy); + } + return result; + } + + /** * Checks whether the given hook is defined for the given repository, then * runs it with the given arguments. * <p> diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_Win32.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_Win32.java index 29fe5dc829..a0ed04fe66 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_Win32.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_Win32.java @@ -47,11 +47,21 @@ package org.eclipse.jgit.util; import java.io.File; import java.io.IOException; import java.nio.charset.Charset; +import java.nio.file.FileVisitOption; +import java.nio.file.FileVisitResult; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.SimpleFileVisitor; +import java.nio.file.attribute.BasicFileAttributes; import java.util.ArrayList; import java.util.Arrays; +import java.util.EnumSet; import java.util.List; import org.eclipse.jgit.errors.CommandFailedException; +import org.eclipse.jgit.treewalk.FileTreeIterator.FileEntry; +import org.eclipse.jgit.treewalk.FileTreeIterator.FileModeStrategy; +import org.eclipse.jgit.treewalk.WorkingTreeIterator.Entry; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -121,6 +131,49 @@ public class FS_Win32 extends FS { /** {@inheritDoc} */ @Override + public Entry[] list(File directory, FileModeStrategy fileModeStrategy) { + List<Entry> result = new ArrayList<>(); + FS fs = this; + boolean checkExecutable = fs.supportsExecute(); + try { + Files.walkFileTree(directory.toPath(), + EnumSet.noneOf(FileVisitOption.class), 1, + new SimpleFileVisitor<Path>() { + @Override + public FileVisitResult visitFile(Path file, + BasicFileAttributes attrs) throws IOException { + File f = file.toFile(); + FS.Attributes attributes = new FS.Attributes(fs, f, + true, attrs.isDirectory(), + checkExecutable && f.canExecute(), + attrs.isSymbolicLink(), + attrs.isRegularFile(), + attrs.creationTime().toMillis(), + attrs.lastModifiedTime().toMillis(), + attrs.size()); + result.add(new FileEntry(f, fs, attributes, + fileModeStrategy)); + return FileVisitResult.CONTINUE; + } + + @Override + public FileVisitResult visitFileFailed(Path file, + IOException exc) throws IOException { + // Just ignore it + return FileVisitResult.CONTINUE; + } + }); + } catch (IOException e) { + // Ignore + } + if (result.isEmpty()) { + return NO_ENTRIES; + } + return result.toArray(new Entry[result.size()]); + } + + /** {@inheritDoc} */ + @Override protected File discoverGitExe() { String path = SystemReader.getInstance().getenv("PATH"); //$NON-NLS-1$ File gitExe = searchPath(path, "git.exe", "git.cmd"); //$NON-NLS-1$ //$NON-NLS-2$ |