/*
 * Copyright (C) 2011, GitHub Inc. 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
 * https://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */
package org.eclipse.jgit.submodule;

import java.io.File;
import java.io.IOException;
import java.text.MessageFormat;
import java.util.HashMap;
import java.util.Map;

import org.eclipse.jgit.dircache.DirCache;
import org.eclipse.jgit.dircache.DirCacheIterator;
import org.eclipse.jgit.errors.ConfigInvalidException;
import org.eclipse.jgit.errors.CorruptObjectException;
import org.eclipse.jgit.errors.IncorrectObjectTypeException;
import org.eclipse.jgit.errors.MissingObjectException;
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;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.FileMode;
import org.eclipse.jgit.lib.ObjectId;
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;
import org.eclipse.jgit.treewalk.CanonicalTreeParser;
import org.eclipse.jgit.treewalk.TreeWalk;
import org.eclipse.jgit.treewalk.filter.PathFilter;
import org.eclipse.jgit.treewalk.filter.TreeFilter;
import org.eclipse.jgit.util.FS;

Walker that visits all submodule entries found in a tree
/** * Walker that visits all submodule entries found in a tree */
public class SubmoduleWalk implements AutoCloseable {
The values for the config parameter submodule.<name>.ignore
Since:3.6
/** * The values for the config parameter submodule.&lt;name&gt;.ignore * * @since 3.6 */
public enum IgnoreSubmoduleMode {
Ignore all modifications to submodules
/** * Ignore all modifications to submodules */
ALL,
Ignore changes to the working tree of a submodule
/** * Ignore changes to the working tree of a submodule */
DIRTY,
Ignore changes to untracked files in the working tree of a submodule
/** * Ignore changes to untracked files in the working tree of a submodule */
UNTRACKED,
Ignore nothing. That's the default
/** * Ignore nothing. That's the default */
NONE; }
Create a generator to walk over the submodule entries currently in the index The .gitmodules file is read from the index.
Params:
Throws:
Returns:generator over submodule index entries. The caller is responsible for calling close().
/** * Create a generator to walk over the submodule entries currently in the * index * * The {@code .gitmodules} file is read from the index. * * @param repository * a {@link org.eclipse.jgit.lib.Repository} object. * @return generator over submodule index entries. The caller is responsible * for calling {@link #close()}. * @throws java.io.IOException */
public static SubmoduleWalk forIndex(Repository repository) throws IOException { @SuppressWarnings("resource") // The caller closes it SubmoduleWalk generator = new SubmoduleWalk(repository); try { DirCache index = repository.readDirCache(); generator.setTree(new DirCacheIterator(index)); } catch (IOException e) { generator.close(); throw e; } return generator; }
Create a generator and advance it to the submodule entry at the given path
Params:
  • repository – a Repository object.
  • treeId – the root of a tree containing both a submodule at the given path and .gitmodules at the root.
  • path – a String object.
Throws:
Returns:generator at given path. The caller is responsible for calling close(). Null if no submodule at given path.
/** * Create a generator and advance it to the submodule entry at the given * path * * @param repository * a {@link org.eclipse.jgit.lib.Repository} object. * @param treeId * the root of a tree containing both a submodule at the given * path and .gitmodules at the root. * @param path * a {@link java.lang.String} object. * @return generator at given path. The caller is responsible for calling * {@link #close()}. Null if no submodule at given path. * @throws java.io.IOException */
public static SubmoduleWalk forPath(Repository repository, AnyObjectId treeId, String path) throws IOException { SubmoduleWalk generator = new SubmoduleWalk(repository); try { generator.setTree(treeId); PathFilter filter = PathFilter.create(path); generator.setFilter(filter); generator.setRootTree(treeId); while (generator.next()) if (filter.isDone(generator.walk)) return generator; } catch (IOException e) { generator.close(); throw e; } generator.close(); return null; }
Create a generator and advance it to the submodule entry at the given path
Params:
  • repository – a Repository object.
  • iterator – the root of a tree containing both a submodule at the given path and .gitmodules at the root.
  • path – a String object.
Throws:
Returns:generator at given path. The caller is responsible for calling close(). Null if no submodule at given path.
/** * Create a generator and advance it to the submodule entry at the given * path * * @param repository * a {@link org.eclipse.jgit.lib.Repository} object. * @param iterator * the root of a tree containing both a submodule at the given * path and .gitmodules at the root. * @param path * a {@link java.lang.String} object. * @return generator at given path. The caller is responsible for calling * {@link #close()}. Null if no submodule at given path. * @throws java.io.IOException */
public static SubmoduleWalk forPath(Repository repository, AbstractTreeIterator iterator, String path) throws IOException { SubmoduleWalk generator = new SubmoduleWalk(repository); try { generator.setTree(iterator); PathFilter filter = PathFilter.create(path); generator.setFilter(filter); generator.setRootTree(iterator); while (generator.next()) if (filter.isDone(generator.walk)) return generator; } catch (IOException e) { generator.close(); throw e; } generator.close(); return null; }
Get submodule directory
Params:
Returns:directory
/** * Get submodule directory * * @param parent * the {@link org.eclipse.jgit.lib.Repository}. * @param path * submodule path * @return directory */
public static File getSubmoduleDirectory(final Repository parent, final String path) { return new File(parent.getWorkTree(), path); }
Get submodule repository
Params:
Throws:
Returns:repository or null if repository doesn't exist
/** * Get submodule repository * * @param parent * the {@link org.eclipse.jgit.lib.Repository}. * @param path * submodule path * @return repository or null if repository doesn't exist * @throws java.io.IOException */
public static Repository getSubmoduleRepository(final Repository parent, final String path) throws IOException { return getSubmoduleRepository(parent.getWorkTree(), path, parent.getFS()); }
Get submodule repository at path
Params:
  • parent – the parent
  • path – submodule path
Throws:
Returns:repository or null if repository doesn't exist
/** * Get submodule repository at path * * @param parent * the parent * @param path * submodule path * @return repository or null if repository doesn't exist * @throws java.io.IOException */
public static Repository getSubmoduleRepository(final File parent, final String path) throws IOException { return getSubmoduleRepository(parent, path, FS.DETECTED); }
Get submodule repository at path, using the specified file system abstraction
Params:
  • parent –
  • path –
  • fs – the file system abstraction to be used
Throws:
Returns:repository or null if repository doesn't exist
Since:4.10
/** * Get submodule repository at path, using the specified file system * abstraction * * @param parent * @param path * @param fs * the file system abstraction to be used * @return repository or null if repository doesn't exist * @throws IOException * @since 4.10 */
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
Params:
  • parent – Repository that contains the submodule
  • path – of the working tree of the submodule
  • fs – FS to use
  • builder – BaseRepositoryBuilder to use to build the submodule repository
Throws:
Returns:the Repository of the submodule, or null if it doesn't exist
Since:5.6
/** * 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<?, ? extends Repository> builder) throws IOException { File subWorkTree = new File(parent, path); if (!subWorkTree.isDirectory()) { return null; } try { return builder // .setMustExist(true) // .setFS(fs) // .setWorkTree(subWorkTree) // .build(); } catch (RepositoryNotFoundException e) { return null; } }
Resolve submodule repository URL.

This handles relative URLs that are typically specified in the '.gitmodules' file by resolving them against the remote URL of the parent repository.

Relative URLs will be resolved against the parent repository's working directory if the parent repository has no configured remote URL.

Params:
  • parent – parent repository
  • url – absolute or relative URL of the submodule repository
Throws:
Returns:resolved URL
/** * Resolve submodule repository URL. * <p> * This handles relative URLs that are typically specified in the * '.gitmodules' file by resolving them against the remote URL of the parent * repository. * <p> * Relative URLs will be resolved against the parent repository's working * directory if the parent repository has no configured remote URL. * * @param parent * parent repository * @param url * absolute or relative URL of the submodule repository * @return resolved URL * @throws java.io.IOException */
public static String getSubmoduleRemoteUrl(final Repository parent, final String url) throws IOException { if (!url.startsWith("./") && !url.startsWith("../")) //$NON-NLS-1$ //$NON-NLS-2$ return url; String remoteName = null; // Look up remote URL associated wit HEAD ref Ref ref = parent.exactRef(Constants.HEAD); if (ref != null) { if (ref.isSymbolic()) ref = ref.getLeaf(); remoteName = parent.getConfig().getString( ConfigConstants.CONFIG_BRANCH_SECTION, Repository.shortenRefName(ref.getName()), ConfigConstants.CONFIG_KEY_REMOTE); } // Fall back to 'origin' if current HEAD ref has no remote URL if (remoteName == null) remoteName = Constants.DEFAULT_REMOTE_NAME; String remoteUrl = parent.getConfig().getString( ConfigConstants.CONFIG_REMOTE_SECTION, remoteName, ConfigConstants.CONFIG_KEY_URL); // Fall back to parent repository's working directory if no remote URL if (remoteUrl == null) { remoteUrl = parent.getWorkTree().getAbsolutePath(); // Normalize slashes to '/' if ('\\' == File.separatorChar) remoteUrl = remoteUrl.replace('\\', '/'); } // Remove trailing '/' if (remoteUrl.charAt(remoteUrl.length() - 1) == '/') remoteUrl = remoteUrl.substring(0, remoteUrl.length() - 1); char separator = '/'; String submoduleUrl = url; while (submoduleUrl.length() > 0) { if (submoduleUrl.startsWith("./")) //$NON-NLS-1$ submoduleUrl = submoduleUrl.substring(2); else if (submoduleUrl.startsWith("../")) { //$NON-NLS-1$ int lastSeparator = remoteUrl.lastIndexOf('/'); if (lastSeparator < 1) { lastSeparator = remoteUrl.lastIndexOf(':'); separator = ':'; } if (lastSeparator < 1) throw new IOException(MessageFormat.format( JGitText.get().submoduleParentRemoteUrlInvalid, remoteUrl)); remoteUrl = remoteUrl.substring(0, lastSeparator); submoduleUrl = submoduleUrl.substring(3); } else break; } return remoteUrl + separator + submoduleUrl; } private final Repository repository; private final TreeWalk walk; private StoredConfig repoConfig; private AbstractTreeIterator rootTree; private Config modulesConfig; private String path; private Map<String, String> pathToName; private RepositoryBuilderFactory factory;
Create submodule generator
Params:
Throws:
/** * Create submodule generator * * @param repository * the {@link org.eclipse.jgit.lib.Repository}. * @throws java.io.IOException */
public SubmoduleWalk(Repository repository) throws IOException { this.repository = repository; repoConfig = repository.getConfig(); walk = new TreeWalk(repository); walk.setRecursive(true); }
Set the config used by this walk. This method need only be called if constructing a walk manually instead of with one of the static factory methods above.
Params:
  • config – .gitmodules config object
Returns:this generator
/** * Set the config used by this walk. * * This method need only be called if constructing a walk manually instead of * with one of the static factory methods above. * * @param config * .gitmodules config object * @return this generator */
public SubmoduleWalk setModulesConfig(Config config) { modulesConfig = config; loadPathNames(); return this; }
Set the tree used by this walk for finding .gitmodules.

The root tree is not read until the first submodule is encountered by the walk.

This method need only be called if constructing a walk manually instead of with one of the static factory methods above.

Params:
  • tree – tree containing .gitmodules
Returns:this generator
/** * Set the tree used by this walk for finding {@code .gitmodules}. * <p> * The root tree is not read until the first submodule is encountered by the * walk. * <p> * This method need only be called if constructing a walk manually instead of * with one of the static factory methods above. * * @param tree * tree containing .gitmodules * @return this generator */
public SubmoduleWalk setRootTree(AbstractTreeIterator tree) { rootTree = tree; modulesConfig = null; pathToName = null; return this; }
Set the tree used by this walk for finding .gitmodules.

The root tree is not read until the first submodule is encountered by the walk.

This method need only be called if constructing a walk manually instead of with one of the static factory methods above.

Params:
  • id – ID of a tree containing .gitmodules
Throws:
Returns:this generator
/** * Set the tree used by this walk for finding {@code .gitmodules}. * <p> * The root tree is not read until the first submodule is encountered by the * walk. * <p> * This method need only be called if constructing a walk manually instead of * with one of the static factory methods above. * * @param id * ID of a tree containing .gitmodules * @return this generator * @throws java.io.IOException */
public SubmoduleWalk setRootTree(AnyObjectId id) throws IOException { final CanonicalTreeParser p = new CanonicalTreeParser(); p.reset(walk.getObjectReader(), id); rootTree = p; modulesConfig = null; pathToName = null; return this; }
Load the config for this walk from .gitmodules.

Uses the root tree if setRootTree(AbstractTreeIterator) was previously called, otherwise uses the working tree.

If no submodule config is found, loads an empty config.

Throws:
Returns:this generator
/** * Load the config for this walk from {@code .gitmodules}. * <p> * Uses the root tree if {@link #setRootTree(AbstractTreeIterator)} was * previously called, otherwise uses the working tree. * <p> * If no submodule config is found, loads an empty config. * * @return this generator * @throws java.io.IOException * if an error occurred, or if the repository is bare * @throws org.eclipse.jgit.errors.ConfigInvalidException */
public SubmoduleWalk loadModulesConfig() throws IOException, ConfigInvalidException { if (rootTree == null) { File modulesFile = new File(repository.getWorkTree(), Constants.DOT_GIT_MODULES); FileBasedConfig config = new FileBasedConfig(modulesFile, repository.getFS()); config.load(); modulesConfig = config; loadPathNames(); } else { try (TreeWalk configWalk = new TreeWalk(repository)) { configWalk.addTree(rootTree); // The root tree may be part of the submodule walk, so we need to revert // it after this walk. int idx; for (idx = 0; !rootTree.first(); idx++) { rootTree.back(1); } try { configWalk.setRecursive(false); PathFilter filter = PathFilter.create(Constants.DOT_GIT_MODULES); configWalk.setFilter(filter); while (configWalk.next()) { if (filter.isDone(configWalk)) { modulesConfig = new BlobBasedConfig(null, repository, configWalk.getObjectId(0)); loadPathNames(); return this; } } modulesConfig = new Config(); pathToName = null; } finally { if (idx > 0) rootTree.next(idx); } } } return this; } private void loadPathNames() { pathToName = null; if (modulesConfig != null) { HashMap<String, String> pathNames = new HashMap<>(); for (String name : modulesConfig .getSubsections(ConfigConstants.CONFIG_SUBMODULE_SECTION)) { pathNames.put(modulesConfig.getString( ConfigConstants.CONFIG_SUBMODULE_SECTION, name, ConfigConstants.CONFIG_KEY_PATH), name); } pathToName = pathNames; } }
Checks whether the working tree contains a .gitmodules file. That's a hint that the repo contains submodules.
Params:
  • repository – the repository to check
Throws:
Returns:true if the working tree contains a .gitmodules file, false otherwise. Always returns false for bare repositories.
Since:3.6
/** * Checks whether the working tree contains a .gitmodules file. That's a * hint that the repo contains submodules. * * @param repository * the repository to check * @return <code>true</code> if the working tree contains a .gitmodules file, * <code>false</code> otherwise. Always returns <code>false</code> * for bare repositories. * @throws java.io.IOException * @throws CorruptObjectException if any. * @since 3.6 */
public static boolean containsGitModulesFile(Repository repository) throws IOException { if (repository.isBare()) { return false; } File modulesFile = new File(repository.getWorkTree(), Constants.DOT_GIT_MODULES); return (modulesFile.exists()); } private void lazyLoadModulesConfig() throws IOException, ConfigInvalidException { if (modulesConfig == null) { loadModulesConfig(); } } private String getModuleName(String modulePath) { String name = pathToName != null ? pathToName.get(modulePath) : null; return name != null ? name : modulePath; }
Set tree filter
Params:
Returns:this generator
/** * Set tree filter * * @param filter * a {@link org.eclipse.jgit.treewalk.filter.TreeFilter} object. * @return this generator */
public SubmoduleWalk setFilter(TreeFilter filter) { walk.setFilter(filter); return this; }
Set the tree iterator used for finding submodule entries
Params:
Throws:
Returns:this generator
/** * Set the tree iterator used for finding submodule entries * * @param iterator * an {@link org.eclipse.jgit.treewalk.AbstractTreeIterator} * object. * @return this generator * @throws org.eclipse.jgit.errors.CorruptObjectException */
public SubmoduleWalk setTree(AbstractTreeIterator iterator) throws CorruptObjectException { walk.addTree(iterator); return this; }
Set the tree used for finding submodule entries
Params:
Throws:
Returns:this generator
/** * Set the tree used for finding submodule entries * * @param treeId * an {@link org.eclipse.jgit.lib.AnyObjectId} object. * @return this generator * @throws java.io.IOException * @throws IncorrectObjectTypeException * if any. * @throws MissingObjectException * if any. */
public SubmoduleWalk setTree(AnyObjectId treeId) throws IOException { walk.addTree(treeId); return this; }
Reset generator and start new submodule walk
Returns:this generator
/** * Reset generator and start new submodule walk * * @return this generator */
public SubmoduleWalk reset() { repoConfig = repository.getConfig(); modulesConfig = null; pathToName = null; walk.reset(); return this; }
Get directory that will be the root of the submodule's local repository
Returns:submodule repository directory
/** * Get directory that will be the root of the submodule's local repository * * @return submodule repository directory */
public File getDirectory() { return getSubmoduleDirectory(repository, path); }
Advance to next submodule in the index tree. The object id and path of the next entry can be obtained by calling getObjectId() and getPath().
Throws:
Returns:true if entry found, false otherwise
/** * Advance to next submodule in the index tree. * * The object id and path of the next entry can be obtained by calling * {@link #getObjectId()} and {@link #getPath()}. * * @return true if entry found, false otherwise * @throws java.io.IOException */
public boolean next() throws IOException { while (walk.next()) { if (FileMode.GITLINK != walk.getFileMode(0)) continue; path = walk.getPathString(); return true; } path = null; return false; }
Get path of current submodule entry
Returns:path
/** * Get path of current submodule entry * * @return path */
public String getPath() { return path; }
Sets the RepositoryBuilderFactory to use for creating submodule repositories. If none is set, a plain RepositoryBuilder is used.
Params:
  • factory – to set
Since:5.6
/** * 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<?, ? extends Repository> getBuilder() { return factory != null ? factory.get() : new RepositoryBuilder(); }
The module name for the current submodule entry (used for the section name of .git/config)
Throws:
Since:4.10
Returns:name
/** * The module name for the current submodule entry (used for the section * name of .git/config) * * @since 4.10 * @return name * @throws ConfigInvalidException * @throws IOException */
public String getModuleName() throws IOException, ConfigInvalidException { lazyLoadModulesConfig(); return getModuleName(path); }
Get object id of current submodule entry
Returns:object id
/** * Get object id of current submodule entry * * @return object id */
public ObjectId getObjectId() { return walk.getObjectId(0); }
Get the configured path for current entry. This will be the value from the .gitmodules file in the current repository's working tree.
Throws:
Returns:configured path
/** * Get the configured path for current entry. This will be the value from * the .gitmodules file in the current repository's working tree. * * @return configured path * @throws org.eclipse.jgit.errors.ConfigInvalidException * @throws java.io.IOException */
public String getModulesPath() throws IOException, ConfigInvalidException { lazyLoadModulesConfig(); return modulesConfig.getString(ConfigConstants.CONFIG_SUBMODULE_SECTION, getModuleName(), ConfigConstants.CONFIG_KEY_PATH); }
Get the configured remote URL for current entry. This will be the value from the repository's config.
Throws:
Returns:configured URL
/** * Get the configured remote URL for current entry. This will be the value * from the repository's config. * * @return configured URL * @throws org.eclipse.jgit.errors.ConfigInvalidException * @throws java.io.IOException */
public String getConfigUrl() throws IOException, ConfigInvalidException { return repoConfig.getString(ConfigConstants.CONFIG_SUBMODULE_SECTION, getModuleName(), ConfigConstants.CONFIG_KEY_URL); }
Get the configured remote URL for current entry. This will be the value from the .gitmodules file in the current repository's working tree.
Throws:
Returns:configured URL
/** * Get the configured remote URL for current entry. This will be the value * from the .gitmodules file in the current repository's working tree. * * @return configured URL * @throws org.eclipse.jgit.errors.ConfigInvalidException * @throws java.io.IOException */
public String getModulesUrl() throws IOException, ConfigInvalidException { lazyLoadModulesConfig(); return modulesConfig.getString(ConfigConstants.CONFIG_SUBMODULE_SECTION, getModuleName(), ConfigConstants.CONFIG_KEY_URL); }
Get the configured update field for current entry. This will be the value from the repository's config.
Throws:
Returns:update value
/** * Get the configured update field for current entry. This will be the value * from the repository's config. * * @return update value * @throws org.eclipse.jgit.errors.ConfigInvalidException * @throws java.io.IOException */
public String getConfigUpdate() throws IOException, ConfigInvalidException { return repoConfig.getString(ConfigConstants.CONFIG_SUBMODULE_SECTION, getModuleName(), ConfigConstants.CONFIG_KEY_UPDATE); }
Get the configured update field for current entry. This will be the value from the .gitmodules file in the current repository's working tree.
Throws:
Returns:update value
/** * Get the configured update field for current entry. This will be the value * from the .gitmodules file in the current repository's working tree. * * @return update value * @throws org.eclipse.jgit.errors.ConfigInvalidException * @throws java.io.IOException */
public String getModulesUpdate() throws IOException, ConfigInvalidException { lazyLoadModulesConfig(); return modulesConfig.getString(ConfigConstants.CONFIG_SUBMODULE_SECTION, getModuleName(), ConfigConstants.CONFIG_KEY_UPDATE); }
Get the configured ignore field for the current entry. This will be the value from the .gitmodules file in the current repository's working tree.
Throws:
Returns:ignore value
Since:3.6
/** * Get the configured ignore field for the current entry. This will be the * value from the .gitmodules file in the current repository's working tree. * * @return ignore value * @throws org.eclipse.jgit.errors.ConfigInvalidException * @throws java.io.IOException * @since 3.6 */
public IgnoreSubmoduleMode getModulesIgnore() throws IOException, ConfigInvalidException { IgnoreSubmoduleMode mode = repoConfig.getEnum( IgnoreSubmoduleMode.values(), ConfigConstants.CONFIG_SUBMODULE_SECTION, getModuleName(), ConfigConstants.CONFIG_KEY_IGNORE, null); if (mode != null) { return mode; } lazyLoadModulesConfig(); return modulesConfig.getEnum(IgnoreSubmoduleMode.values(), ConfigConstants.CONFIG_SUBMODULE_SECTION, getModuleName(), ConfigConstants.CONFIG_KEY_IGNORE, IgnoreSubmoduleMode.NONE); }
Get repository for current submodule entry
Throws:
Returns:repository or null if non-existent
/** * Get repository for current submodule entry * * @return repository or null if non-existent * @throws java.io.IOException */
public Repository getRepository() throws IOException { return getSubmoduleRepository(repository.getWorkTree(), path, repository.getFS(), getBuilder()); }
Get commit id that HEAD points to in the current submodule's repository
Throws:
Returns:object id of HEAD reference
/** * Get commit id that HEAD points to in the current submodule's repository * * @return object id of HEAD reference * @throws java.io.IOException */
public ObjectId getHead() throws IOException { try (Repository subRepo = getRepository()) { if (subRepo == null) { return null; } return subRepo.resolve(Constants.HEAD); } }
Get ref that HEAD points to in the current submodule's repository
Throws:
Returns:ref name, null on failures
/** * Get ref that HEAD points to in the current submodule's repository * * @return ref name, null on failures * @throws java.io.IOException */
public String getHeadRef() throws IOException { try (Repository subRepo = getRepository()) { if (subRepo == null) { return null; } Ref head = subRepo.exactRef(Constants.HEAD); return head != null ? head.getLeaf().getName() : null; } }
Get the resolved remote URL for the current submodule.

This method resolves the value of getModulesUrl() to an absolute URL

Throws:
Returns:resolved remote URL
/** * Get the resolved remote URL for the current submodule. * <p> * This method resolves the value of {@link #getModulesUrl()} to an absolute * URL * * @return resolved remote URL * @throws java.io.IOException * @throws org.eclipse.jgit.errors.ConfigInvalidException */
public String getRemoteUrl() throws IOException, ConfigInvalidException { String url = getModulesUrl(); return url != null ? getSubmoduleRemoteUrl(repository, url) : null; }
{@inheritDoc}

Release any resources used by this walker's reader.

Since:4.0
/** * {@inheritDoc} * <p> * Release any resources used by this walker's reader. * * @since 4.0 */
@Override public void close() { walk.close(); } }