Further cleanup of exceptions in Git API

- Translate internal exceptions to corresponding API exception
- Do not catch GitAPI exceptions internally to an internal
exception. Just pass them to caller
- Mention thrown exceptions in javadoc

Change-Id: I9044cf86d2b0bcc8b63b7cc016e1bf0055a62053
Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/ApplyCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/ApplyCommand.java
index 8658b07..32abf86 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/ApplyCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/ApplyCommand.java
@@ -102,8 +102,12 @@ public ApplyCommand setPatch(InputStream in) {
 	 * method twice on an instance.
 	 *
 	 * @return an {@link ApplyResult} object representing the command result
+	 * @throws GitAPIException
+	 * @throws PatchFormatException
+	 * @throws PatchApplyException
 	 */
-	public ApplyResult call() throws GitAPIException {
+	public ApplyResult call() throws GitAPIException, PatchFormatException,
+			PatchApplyException {
 		checkCallable();
 		ApplyResult r = new ApplyResult();
 		try {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/CherryPickCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/CherryPickCommand.java
index 41265e8..b5bf119 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/CherryPickCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/CherryPickCommand.java
@@ -47,10 +47,14 @@
 import java.util.LinkedList;
 import java.util.List;
 
+import org.eclipse.jgit.api.errors.ConcurrentRefUpdateException;
 import org.eclipse.jgit.api.errors.GitAPIException;
 import org.eclipse.jgit.api.errors.JGitInternalException;
 import org.eclipse.jgit.api.errors.MultipleParentsNotAllowedException;
 import org.eclipse.jgit.api.errors.NoHeadException;
+import org.eclipse.jgit.api.errors.NoMessageException;
+import org.eclipse.jgit.api.errors.UnmergedPathsException;
+import org.eclipse.jgit.api.errors.WrongRepositoryStateException;
 import org.eclipse.jgit.dircache.DirCacheCheckout;
 import org.eclipse.jgit.internal.JGitText;
 import org.eclipse.jgit.lib.AnyObjectId;
@@ -94,8 +98,16 @@ protected CherryPickCommand(Repository repo) {
 	 * invocation of the command. Don't call this method twice on an instance.
 	 *
 	 * @return the result of the cherry-pick
+	 * @throws GitAPIException
+	 * @throws WrongRepositoryStateException
+	 * @throws ConcurrentRefUpdateException
+	 * @throws UnmergedPathsException
+	 * @throws NoMessageException
+	 * @throws NoHeadException
 	 */
-	public CherryPickResult call() throws GitAPIException {
+	public CherryPickResult call() throws GitAPIException, NoMessageException,
+			UnmergedPathsException, ConcurrentRefUpdateException,
+			WrongRepositoryStateException, NoHeadException {
 		RevCommit newHead = null;
 		List<Ref> cherryPickedRefs = new LinkedList<Ref>();
 		checkCallable();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/CleanCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/CleanCommand.java
index 341be91..1c19e93 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/CleanCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/CleanCommand.java
@@ -51,6 +51,7 @@
 
 import org.eclipse.jgit.api.errors.GitAPIException;
 import org.eclipse.jgit.api.errors.JGitInternalException;
+import org.eclipse.jgit.errors.NoWorkTreeException;
 import org.eclipse.jgit.lib.Repository;
 import org.eclipse.jgit.util.FileUtils;
 
@@ -81,8 +82,10 @@ protected CleanCommand(Repository repo) {
 	 * call to {@link #call()})
 	 *
 	 * @return a set of strings representing each file cleaned.
+	 * @throws GitAPIException
+	 * @throws NoWorkTreeException
 	 */
-	public Set<String> call() throws GitAPIException {
+	public Set<String> call() throws NoWorkTreeException, GitAPIException {
 		Set<String> files = new TreeSet<String>();
 		try {
 			StatusCommand command = new StatusCommand(repo);
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/CloneCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/CloneCommand.java
index 23bbc2a..067e92a 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/CloneCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/CloneCommand.java
@@ -113,8 +113,12 @@ public CloneCommand() {
 	 * Executes the {@code Clone} command.
 	 *
 	 * @return the newly created {@code Git} object with associated repository
+	 * @throws InvalidRemoteException
+	 * @throws org.eclipse.jgit.api.errors.TransportException
+	 * @throws GitAPIException
 	 */
-	public Git call() throws GitAPIException {
+	public Git call() throws GitAPIException, InvalidRemoteException,
+			org.eclipse.jgit.api.errors.TransportException {
 		try {
 			URIish u = new URIish(uri);
 			Repository repository = init(u);
@@ -124,10 +128,9 @@ public Git call() throws GitAPIException {
 			return new Git(repository);
 		} catch (IOException ioe) {
 			throw new JGitInternalException(ioe.getMessage(), ioe);
-		} catch (InvalidRemoteException e) {
-			throw new JGitInternalException(e.getMessage(), e);
 		} catch (URISyntaxException e) {
-			throw new JGitInternalException(e.getMessage(), e);
+			throw new InvalidRemoteException(MessageFormat.format(
+					JGitText.get().invalidRemote, remote));
 		}
 	}
 
@@ -144,7 +147,9 @@ private Repository init(URIish u) throws GitAPIException {
 	}
 
 	private FetchResult fetch(Repository clonedRepo, URIish u)
-			throws URISyntaxException, IOException, GitAPIException {
+			throws URISyntaxException,
+			org.eclipse.jgit.api.errors.TransportException, IOException,
+			GitAPIException {
 		// create the remote config and save it
 		RemoteConfig config = new RemoteConfig(clonedRepo.getConfig(), remote);
 		config.addURI(u);
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/FetchCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/FetchCommand.java
index 6df244b..69c4923 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/FetchCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/FetchCommand.java
@@ -135,8 +135,7 @@ public FetchResult call() throws GitAPIException, InvalidRemoteException,
 					JGitText.get().invalidRemote, remote), e);
 		} catch (TransportException e) {
 			throw new org.eclipse.jgit.api.errors.TransportException(
-					JGitText.get().exceptionCaughtDuringExecutionOfFetchCommand,
-					e);
+					e.getMessage(), e);
 		} catch (URISyntaxException e) {
 			throw new InvalidRemoteException(MessageFormat.format(
 					JGitText.get().invalidRemote, remote));
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/LsRemoteCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/LsRemoteCommand.java
index b041f33..c450ea9 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/LsRemoteCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/LsRemoteCommand.java
@@ -148,6 +148,7 @@ public LsRemoteCommand setUploadPack(String uploadPack) {
 	 *             for errors that occurs during transport
 	 */
 	public Collection<Ref> call() throws GitAPIException,
+			InvalidRemoteException,
 			org.eclipse.jgit.api.errors.TransportException {
 		checkCallable();
 
@@ -186,8 +187,8 @@ public Collection<Ref> call() throws GitAPIException,
 					JGitText.get().exceptionCaughtDuringExecutionOfLsRemoteCommand,
 					e);
 		} catch (TransportException e) {
-				throw new org.eclipse.jgit.api.errors.TransportException(
-					JGitText.get().exceptionCaughtDuringExecutionOfLsRemoteCommand,
+			throw new org.eclipse.jgit.api.errors.TransportException(
+					e.getMessage(),
 					e);
 		} finally {
 			if (fc != null)
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/PullCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/PullCommand.java
index 86d38fb..fa425d3 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/PullCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/PullCommand.java
@@ -48,16 +48,12 @@
 
 import org.eclipse.jgit.api.RebaseCommand.Operation;
 import org.eclipse.jgit.api.errors.CanceledException;
-import org.eclipse.jgit.api.errors.CheckoutConflictException;
-import org.eclipse.jgit.api.errors.ConcurrentRefUpdateException;
 import org.eclipse.jgit.api.errors.DetachedHeadException;
 import org.eclipse.jgit.api.errors.GitAPIException;
 import org.eclipse.jgit.api.errors.InvalidConfigurationException;
-import org.eclipse.jgit.api.errors.InvalidMergeHeadsException;
 import org.eclipse.jgit.api.errors.InvalidRemoteException;
 import org.eclipse.jgit.api.errors.JGitInternalException;
 import org.eclipse.jgit.api.errors.NoHeadException;
-import org.eclipse.jgit.api.errors.NoMessageException;
 import org.eclipse.jgit.api.errors.RefNotFoundException;
 import org.eclipse.jgit.api.errors.WrongRepositoryStateException;
 import org.eclipse.jgit.internal.JGitText;
@@ -109,11 +105,21 @@ public PullCommand setProgressMonitor(ProgressMonitor monitor) {
 	 * command. Don't call this method twice on an instance.
 	 *
 	 * @return the result of the pull
+	 * @throws WrongRepositoryStateException
+	 * @throws InvalidConfigurationException
+	 * @throws DetachedHeadException
+	 * @throws InvalidRemoteException
+	 * @throws CanceledException
+	 * @throws RefNotFoundException
+	 * @throws NoHeadException
+	 * @throws org.eclipse.jgit.api.errors.TransportException
+	 * @throws GitAPIException
 	 */
-	public PullResult call() throws GitAPIException, WrongRepositoryStateException,
-			InvalidConfigurationException, DetachedHeadException,
-			InvalidRemoteException, CanceledException, RefNotFoundException,
-			NoHeadException {
+	public PullResult call() throws GitAPIException,
+			WrongRepositoryStateException, InvalidConfigurationException,
+			DetachedHeadException, InvalidRemoteException, CanceledException,
+			RefNotFoundException, NoHeadException,
+			org.eclipse.jgit.api.errors.TransportException {
 		checkCallable();
 
 		monitor.beginTask(JGitText.get().pullTaskName, 2);
@@ -239,44 +245,19 @@ public PullResult call() throws GitAPIException, WrongRepositoryStateException,
 		PullResult result;
 		if (doRebase) {
 			RebaseCommand rebase = new RebaseCommand(repo);
-			try {
-				RebaseResult rebaseRes = rebase.setUpstream(commitToMerge)
-						.setProgressMonitor(monitor).setOperation(
-								Operation.BEGIN).call();
-				result = new PullResult(fetchRes, remote, rebaseRes);
-			} catch (NoHeadException e) {
-				throw new JGitInternalException(e.getMessage(), e);
-			} catch (RefNotFoundException e) {
-				throw new JGitInternalException(e.getMessage(), e);
-			} catch (JGitInternalException e) {
-				throw new JGitInternalException(e.getMessage(), e);
-			} catch (GitAPIException e) {
-				throw new JGitInternalException(e.getMessage(), e);
-			}
+			RebaseResult rebaseRes = rebase.setUpstream(commitToMerge)
+					.setProgressMonitor(monitor).setOperation(Operation.BEGIN)
+					.call();
+			result = new PullResult(fetchRes, remote, rebaseRes);
 		} else {
 			MergeCommand merge = new MergeCommand(repo);
 			String name = "branch \'"
 					+ Repository.shortenRefName(remoteBranchName) + "\' of "
 					+ remoteUri;
 			merge.include(name, commitToMerge);
-			MergeResult mergeRes;
-			try {
-				mergeRes = merge.call();
-				monitor.update(1);
-				result = new PullResult(fetchRes, remote, mergeRes);
-			} catch (NoHeadException e) {
-				throw new JGitInternalException(e.getMessage(), e);
-			} catch (ConcurrentRefUpdateException e) {
-				throw new JGitInternalException(e.getMessage(), e);
-			} catch (CheckoutConflictException e) {
-				throw new JGitInternalException(e.getMessage(), e);
-			} catch (InvalidMergeHeadsException e) {
-				throw new JGitInternalException(e.getMessage(), e);
-			} catch (WrongRepositoryStateException e) {
-				throw new JGitInternalException(e.getMessage(), e);
-			} catch (NoMessageException e) {
-				throw new JGitInternalException(e.getMessage(), e);
-			}
+			MergeResult mergeRes = merge.call();
+			monitor.update(1);
+			result = new PullResult(fetchRes, remote, mergeRes);
 		}
 		monitor.endTask();
 		return result;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/PushCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/PushCommand.java
index edfb2f7..1a4058e 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/PushCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/PushCommand.java
@@ -109,9 +109,13 @@ protected PushCommand(Repository repo) {
 	 * @return an iteration over {@link PushResult} objects
 	 * @throws InvalidRemoteException
 	 *             when called with an invalid remote uri
+	 * @throws org.eclipse.jgit.api.errors.TransportException
+	 *             when an error occurs with the transport
+	 * @throws GitAPIException
 	 */
 	public Iterable<PushResult> call() throws GitAPIException,
-			InvalidRemoteException {
+			InvalidRemoteException,
+			org.eclipse.jgit.api.errors.TransportException {
 		checkCallable();
 
 		ArrayList<PushResult> pushResults = new ArrayList<PushResult>(3);
@@ -150,9 +154,8 @@ public Iterable<PushResult> call() throws GitAPIException,
 					pushResults.add(result);
 
 				} catch (TransportException e) {
-					throw new JGitInternalException(
-							JGitText.get().exceptionCaughtDuringExecutionOfPushCommand,
-							e);
+					throw new org.eclipse.jgit.api.errors.TransportException(
+							e.getMessage(), e);
 				} finally {
 					transport.close();
 				}
@@ -161,6 +164,9 @@ public Iterable<PushResult> call() throws GitAPIException,
 		} catch (URISyntaxException e) {
 			throw new InvalidRemoteException(MessageFormat.format(
 					JGitText.get().invalidRemote, remote));
+		} catch (TransportException e) {
+			throw new org.eclipse.jgit.api.errors.TransportException(
+					e.getMessage(), e);
 		} catch (NotSupportedException e) {
 			throw new JGitInternalException(
 					JGitText.get().exceptionCaughtDuringExecutionOfPushCommand,
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/RebaseCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/RebaseCommand.java
index ecf8593..645c9ff 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/RebaseCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/RebaseCommand.java
@@ -189,9 +189,13 @@ protected RebaseCommand(Repository repo) {
 	 * this method twice on an instance.
 	 *
 	 * @return an object describing the result of this command
+	 * @throws GitAPIException
+	 * @throws WrongRepositoryStateException
+	 * @throws NoHeadException
+	 * @throws RefNotFoundException
 	 */
 	public RebaseResult call() throws GitAPIException, NoHeadException,
-			RefNotFoundException {
+			RefNotFoundException, WrongRepositoryStateException {
 		RevCommit newHead = null;
 		boolean lastStepWasForward = false;
 		checkCallable();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/ReflogCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/ReflogCommand.java
index c4d112a..ef344b5 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/ReflogCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/ReflogCommand.java
@@ -85,7 +85,14 @@ public ReflogCommand setRef(String ref) {
 		return this;
 	}
 
-	public Collection<ReflogEntry> call() throws GitAPIException {
+	/**
+	 * Run the reflog command
+	 *
+	 * @throws GitAPIException
+	 * @throws InvalidRefNameException
+	 */
+	public Collection<ReflogEntry> call() throws GitAPIException,
+			InvalidRefNameException {
 		checkCallable();
 
 		try {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/ResetCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/ResetCommand.java
index 2498480..b34b902 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/ResetCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/ResetCommand.java
@@ -136,6 +136,7 @@ public ResetCommand(Repository repo) {
 	 * twice on an instance.
 	 *
 	 * @return the Ref after reset
+	 * @throws GitAPIException
 	 */
 	public Ref call() throws GitAPIException, CheckoutConflictException {
 		checkCallable();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/RevertCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/RevertCommand.java
index 416677c..fde6b94 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/RevertCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/RevertCommand.java
@@ -49,10 +49,14 @@
 import java.util.Map;
 
 import org.eclipse.jgit.api.MergeResult.MergeStatus;
+import org.eclipse.jgit.api.errors.ConcurrentRefUpdateException;
 import org.eclipse.jgit.api.errors.GitAPIException;
 import org.eclipse.jgit.api.errors.JGitInternalException;
 import org.eclipse.jgit.api.errors.MultipleParentsNotAllowedException;
 import org.eclipse.jgit.api.errors.NoHeadException;
+import org.eclipse.jgit.api.errors.NoMessageException;
+import org.eclipse.jgit.api.errors.UnmergedPathsException;
+import org.eclipse.jgit.api.errors.WrongRepositoryStateException;
 import org.eclipse.jgit.dircache.DirCacheCheckout;
 import org.eclipse.jgit.internal.JGitText;
 import org.eclipse.jgit.lib.AnyObjectId;
@@ -105,8 +109,15 @@ protected RevertCommand(Repository repo) {
 	 *         returned. If a failure occurred during revert <code>null</code>
 	 *         is returned. The list of successfully reverted {@link Ref}'s can
 	 *         be obtained by calling {@link #getRevertedRefs()}
+	 * @throws GitAPIException
+	 * @throws WrongRepositoryStateException
+	 * @throws ConcurrentRefUpdateException
+	 * @throws UnmergedPathsException
+	 * @throws NoMessageException
 	 */
-	public RevCommit call() throws GitAPIException {
+	public RevCommit call() throws NoMessageException, UnmergedPathsException,
+			ConcurrentRefUpdateException, WrongRepositoryStateException,
+			GitAPIException {
 		RevCommit newHead = null;
 		checkCallable();
 
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/StashApplyCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/StashApplyCommand.java
index 4992d3c..c26a485 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/StashApplyCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/StashApplyCommand.java
@@ -296,8 +296,11 @@ public void apply(DirCacheEntry ent) {
 	 * Apply the changes in a stashed commit to the working directory and index
 	 *
 	 * @return id of stashed commit that was applied
+	 * @throws GitAPIException
+	 * @throws WrongRepositoryStateException
 	 */
-	public ObjectId call() throws GitAPIException {
+	public ObjectId call() throws GitAPIException,
+			WrongRepositoryStateException {
 		checkCallable();
 
 		if (repo.getRepositoryState() != RepositoryState.SAFE)
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/StashCreateCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/StashCreateCommand.java
index 4056894..4c7ae6a 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/StashCreateCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/StashCreateCommand.java
@@ -211,6 +211,7 @@ private Ref getHead() throws GitAPIException {
 	 * and reset to the current HEAD commit.
 	 *
 	 * @return stashed commit or null if no changes to stash
+	 * @throws GitAPIException
 	 */
 	public RevCommit call() throws GitAPIException {
 		checkCallable();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/StashDropCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/StashDropCommand.java
index eb61298..dde736b 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/StashDropCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/StashDropCommand.java
@@ -167,6 +167,7 @@ private void updateRef(Ref stashRef, ObjectId newId) {
 	 * stash reference after the drop occurs
 	 *
 	 * @return commit id of stash reference or null if no more stashed changes
+	 * @throws GitAPIException
 	 */
 	public ObjectId call() throws GitAPIException {
 		checkCallable();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/StashListCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/StashListCommand.java
index 407b5ab..6977905 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/StashListCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/StashListCommand.java
@@ -76,7 +76,8 @@ public StashListCommand(final Repository repo) {
 		super(repo);
 	}
 
-	public Collection<RevCommit> call() throws GitAPIException {
+	public Collection<RevCommit> call() throws GitAPIException,
+			InvalidRefNameException {
 		checkCallable();
 
 		try {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/SubmoduleUpdateCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/SubmoduleUpdateCommand.java
index be705ee..caf2ced 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/SubmoduleUpdateCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/SubmoduleUpdateCommand.java
@@ -47,8 +47,16 @@
 import java.util.Collection;
 import java.util.List;
 
+import org.eclipse.jgit.api.errors.CheckoutConflictException;
+import org.eclipse.jgit.api.errors.ConcurrentRefUpdateException;
 import org.eclipse.jgit.api.errors.GitAPIException;
+import org.eclipse.jgit.api.errors.InvalidConfigurationException;
+import org.eclipse.jgit.api.errors.InvalidMergeHeadsException;
 import org.eclipse.jgit.api.errors.JGitInternalException;
+import org.eclipse.jgit.api.errors.NoHeadException;
+import org.eclipse.jgit.api.errors.NoMessageException;
+import org.eclipse.jgit.api.errors.RefNotFoundException;
+import org.eclipse.jgit.api.errors.WrongRepositoryStateException;
 import org.eclipse.jgit.dircache.DirCacheCheckout;
 import org.eclipse.jgit.errors.ConfigInvalidException;
 import org.eclipse.jgit.lib.ConfigConstants;
@@ -109,7 +117,25 @@ public SubmoduleUpdateCommand addPath(final String path) {
 		return this;
 	}
 
-	public Collection<String> call() throws GitAPIException {
+	/**
+	 * Execute the SubmoduleUpdateCommand command.
+	 *
+	 * @return a collection of updated submodule paths
+	 * @throws ConcurrentRefUpdateException
+	 * @throws CheckoutConflictException
+	 * @throws InvalidMergeHeadsException
+	 * @throws InvalidConfigurationException
+	 * @throws NoHeadException
+	 * @throws NoMessageException
+	 * @throws RefNotFoundException
+	 * @throws WrongRepositoryStateException
+	 * @throws GitAPIException
+	 */
+	public Collection<String> call() throws InvalidConfigurationException,
+			NoHeadException, ConcurrentRefUpdateException,
+			CheckoutConflictException, InvalidMergeHeadsException,
+			WrongRepositoryStateException, NoMessageException, NoHeadException,
+			RefNotFoundException, GitAPIException {
 		checkCallable();
 
 		try {
@@ -168,9 +194,7 @@ public Collection<String> call() throws GitAPIException {
 		} catch (IOException e) {
 			throw new JGitInternalException(e.getMessage(), e);
 		} catch (ConfigInvalidException e) {
-			throw new JGitInternalException(e.getMessage(), e);
-		} catch (GitAPIException e) {
-			throw new JGitInternalException(e.getMessage(), e);
+			throw new InvalidConfigurationException(e.getMessage(), e);
 		}
 	}
 }