/*
 * 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
 */
public class SubmoduleWalk implements AutoCloseable {

	/**
	 * The values for the config parameter submodule.&lt;name&gt;.ignore
	 *
	 * @since 3.6
	 */
	public enum IgnoreSubmoduleMode {
		/**
		 * Ignore all modifications to submodules
		 */
		ALL,

		/**
		 * Ignore changes to the working tree of a submodule
		 */
		DIRTY,

		/**
		 * Ignore changes to untracked files in the working tree of a submodule
		 */
		UNTRACKED,

		/**
		 * Ignore nothing. That's the default
		 */
		NONE;
	}

	/**
	 * 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
	 *             if an IO error occurred
	 */
	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
	 *
	 * @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
	 *             if an IO error occurred
	 */
	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
	 *
	 * @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
	 *             if an IO error occurred
	 */
	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
	 *
	 * @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
	 *
	 * @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
	 *             if an IO error occurred
	 */
	public static Repository getSubmoduleRepository(final Repository parent,
			final String path) throws IOException {
		return getSubmoduleRepository(parent.getWorkTree(), path,
				parent.getFS());
	}

	/**
	 * 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
	 *             if an IO error occurred
	 */
	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
	 *
	 * @param parent
	 *            {@link Repository} that contains the submodule
	 * @param path
	 *            of the working tree of the submodule
	 * @param fs
	 *            the file system abstraction to be used
	 * @return repository or null if repository doesn't exist
	 * @throws IOException
	 *             if an IO error occurred
	 * @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
	 *
	 * @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
	 *             if an IO error occurred
	 * @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.
	 * <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
	 *             if an IO error occurred
	 */
	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
	 *
	 * @param repository
	 *            the {@link org.eclipse.jgit.lib.Repository}.
	 * @throws java.io.IOException
	 *             if an IO error occurred
	 */
	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.
	 *
	 * @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 {@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 {@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
	 *             if an IO error occurred
	 */
	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 {@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
	 *             if .gitmodules config is invalid
	 */
	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.
	 *
	 * @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
	 *             if an IO error occurred
	 * @throws CorruptObjectException
	 *             if a corrupt object was found
	 * @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
	 *
	 * @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
	 *
	 * @param iterator
	 *            an {@link org.eclipse.jgit.treewalk.AbstractTreeIterator}
	 *            object.
	 * @return this generator
	 * @throws org.eclipse.jgit.errors.CorruptObjectException
	 *             if a corrupt object was found
	 */
	public SubmoduleWalk setTree(AbstractTreeIterator iterator)
			throws CorruptObjectException {
		walk.addTree(iterator);
		return this;
	}

	/**
	 * 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
	 *             if an IO error occurred
	 * @throws IncorrectObjectTypeException
	 *             if object has unexpected type
	 * @throws MissingObjectException
	 *             if object is missing
	 */
	public SubmoduleWalk setTree(AnyObjectId treeId) throws IOException {
		walk.addTree(treeId);
		return this;
	}

	/**
	 * 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
	 *
	 * @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
	 * {@link #getObjectId()} and {@link #getPath()}.
	 *
	 * @return true if entry found, false otherwise
	 * @throws java.io.IOException
	 *             if an IO error occurred
	 */
	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
	 *
	 * @return path
	 */
	public String getPath() {
		return path;
	}

	/**
	 * 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)
	 *
	 * @since 4.10
	 * @return name of the submodule
	 * @throws ConfigInvalidException
	 *             if the .gitmodules config is invalid
	 * @throws IOException
	 *             if an IO error occurred
	 */
	public String getModuleName() throws IOException, ConfigInvalidException {
		lazyLoadModulesConfig();
		return getModuleName(path);
	}

	/**
	 * 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.
	 *
	 * @return configured path
	 * @throws org.eclipse.jgit.errors.ConfigInvalidException
	 *             if .gitmodules config is invalid
	 * @throws java.io.IOException
	 *             if an IO error occurred
	 */
	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.
	 *
	 * @return configured URL
	 * @throws org.eclipse.jgit.errors.ConfigInvalidException
	 *             if .gitmodules config is invalid
	 * @throws java.io.IOException
	 *             if an IO error occurred
	 */
	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.
	 *
	 * @return configured URL
	 * @throws org.eclipse.jgit.errors.ConfigInvalidException
	 *             if .gitmodules config is invalid
	 * @throws java.io.IOException
	 *             if an IO error occurred
	 */
	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.
	 *
	 * @return update value
	 * @throws org.eclipse.jgit.errors.ConfigInvalidException
	 *             if .gitmodules config is invalid
	 * @throws java.io.IOException
	 *             if an IO error occurred
	 */
	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.
	 *
	 * @return update value
	 * @throws org.eclipse.jgit.errors.ConfigInvalidException
	 *             if .gitmodules config is invalid
	 * @throws java.io.IOException
	 *             if an IO error occurred
	 */
	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.
	 *
	 * @return ignore value
	 * @throws org.eclipse.jgit.errors.ConfigInvalidException
	 *             if .gitmodules config is invalid
	 * @throws java.io.IOException
	 *             if an IO error occurred
	 * @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
	 *
	 * @return repository or null if non-existent
	 * @throws java.io.IOException
	 *             if an IO error occurred
	 */
	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
	 *
	 * @return object id of HEAD reference
	 * @throws java.io.IOException
	 *             if an IO error occurred
	 */
	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
	 *
	 * @return ref name, null on failures
	 * @throws java.io.IOException
	 *             if an IO error occurred
	 */
	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.
	 * <p>
	 * This method resolves the value of {@link #getModulesUrl()} to an absolute
	 * URL
	 *
	 * @return resolved remote URL
	 * @throws java.io.IOException
	 *             if an IO error occurred
	 * @throws org.eclipse.jgit.errors.ConfigInvalidException
	 *             if .gitmodules config is invalid
	 */
	public String getRemoteUrl() throws IOException, ConfigInvalidException {
		String url = getModulesUrl();
		return url != null ? getSubmoduleRemoteUrl(repository, url) : null;
	}

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