diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/IndexDiff.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/IndexDiff.java index 4e9fab7b5..167d0e08a 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/IndexDiff.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/IndexDiff.java @@ -384,7 +384,32 @@ public void setFilter(TreeFilter filter) { * @throws java.io.IOException */ public boolean diff() throws IOException { - return diff(null, 0, 0, ""); //$NON-NLS-1$ + return diff(null); + } + + /** + * Run the diff operation. Until this is called, all lists will be empty. + * Use + * {@link #diff(ProgressMonitor, int, int, String, RepositoryBuilderFactory)} + * if a progress monitor is required. + *

+ * The operation may create repositories for submodules using builders + * provided by the given {@code factory}, if any, and will also close these + * submodule repositories again. + *

+ * + * @param factory + * the {@link RepositoryBuilderFactory} to use to create builders + * to create submodule repositories, if needed; if {@code null}, + * submodule repositories will be built using a plain + * {@link RepositoryBuilder}. + * @return if anything is different between index, tree, and workdir + * @throws java.io.IOException + * @since 5.6 + */ + public boolean diff(RepositoryBuilderFactory factory) + throws IOException { + return diff(null, 0, 0, "", factory); //$NON-NLS-1$ } /** @@ -410,6 +435,45 @@ public boolean diff() throws IOException { public boolean diff(final ProgressMonitor monitor, int estWorkTreeSize, int estIndexSize, final String title) throws IOException { + return diff(monitor, estWorkTreeSize, estIndexSize, title, null); + } + + /** + * Run the diff operation. Until this is called, all lists will be empty. + *

+ * The operation may be aborted by the progress monitor. In that event it + * will report what was found before the cancel operation was detected. + * Callers should ignore the result if monitor.isCancelled() is true. If a + * progress monitor is not needed, callers should use {@link #diff()} + * instead. Progress reporting is crude and approximate and only intended + * for informing the user. + *

+ *

+ * The operation may create repositories for submodules using builders + * provided by the given {@code factory}, if any, and will also close these + * submodule repositories again. + *

+ * + * @param monitor + * for reporting progress, may be null + * @param estWorkTreeSize + * number or estimated files in the working tree + * @param estIndexSize + * number of estimated entries in the cache + * @param title + * a {@link java.lang.String} object. + * @param factory + * the {@link RepositoryBuilderFactory} to use to create builders + * to create submodule repositories, if needed; if {@code null}, + * submodule repositories will be built using a plain + * {@link RepositoryBuilder}. + * @return if anything is different between index, tree, and workdir + * @throws java.io.IOException + * @since 5.6 + */ + public boolean diff(ProgressMonitor monitor, int estWorkTreeSize, + int estIndexSize, String title, RepositoryBuilderFactory factory) + throws IOException { dirCache = repository.readDirCache(); try (TreeWalk treeWalk = new TreeWalk(repository)) { @@ -537,6 +601,7 @@ public boolean diff(final ProgressMonitor monitor, int estWorkTreeSize, if (ignoreSubmoduleMode != IgnoreSubmoduleMode.ALL) { try (SubmoduleWalk smw = new SubmoduleWalk(repository)) { smw.setTree(new DirCacheIterator(dirCache)); + smw.setBuilderFactory(factory); while (smw.next()) { IgnoreSubmoduleMode localIgnoreSubmoduleMode = ignoreSubmoduleMode; try { @@ -568,7 +633,7 @@ public boolean diff(final ProgressMonitor monitor, int estWorkTreeSize, subRepo)); submoduleIndexDiffs.put(subRepoPath, smid); } - if (smid.diff()) { + if (smid.diff(factory)) { if (localIgnoreSubmoduleMode == IgnoreSubmoduleMode.UNTRACKED && smid.getAdded().isEmpty() && smid.getChanged().isEmpty() diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/RepositoryBuilderFactory.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/RepositoryBuilderFactory.java new file mode 100644 index 000000000..fc1251683 --- /dev/null +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/RepositoryBuilderFactory.java @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2019, Thomas Wolf and others + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0 which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +package org.eclipse.jgit.lib; + +import java.util.function.Supplier; + +/** + * A factory for {@link BaseRepositoryBuilder}s. + *

+ * Note that a {@link BaseRepositoryBuilder} should be used only once to build a + * repository. Otherwise subsequently built repositories may be built using + * settings made for earlier built repositories. + *

+ * + * @since 5.6 + */ +public interface RepositoryBuilderFactory extends + Supplier> { + // Empty +} diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/submodule/SubmoduleWalk.java b/org.eclipse.jgit/src/org/eclipse/jgit/submodule/SubmoduleWalk.java index 3eca08a44..2e5776d64 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/submodule/SubmoduleWalk.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/submodule/SubmoduleWalk.java @@ -57,6 +57,7 @@ import org.eclipse.jgit.errors.RepositoryNotFoundException; import org.eclipse.jgit.internal.JGitText; import org.eclipse.jgit.lib.AnyObjectId; +import org.eclipse.jgit.lib.BaseRepositoryBuilder; import org.eclipse.jgit.lib.BlobBasedConfig; import org.eclipse.jgit.lib.Config; import org.eclipse.jgit.lib.ConfigConstants; @@ -66,6 +67,7 @@ import org.eclipse.jgit.lib.Ref; import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.lib.RepositoryBuilder; +import org.eclipse.jgit.lib.RepositoryBuilderFactory; import org.eclipse.jgit.lib.StoredConfig; import org.eclipse.jgit.storage.file.FileBasedConfig; import org.eclipse.jgit.treewalk.AbstractTreeIterator; @@ -260,15 +262,41 @@ public static Repository getSubmoduleRepository(final File parent, */ public static Repository getSubmoduleRepository(final File parent, final String path, FS fs) throws IOException { + return getSubmoduleRepository(parent, path, fs, + new RepositoryBuilder()); + } + + /** + * Get submodule repository at path, using the specified file system + * abstraction and the specified builder + * + * @param parent + * {@link Repository} that contains the submodule + * @param path + * of the working tree of the submodule + * @param fs + * {@link FS} to use + * @param builder + * {@link BaseRepositoryBuilder} to use to build the submodule + * repository + * @return the {@link Repository} of the submodule, or {@code null} if it + * doesn't exist + * @throws IOException + * on errors + * @since 5.6 + */ + public static Repository getSubmoduleRepository(File parent, String path, + FS fs, BaseRepositoryBuilder builder) + throws IOException { File subWorkTree = new File(parent, path); - if (!subWorkTree.isDirectory()) + if (!subWorkTree.isDirectory()) { return null; - File workTree = new File(parent, path); + } try { - return new RepositoryBuilder() // + return builder // .setMustExist(true) // .setFS(fs) // - .setWorkTree(workTree) // + .setWorkTree(subWorkTree) // .build(); } catch (RepositoryNotFoundException e) { return null; @@ -366,6 +394,8 @@ else if (submoduleUrl.startsWith("../")) { //$NON-NLS-1$ private Map pathToName; + private RepositoryBuilderFactory factory; + /** * Create submodule generator * @@ -639,7 +669,25 @@ public String getPath() { } /** - * The module name for the current submodule entry (used for the section name of .git/config) + * Sets the {@link RepositoryBuilderFactory} to use for creating submodule + * repositories. If none is set, a plain {@link RepositoryBuilder} is used. + * + * @param factory + * to set + * @since 5.6 + */ + public void setBuilderFactory(RepositoryBuilderFactory factory) { + this.factory = factory; + } + + private BaseRepositoryBuilder getBuilder() { + return factory != null ? factory.get() : new RepositoryBuilder(); + } + + /** + * The module name for the current submodule entry (used for the section + * name of .git/config) + * * @since 4.10 * @return name */ @@ -755,7 +803,8 @@ ConfigConstants.CONFIG_SUBMODULE_SECTION, getModuleName(), * @throws java.io.IOException */ public Repository getRepository() throws IOException { - return getSubmoduleRepository(repository, path); + return getSubmoduleRepository(repository.getWorkTree(), path, + repository.getFS(), getBuilder()); } /**