/*
 * Copyright (C) 2010, Christian Halstrick <christian.halstrick@sap.com>
 * Copyright (C) 2010, Chris Aniszczyk <caniszczyk@gmail.com>
 * and other copyright owners as documented in the project's IP log.
 *
 * 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
 *
 * 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.
 */
package org.eclipse.jgit.api;

import java.io.File;
import java.io.IOException;

import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.lib.RepositoryBuilder;
import org.eclipse.jgit.lib.RepositoryCache;
import org.eclipse.jgit.util.FS;

/**
 * Offers a "GitPorcelain"-like API to interact with a git repository.
 * <p>
 * The GitPorcelain commands are described in the <a href=
 * "http://www.kernel.org/pub/software/scm/git/docs/git.html#_high_level_commands_porcelain"
 * >Git Documentation</a>.
 * <p>
 * This class only offers methods to construct so-called command classes. Each
 * GitPorcelain command is represented by one command class.<br>
 * Example: this class offers a {@code commit()} method returning an instance of
 * the {@code CommitCommand} class. The {@code CommitCommand} class has setters
 * for all the arguments and options. The {@code CommitCommand} class also has a
 * {@code call} method to actually execute the commit. The following code show's
 * how to do a simple commit:
 *
 * <pre>
 * Git git = new Git(myRepo);
 * git.commit().setMessage(&quot;Fix393&quot;).setAuthor(developerIdent).call();
 * </pre>
 *
 * All mandatory parameters for commands have to be specified in the methods of
 * this class, the optional parameters have to be specified by the
 * setter-methods of the Command class.
 * <p>
 * This class is intended to be used internally (e.g. by JGit tests) or by
 * external components (EGit, third-party tools) when they need exactly the
 * functionality of a GitPorcelain command. There are use-cases where this class
 * is not optimal and where you should use the more low-level JGit classes. The
 * methods in this class may for example offer too much functionality or they
 * offer the functionality with the wrong arguments.
 */
public class Git implements AutoCloseable {
	/** The git repository this class is interacting with */
	private final Repository repo;

	private final boolean closeRepo;

	/**
	 * Open repository
	 *
	 * @param dir
	 *            the repository to open. May be either the GIT_DIR, or the
	 *            working tree directory that contains {@code .git}.
	 * @return a {@link org.eclipse.jgit.api.Git} object for the existing git
	 *         repository
	 * @throws java.io.IOException
	 */
	public static Git open(File dir) throws IOException {
		return open(dir, FS.DETECTED);
	}

	/**
	 * Open repository
	 *
	 * @param dir
	 *            the repository to open. May be either the GIT_DIR, or the
	 *            working tree directory that contains {@code .git}.
	 * @param fs
	 *            filesystem abstraction to use when accessing the repository.
	 * @return a {@link org.eclipse.jgit.api.Git} object for the existing git
	 *         repository. Closing this instance will close the repo.
	 * @throws java.io.IOException
	 */
	public static Git open(File dir, FS fs) throws IOException {
		RepositoryCache.FileKey key;

		key = RepositoryCache.FileKey.lenient(dir, fs);
		Repository db = new RepositoryBuilder().setFS(fs).setGitDir(key.getFile())
				.setMustExist(true).build();
		return new Git(db, true);
	}

	/**
	 * Wrap repository
	 *
	 * @param repo
	 *            the git repository this class is interacting with;
	 *            {@code null} is not allowed.
	 * @return a {@link org.eclipse.jgit.api.Git} object for the existing git
	 *         repository. The caller is responsible for closing the repository;
	 *         {@link #close()} on this instance does not close the repo.
	 */
	public static Git wrap(Repository repo) {
		return new Git(repo);
	}

	/**
	 * {@inheritDoc}
	 * <p>
	 * Free resources associated with this instance.
	 * <p>
	 * If the repository was opened by a static factory method in this class,
	 * then this method calls {@link Repository#close()} on the underlying
	 * repository instance. (Whether this actually releases underlying
	 * resources, such as file handles, may vary; see {@link Repository} for
	 * more details.)
	 * <p>
	 * If the repository was created by a caller and passed into
	 * {@link #Git(Repository)} or a static factory method in this class, then
	 * this method does not call close on the underlying repository.
	 * <p>
	 * In all cases, after calling this method you should not use this
	 * {@link Git} instance anymore.
	 *
	 * @since 3.2
	 */
	@Override
	public void close() {
		if (closeRepo)
			repo.close();
	}

	/**
	 * Return a command object to execute a {@code clone} command
	 *
	 * @see <a href=
	 *      "http://www.kernel.org/pub/software/scm/git/docs/git-clone.html"
	 *      >Git documentation about clone</a>
	 * @return a {@link org.eclipse.jgit.api.CloneCommand} used to collect all
	 *         optional parameters and to finally execute the {@code clone}
	 *         command
	 */
	public static CloneCommand cloneRepository() {
		return new CloneCommand();
	}

	/**
	 * Return a command to list remote branches/tags without a local repository.
	 *
	 * @return a {@link org.eclipse.jgit.api.LsRemoteCommand}
	 * @since 3.1
	 */
	public static LsRemoteCommand lsRemoteRepository() {
		return new LsRemoteCommand(null);
	}

	/**
	 * Return a command object to execute a {@code init} command
	 *
	 * @see <a href=
	 *      "http://www.kernel.org/pub/software/scm/git/docs/git-init.html" >Git
	 *      documentation about init</a>
	 * @return a {@link org.eclipse.jgit.api.InitCommand} used to collect all
	 *         optional parameters and to finally execute the {@code init}
	 *         command
	 */
	public static InitCommand init() {
		return new InitCommand();
	}

	/**
	 * Construct a new {@link org.eclipse.jgit.api.Git} object which can
	 * interact with the specified git repository.
	 * <p>
	 * All command classes returned by methods of this class will always
	 * interact with this git repository.
	 * <p>
	 * The caller is responsible for closing the repository; {@link #close()} on
	 * this instance does not close the repo.
	 *
	 * @param repo
	 *            the git repository this class is interacting with;
	 *            {@code null} is not allowed.
	 */
	public Git(Repository repo) {
		this(repo, false);
	}

	Git(Repository repo, boolean closeRepo) {
		if (repo == null)
			throw new NullPointerException();
		this.repo = repo;
		this.closeRepo = closeRepo;
	}

	/**
	 * Return a command object to execute a {@code Commit} command
	 *
	 * @see <a href=
	 *      "http://www.kernel.org/pub/software/scm/git/docs/git-commit.html"
	 *      >Git documentation about Commit</a>
	 * @return a {@link org.eclipse.jgit.api.CommitCommand} used to collect all
	 *         optional parameters and to finally execute the {@code Commit}
	 *         command
	 */
	public CommitCommand commit() {
		return new CommitCommand(repo);
	}

	/**
	 * Return a command object to execute a {@code Log} command
	 *
	 * @see <a href=
	 *      "http://www.kernel.org/pub/software/scm/git/docs/git-log.html" >Git
	 *      documentation about Log</a>
	 * @return a {@link org.eclipse.jgit.api.LogCommand} used to collect all
	 *         optional parameters and to finally execute the {@code Log}
	 *         command
	 */
	public LogCommand log() {
		return new LogCommand(repo);
	}

	/**
	 * Return a command object to execute a {@code Merge} command
	 *
	 * @see <a href=
	 *      "http://www.kernel.org/pub/software/scm/git/docs/git-merge.html"
	 *      >Git documentation about Merge</a>
	 * @return a {@link org.eclipse.jgit.api.MergeCommand} used to collect all
	 *         optional parameters and to finally execute the {@code Merge}
	 *         command
	 */
	public MergeCommand merge() {
		return new MergeCommand(repo);
	}

	/**
	 * Return a command object to execute a {@code Pull} command
	 *
	 * @return a {@link org.eclipse.jgit.api.PullCommand}
	 */
	public PullCommand pull() {
		return new PullCommand(repo);
	}

	/**
	 * Return a command object used to create branches
	 *
	 * @return a {@link org.eclipse.jgit.api.CreateBranchCommand}
	 */
	public CreateBranchCommand branchCreate() {
		return new CreateBranchCommand(repo);
	}

	/**
	 * Return a command object used to delete branches
	 *
	 * @return a {@link org.eclipse.jgit.api.DeleteBranchCommand}
	 */
	public DeleteBranchCommand branchDelete() {
		return new DeleteBranchCommand(repo);
	}

	/**
	 * Return a command object used to list branches
	 *
	 * @return a {@link org.eclipse.jgit.api.ListBranchCommand}
	 */
	public ListBranchCommand branchList() {
		return new ListBranchCommand(repo);
	}

	/**
	 *
	 * Return a command object used to list tags
	 *
	 * @return a {@link org.eclipse.jgit.api.ListTagCommand}
	 */
	public ListTagCommand tagList() {
		return new ListTagCommand(repo);
	}

	/**
	 * Return a command object used to rename branches
	 *
	 * @return a {@link org.eclipse.jgit.api.RenameBranchCommand}
	 */
	public RenameBranchCommand branchRename() {
		return new RenameBranchCommand(repo);
	}

	/**
	 * Return a command object to execute a {@code Add} command
	 *
	 * @see <a href=
	 *      "http://www.kernel.org/pub/software/scm/git/docs/git-add.html" >Git
	 *      documentation about Add</a>
	 * @return a {@link org.eclipse.jgit.api.AddCommand} used to collect all
	 *         optional parameters and to finally execute the {@code Add}
	 *         command
	 */
	public AddCommand add() {
		return new AddCommand(repo);
	}

	/**
	 * Return a command object to execute a {@code Tag} command
	 *
	 * @see <a href=
	 *      "http://www.kernel.org/pub/software/scm/git/docs/git-tag.html" >Git
	 *      documentation about Tag</a>
	 * @return a {@link org.eclipse.jgit.api.TagCommand} used to collect all
	 *         optional parameters and to finally execute the {@code Tag}
	 *         command
	 */
	public TagCommand tag() {
		return new TagCommand(repo);
	}

	/**
	 * Return a command object to execute a {@code Fetch} command
	 *
	 * @see <a href=
	 *      "http://www.kernel.org/pub/software/scm/git/docs/git-fetch.html"
	 *      >Git documentation about Fetch</a>
	 * @return a {@link org.eclipse.jgit.api.FetchCommand} used to collect all
	 *         optional parameters and to finally execute the {@code Fetch}
	 *         command
	 */
	public FetchCommand fetch() {
		return new FetchCommand(repo);
	}

	/**
	 * Return a command object to execute a {@code Push} command
	 *
	 * @see <a href=
	 *      "http://www.kernel.org/pub/software/scm/git/docs/git-push.html" >Git
	 *      documentation about Push</a>
	 * @return a {@link org.eclipse.jgit.api.PushCommand} used to collect all
	 *         optional parameters and to finally execute the {@code Push}
	 *         command
	 */
	public PushCommand push() {
		return new PushCommand(repo);
	}

	/**
	 * Return a command object to execute a {@code cherry-pick} command
	 *
	 * @see <a href=
	 *      "http://www.kernel.org/pub/software/scm/git/docs/git-cherry-pick.html"
	 *      >Git documentation about cherry-pick</a>
	 * @return a {@link org.eclipse.jgit.api.CherryPickCommand} used to collect
	 *         all optional parameters and to finally execute the
	 *         {@code cherry-pick} command
	 */
	public CherryPickCommand cherryPick() {
		return new CherryPickCommand(repo);
	}

	/**
	 * Return a command object to execute a {@code revert} command
	 *
	 * @see <a href=
	 *      "http://www.kernel.org/pub/software/scm/git/docs/git-revert.html"
	 *      >Git documentation about reverting changes</a>
	 * @return a {@link org.eclipse.jgit.api.RevertCommand} used to collect all
	 *         optional parameters and to finally execute the
	 *         {@code cherry-pick} command
	 */
	public RevertCommand revert() {
		return new RevertCommand(repo);
	}

	/**
	 * Return a command object to execute a {@code Rebase} command
	 *
	 * @see <a href=
	 *      "http://www.kernel.org/pub/software/scm/git/docs/git-rebase.html"
	 *      >Git documentation about rebase</a>
	 * @return a {@link org.eclipse.jgit.api.RebaseCommand} used to collect all
	 *         optional parameters and to finally execute the {@code rebase}
	 *         command
	 */
	public RebaseCommand rebase() {
		return new RebaseCommand(repo);
	}

	/**
	 * Return a command object to execute a {@code rm} command
	 *
	 * @see <a href=
	 *      "http://www.kernel.org/pub/software/scm/git/docs/git-rm.html" >Git
	 *      documentation about rm</a>
	 * @return a {@link org.eclipse.jgit.api.RmCommand} used to collect all
	 *         optional parameters and to finally execute the {@code rm} command
	 */
	public RmCommand rm() {
		return new RmCommand(repo);
	}

	/**
	 * Return a command object to execute a {@code checkout} command
	 *
	 * @see <a href=
	 *      "http://www.kernel.org/pub/software/scm/git/docs/git-checkout.html"
	 *      >Git documentation about checkout</a>
	 * @return a {@link org.eclipse.jgit.api.CheckoutCommand} used to collect
	 *         all optional parameters and to finally execute the
	 *         {@code checkout} command
	 */
	public CheckoutCommand checkout() {
		return new CheckoutCommand(repo);
	}

	/**
	 * Return a command object to execute a {@code reset} command
	 *
	 * @see <a href=
	 *      "http://www.kernel.org/pub/software/scm/git/docs/git-reset.html"
	 *      >Git documentation about reset</a>
	 * @return a {@link org.eclipse.jgit.api.ResetCommand} used to collect all
	 *         optional parameters and to finally execute the {@code reset}
	 *         command
	 */
	public ResetCommand reset() {
		return new ResetCommand(repo);
	}

	/**
	 * Return a command object to execute a {@code status} command
	 *
	 * @see <a href=
	 *      "http://www.kernel.org/pub/software/scm/git/docs/git-status.html"
	 *      >Git documentation about status</a>
	 * @return a {@link org.eclipse.jgit.api.StatusCommand} used to collect all
	 *         optional parameters and to finally execute the {@code status}
	 *         command
	 */
	public StatusCommand status() {
		return new StatusCommand(repo);
	}

	/**
	 * Return a command to create an archive from a tree
	 *
	 * @return a {@link org.eclipse.jgit.api.ArchiveCommand}
	 * @since 3.1
	 */
	public ArchiveCommand archive() {
		return new ArchiveCommand(repo);
	}

	/**
	 * Return a command to add notes to an object
	 *
	 * @return a {@link org.eclipse.jgit.api.AddNoteCommand}
	 */
	public AddNoteCommand notesAdd() {
		return new AddNoteCommand(repo);
	}

	/**
	 * Return a command to remove notes on an object
	 *
	 * @return a {@link org.eclipse.jgit.api.RemoveNoteCommand}
	 */
	public RemoveNoteCommand notesRemove() {
		return new RemoveNoteCommand(repo);
	}

	/**
	 * Return a command to list all notes
	 *
	 * @return a {@link org.eclipse.jgit.api.ListNotesCommand}
	 */
	public ListNotesCommand notesList() {
		return new ListNotesCommand(repo);
	}

	/**
	 * Return a command to show notes on an object
	 *
	 * @return a {@link org.eclipse.jgit.api.ShowNoteCommand}
	 */
	public ShowNoteCommand notesShow() {
		return new ShowNoteCommand(repo);
	}

	/**
	 * Return a command object to execute a {@code ls-remote} command
	 *
	 * @see <a href=
	 *      "http://www.kernel.org/pub/software/scm/git/docs/git-ls-remote.html"
	 *      >Git documentation about ls-remote</a>
	 * @return a {@link org.eclipse.jgit.api.LsRemoteCommand} used to collect
	 *         all optional parameters and to finally execute the {@code status}
	 *         command
	 */
	public LsRemoteCommand lsRemote() {
		return new LsRemoteCommand(repo);
	}

	/**
	 * Return a command object to execute a {@code clean} command
	 *
	 * @see <a href=
	 *      "http://www.kernel.org/pub/software/scm/git/docs/git-clean.html"
	 *      >Git documentation about Clean</a>
	 * @return a {@link org.eclipse.jgit.api.CleanCommand} used to collect all
	 *         optional parameters and to finally execute the {@code clean}
	 *         command
	 */
	public CleanCommand clean() {
		return new CleanCommand(repo);
	}

	/**
	 * Return a command object to execute a {@code blame} command
	 *
	 * @see <a href=
	 *      "http://www.kernel.org/pub/software/scm/git/docs/git-blame.html"
	 *      >Git documentation about Blame</a>
	 * @return a {@link org.eclipse.jgit.api.BlameCommand} used to collect all
	 *         optional parameters and to finally execute the {@code blame}
	 *         command
	 */
	public BlameCommand blame() {
		return new BlameCommand(repo);
	}

	/**
	 * Return a command object to execute a {@code reflog} command
	 *
	 * @see <a href=
	 *      "http://www.kernel.org/pub/software/scm/git/docs/git-reflog.html"
	 *      >Git documentation about reflog</a>
	 * @return a {@link org.eclipse.jgit.api.ReflogCommand} used to collect all
	 *         optional parameters and to finally execute the {@code reflog}
	 *         command
	 */
	public ReflogCommand reflog() {
		return new ReflogCommand(repo);
	}

	/**
	 * Return a command object to execute a {@code diff} command
	 *
	 * @see <a href=
	 *      "http://www.kernel.org/pub/software/scm/git/docs/git-diff.html" >Git
	 *      documentation about diff</a>
	 * @return a {@link org.eclipse.jgit.api.DiffCommand} used to collect all
	 *         optional parameters and to finally execute the {@code diff}
	 *         command
	 */
	public DiffCommand diff() {
		return new DiffCommand(repo);
	}

	/**
	 * Return a command object used to delete tags
	 *
	 * @return a {@link org.eclipse.jgit.api.DeleteTagCommand}
	 */
	public DeleteTagCommand tagDelete() {
		return new DeleteTagCommand(repo);
	}

	/**
	 * Return a command object to execute a {@code submodule add} command
	 *
	 * @return a {@link org.eclipse.jgit.api.SubmoduleAddCommand} used to add a
	 *         new submodule to a parent repository
	 */
	public SubmoduleAddCommand submoduleAdd() {
		return new SubmoduleAddCommand(repo);
	}

	/**
	 * Return a command object to execute a {@code submodule init} command
	 *
	 * @return a {@link org.eclipse.jgit.api.SubmoduleInitCommand} used to
	 *         initialize the repository's config with settings from the
	 *         .gitmodules file in the working tree
	 */
	public SubmoduleInitCommand submoduleInit() {
		return new SubmoduleInitCommand(repo);
	}

	/**
	 * Returns a command object to execute a {@code submodule deinit} command
	 *
	 * @return a {@link org.eclipse.jgit.api.SubmoduleDeinitCommand} used to
	 *         remove a submodule's working tree manifestation
	 * @since 4.10
	 */
	public SubmoduleDeinitCommand submoduleDeinit() {
		return new SubmoduleDeinitCommand(repo);
	}

	/**
	 * Returns a command object to execute a {@code submodule status} command
	 *
	 * @return a {@link org.eclipse.jgit.api.SubmoduleStatusCommand} used to
	 *         report the status of a repository's configured submodules
	 */
	public SubmoduleStatusCommand submoduleStatus() {
		return new SubmoduleStatusCommand(repo);
	}

	/**
	 * Return a command object to execute a {@code submodule sync} command
	 *
	 * @return a {@link org.eclipse.jgit.api.SubmoduleSyncCommand} used to
	 *         update the URL of a submodule from the parent repository's
	 *         .gitmodules file
	 */
	public SubmoduleSyncCommand submoduleSync() {
		return new SubmoduleSyncCommand(repo);
	}

	/**
	 * Return a command object to execute a {@code submodule update} command
	 *
	 * @return a {@link org.eclipse.jgit.api.SubmoduleUpdateCommand} used to
	 *         update the submodules in a repository to the configured revision
	 */
	public SubmoduleUpdateCommand submoduleUpdate() {
		return new SubmoduleUpdateCommand(repo);
	}

	/**
	 * Return a command object used to list stashed commits
	 *
	 * @return a {@link org.eclipse.jgit.api.StashListCommand}
	 */
	public StashListCommand stashList() {
		return new StashListCommand(repo);
	}

	/**
	 * Return a command object used to create a stashed commit
	 *
	 * @return a {@link org.eclipse.jgit.api.StashCreateCommand}
	 * @since 2.0
	 */
	public StashCreateCommand stashCreate() {
		return new StashCreateCommand(repo);
	}

	/**
	 * Returs a command object used to apply a stashed commit
	 *
	 * @return a {@link org.eclipse.jgit.api.StashApplyCommand}
	 * @since 2.0
	 */
	public StashApplyCommand stashApply() {
		return new StashApplyCommand(repo);
	}

	/**
	 * Return a command object used to drop a stashed commit
	 *
	 * @return a {@link org.eclipse.jgit.api.StashDropCommand}
	 * @since 2.0
	 */
	public StashDropCommand stashDrop() {
		return new StashDropCommand(repo);
	}

	/**
	 * Return a command object to execute a {@code apply} command
	 *
	 * @see <a href=
	 *      "http://www.kernel.org/pub/software/scm/git/docs/git-apply.html"
	 *      >Git documentation about apply</a>
	 * @return a {@link org.eclipse.jgit.api.ApplyCommand} used to collect all
	 *         optional parameters and to finally execute the {@code apply}
	 *         command
	 * @since 2.0
	 */
	public ApplyCommand apply() {
		return new ApplyCommand(repo);
	}

	/**
	 * Return a command object to execute a {@code gc} command
	 *
	 * @see <a href=
	 *      "http://www.kernel.org/pub/software/scm/git/docs/git-gc.html" >Git
	 *      documentation about gc</a>
	 * @return a {@link org.eclipse.jgit.api.GarbageCollectCommand} used to
	 *         collect all optional parameters and to finally execute the
	 *         {@code gc} command
	 * @since 2.2
	 */
	public GarbageCollectCommand gc() {
		return new GarbageCollectCommand(repo);
	}

	/**
	 * Return a command object to find human-readable names of revisions.
	 *
	 * @return a {@link org.eclipse.jgit.api.NameRevCommand}.
	 * @since 3.0
	 */
	public NameRevCommand nameRev() {
		return new NameRevCommand(repo);
	}

	/**
	 * Return a command object to come up with a short name that describes a
	 * commit in terms of the nearest git tag.
	 *
	 * @return a {@link org.eclipse.jgit.api.DescribeCommand}.
	 * @since 3.2
	 */
	public DescribeCommand describe() {
		return new DescribeCommand(repo);
	}

	/**
	 * Return a command used to list the available remotes.
	 *
	 * @return a {@link org.eclipse.jgit.api.RemoteListCommand}
	 * @since 4.2
	 */
	public RemoteListCommand remoteList() {
		return new RemoteListCommand(repo);
	}

	/**
	 * Return a command used to add a new remote.
	 *
	 * @return a {@link org.eclipse.jgit.api.RemoteAddCommand}
	 * @since 4.2
	 */
	public RemoteAddCommand remoteAdd() {
		return new RemoteAddCommand(repo);
	}

	/**
	 * Return a command used to remove an existing remote.
	 *
	 * @return a {@link org.eclipse.jgit.api.RemoteRemoveCommand}
	 * @since 4.2
	 */
	public RemoteRemoveCommand remoteRemove() {
		return new RemoteRemoveCommand(repo);
	}

	/**
	 * Return a command used to change the URL of an existing remote.
	 *
	 * @return a {@link org.eclipse.jgit.api.RemoteSetUrlCommand}
	 * @since 4.2
	 */
	public RemoteSetUrlCommand remoteSetUrl() {
		return new RemoteSetUrlCommand(repo);
	}

	/**
	 * Get repository
	 *
	 * @return the git repository this class is interacting with; see
	 *         {@link #close()} for notes on closing this repository.
	 */
	public Repository getRepository() {
		return repo;
	}

	/** {@inheritDoc} */
	@Override
	public String toString() {
		return "Git[" + repo + "]"; //$NON-NLS-1$//$NON-NLS-2$
	}
}
