diff --git a/org.eclipse.jgit.test/META-INF/MANIFEST.MF b/org.eclipse.jgit.test/META-INF/MANIFEST.MF
index 8b44b60535ca854535ecfd94807413a1d5633751..d5eccecb08a19dcbb598620ead4a4ad123b8c33c 100644
--- a/org.eclipse.jgit.test/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit.test/META-INF/MANIFEST.MF
@@ -9,6 +9,7 @@ Bundle-ActivationPolicy: lazy
 Bundle-RequiredExecutionEnvironment: J2SE-1.5
 Import-Package: junit.framework;version="[3.8.2,4.0.0)",
  junit.textui;version="[3.8.2,4.0.0)",
+ org.eclipse.jgit.api;version="[0.8.0,0.9.0)",
  org.eclipse.jgit.diff;version="[0.8.0,0.9.0)",
  org.eclipse.jgit.dircache;version="[0.8.0,0.9.0)",
  org.eclipse.jgit.errors;version="[0.8.0,0.9.0)",
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CommitAndLogCommandTests.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CommitAndLogCommandTests.java
new file mode 100644
index 0000000000000000000000000000000000000000..d8fbb9578a90dd28ec88d630f8b2857c3b62e72b
--- /dev/null
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CommitAndLogCommandTests.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2010, Christian Halstrick <christian.halstrick@sap.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 org.eclipse.jgit.errors.UnmergedPathException;
+import org.eclipse.jgit.lib.PersonIdent;
+import org.eclipse.jgit.lib.RepositoryTestCase;
+import org.eclipse.jgit.revwalk.RevCommit;
+
+public class CommitAndLogCommandTests extends RepositoryTestCase {
+	public void testSomeCommits() throws NoHeadException, NoMessageException,
+			UnmergedPathException, ConcurrentRefUpdateException {
+
+		// do 4 commits
+		Git git = new Git(db);
+		git.commit().setMessage("initial commit").call();
+		git.commit().setMessage("second commit").setCommitter(committer).call();
+		git.commit().setMessage("third commit").setAuthor(author).call();
+		git.commit().setMessage("fourth commit").setAuthor(author)
+				.setCommitter(committer).call();
+		Iterable<RevCommit> commits = git.log().call();
+
+		// check that all commits came in correctly
+		PersonIdent defaultCommitter = new PersonIdent(db);
+		PersonIdent expectedAuthors[] = new PersonIdent[] {
+				defaultCommitter, committer, author, author };
+		PersonIdent expectedCommitters[] = new PersonIdent[] {
+				defaultCommitter, committer, defaultCommitter, committer };
+		String expectedMessages[] = new String[] { "initial commit",
+				"second commit", "third commit", "fourth commit" };
+		int l = expectedAuthors.length - 1;
+		for (RevCommit c : commits) {
+			assertEquals(expectedAuthors[l].getName(), c.getAuthorIdent()
+					.getName());
+			assertEquals(expectedCommitters[l].getName(), c.getCommitterIdent()
+					.getName());
+			assertEquals(c.getFullMessage(), expectedMessages[l]);
+			l--;
+		}
+		assertEquals(l, -1);
+	}
+
+	// try to do a commit without specifying a message. Should fail!
+	public void testWrongParams() throws UnmergedPathException,
+			NoHeadException, ConcurrentRefUpdateException {
+		Git git = new Git(db);
+		try {
+			git.commit().setAuthor(author).call();
+			fail("Didn't get the expected exception");
+		} catch (NoMessageException e) {
+		}
+	}
+
+	// try to work with Commands after command has been invoked. Should throw
+	// exceptions
+	public void testMultipleInvocations() throws NoHeadException,
+			ConcurrentRefUpdateException, NoMessageException,
+			UnmergedPathException {
+		Git git = new Git(db);
+		CommitCommand commitCmd = git.commit();
+		commitCmd.setMessage("initial commit").call();
+		try {
+			// check that setters can't be called after invocation
+			commitCmd.setAuthor(author);
+			fail("didn't catch the expected exception");
+		} catch (IllegalStateException e) {
+		}
+		LogCommand logCmd = git.log();
+		logCmd.call();
+		try {
+			// check that call can't be called twice
+			logCmd.call();
+			fail("didn't catch the expected exception");
+		} catch (IllegalStateException e) {
+		}
+	}
+}
diff --git a/org.eclipse.jgit/META-INF/MANIFEST.MF b/org.eclipse.jgit/META-INF/MANIFEST.MF
index f586e924874f2a73ca9970bc932d5a31f66b87b1..7c04302d8b3977f32b6e63e3e8eec08c329cfa01 100644
--- a/org.eclipse.jgit/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit/META-INF/MANIFEST.MF
@@ -5,7 +5,8 @@ Bundle-SymbolicName: org.eclipse.jgit
 Bundle-Version: 0.8.0.qualifier
 Bundle-Localization: plugin
 Bundle-Vendor: %provider_name
-Export-Package: org.eclipse.jgit.diff;version="0.8.0",
+Export-Package: org.eclipse.jgit.api;version="0.8.0",
+ org.eclipse.jgit.diff;version="0.8.0",
  org.eclipse.jgit.dircache;version="0.8.0",
  org.eclipse.jgit.errors;version="0.8.0",
  org.eclipse.jgit.fnmatch;version="0.8.0",
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/CommitCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/CommitCommand.java
new file mode 100644
index 0000000000000000000000000000000000000000..7501509d11ec443a7b386775a35c8c3c7d90f744
--- /dev/null
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/CommitCommand.java
@@ -0,0 +1,299 @@
+/*
+ * Copyright (C) 2010, Christian Halstrick <christian.halstrick@sap.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.IOException;
+
+import org.eclipse.jgit.dircache.DirCache;
+import org.eclipse.jgit.errors.UnmergedPathException;
+import org.eclipse.jgit.lib.Commit;
+import org.eclipse.jgit.lib.Constants;
+import org.eclipse.jgit.lib.ObjectId;
+import org.eclipse.jgit.lib.ObjectWriter;
+import org.eclipse.jgit.lib.PersonIdent;
+import org.eclipse.jgit.lib.Ref;
+import org.eclipse.jgit.lib.RefUpdate;
+import org.eclipse.jgit.lib.RefUpdate.Result;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.revwalk.RevCommit;
+import org.eclipse.jgit.revwalk.RevWalk;
+
+/**
+ * A class used to execute a {@code Commit} command. It has setters for all
+ * supported options and arguments of this command and a {@link #call()} method
+ * to finally execute the command.
+ *
+ * @see <a
+ *      href="http://www.kernel.org/pub/software/scm/git/docs/git-commit.html"
+ *      >Git documentation about Commit</a>
+ */
+public class CommitCommand extends GitCommand<RevCommit> {
+	private PersonIdent author;
+
+	private PersonIdent committer;
+
+	private String message;
+
+	/**
+	 * @param repo
+	 */
+	protected CommitCommand(Repository repo) {
+		super(repo);
+	}
+
+	/**
+	 * Executes the {@code commit} command with all the options and parameters
+	 * collected by the setter methods of this class. Each instance of this
+	 * class should only be used for one invocation of the command (means: one
+	 * call to {@link #call()})
+	 *
+	 * @return a {@link Commit} object representing the successful commit
+	 * @throws NoHeadException
+	 *             when called on a git repo without a HEAD reference
+	 * @throws NoMessageException
+	 *             when called without specifying a commit message
+	 * @throws UnmergedPathException
+	 *             when the current index contained unmerged pathes (conflicts)
+	 * @throws JGitInternalException
+	 *             a low-level exception of JGit has occurred. The original
+	 *             exception can be retrieved by calling
+	 *             {@link Exception#getCause()}. Expect only
+	 *             {@code IOException's} to be wrapped. Subclasses of
+	 *             {@link IOException} (e.g. {@link UnmergedPathException}) are
+	 *             typically not wrapped here but thrown as original exception
+	 */
+	public RevCommit call() throws NoHeadException, NoMessageException,
+			UnmergedPathException, ConcurrentRefUpdateException,
+			JGitInternalException {
+		checkCallable();
+		processOptions();
+
+		try {
+			Ref head = repo.getRef(Constants.HEAD);
+			if (head == null)
+				throw new NoHeadException(
+						"Commit on repo without HEAD currently not supported");
+
+			// determine the current HEAD and the commit it is referring to
+			ObjectId parentID = repo.resolve(Constants.HEAD + "^{commit}");
+
+			// lock the index
+			DirCache index = DirCache.lock(repo);
+			try {
+				ObjectWriter repoWriter = new ObjectWriter(repo);
+
+				// Write the index as tree to the object database. This may fail
+				// for example when the index contains unmerged pathes
+				// (unresolved conflicts)
+				ObjectId indexTreeId = index.writeTree(repoWriter);
+
+				// Create a Commit object, populate it and write it
+				Commit commit = new Commit(repo);
+				commit.setCommitter(committer);
+				commit.setAuthor(author);
+				commit.setMessage(message);
+				if (parentID != null)
+					commit.setParentIds(new ObjectId[] { parentID });
+				commit.setTreeId(indexTreeId);
+				ObjectId commitId = repoWriter.writeCommit(commit);
+
+				RevCommit revCommit = new RevWalk(repo).parseCommit(commitId);
+				RefUpdate ru = repo.updateRef(Constants.HEAD);
+				ru.setNewObjectId(commitId);
+				ru.setRefLogMessage("commit : " + revCommit.getShortMessage(),
+						false);
+
+				ru.setExpectedOldObjectId(parentID);
+				Result rc = ru.update();
+				switch (rc) {
+				case NEW:
+				case FAST_FORWARD:
+					setCallable(false);
+					return revCommit;
+				case REJECTED:
+				case LOCK_FAILURE:
+					throw new ConcurrentRefUpdateException(
+							"Could lock HEAD during commit", ru.getRef(), rc);
+				default:
+					throw new JGitInternalException(
+							"Updating the ref "
+									+ Constants.HEAD
+									+ " to "
+									+ commitId.toString()
+									+ " failed. ReturnCode from RefUpdate.update() was "
+									+ rc);
+				}
+			} finally {
+				index.unlock();
+			}
+		} catch (UnmergedPathException e) {
+			// since UnmergedPathException is a subclass of IOException
+			// which should not be wrapped by a JGitInternalException we
+			// have to catch and re-throw it here
+			throw e;
+		} catch (IOException e) {
+			throw new JGitInternalException(
+					"Exception caught during execution of commit command", e);
+		}
+	}
+
+	/**
+	 * Sets default values for not explicitly specified options. Then validates
+	 * that all required data has been provided.
+	 *
+	 * @throws NoMessageException
+	 *             if the commit message has not been specified
+	 */
+	private void processOptions() throws NoMessageException {
+		if (message == null)
+			// as long as we don't suppport -C option we have to have
+			// an explicit message
+			throw new NoMessageException("commit message not specified");
+		if (committer == null)
+			committer = new PersonIdent(repo);
+		if (author == null)
+			author = committer;
+	}
+
+	/**
+	 * @param message
+	 *            the commit message used for the {@code commit}
+	 * @return {@code this}
+	 */
+	public CommitCommand setMessage(String message) {
+		checkCallable();
+		this.message = message;
+		return this;
+	}
+
+	/**
+	 * @return the commit message used for the <code>commit</code>
+	 */
+	public String getMessage() {
+		return message;
+	}
+
+	/**
+	 * Sets the committer for this {@code commit}. If no committer is explicitly
+	 * specified because this method is never called or called with {@code null}
+	 * value then the committer will be deduced from config info in repository,
+	 * with current time.
+	 *
+	 * @param committer
+	 *            the committer used for the {@code commit}
+	 * @return {@code this}
+	 */
+	public CommitCommand setCommitter(PersonIdent committer) {
+		checkCallable();
+		this.committer = committer;
+		return this;
+	}
+
+	/**
+	 * Sets the committer for this {@code commit}. If no committer is explicitly
+	 * specified because this method is never called or called with {@code null}
+	 * value then the committer will be deduced from config info in repository,
+	 * with current time.
+	 *
+	 * @param name
+	 *            the name of the committer used for the {@code commit}
+	 * @param email
+	 *            the email of the committer used for the {@code commit}
+	 * @return {@code this}
+	 */
+	public CommitCommand setCommitter(String name, String email) {
+		checkCallable();
+		return setCommitter(new PersonIdent(name, email));
+	}
+
+	/**
+	 * @return the committer used for the {@code commit}. If no committer was
+	 *         specified {@code null} is returned and the default
+	 *         {@link PersonIdent} of this repo is used during execution of the
+	 *         command
+	 */
+	public PersonIdent getCommitter() {
+		return committer;
+	}
+
+	/**
+	 * Sets the author for this {@code commit}. If no author is explicitly
+	 * specified because this method is never called or called with {@code null}
+	 * value then the author will be set to the committer.
+	 *
+	 * @param author
+	 *            the author used for the {@code commit}
+	 * @return {@code this}
+	 */
+	public CommitCommand setAuthor(PersonIdent author) {
+		checkCallable();
+		this.author = author;
+		return this;
+	}
+
+	/**
+	 * Sets the author for this {@code commit}. If no author is explicitly
+	 * specified because this method is never called or called with {@code null}
+	 * value then the author will be set to the committer.
+	 *
+	 * @param name
+	 *            the name of the author used for the {@code commit}
+	 * @param email
+	 *            the email of the author used for the {@code commit}
+	 * @return {@code this}
+	 */
+	public CommitCommand setAuthor(String name, String email) {
+		checkCallable();
+		return setAuthor(new PersonIdent(name, email));
+	}
+
+	/**
+	 * @return the author used for the {@code commit}. If no author was
+	 *         specified {@code null} is returned and the default
+	 *         {@link PersonIdent} of this repo is used during execution of the
+	 *         command
+	 */
+	public PersonIdent getAuthor() {
+		return author;
+	}
+}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/ConcurrentRefUpdateException.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/ConcurrentRefUpdateException.java
new file mode 100644
index 0000000000000000000000000000000000000000..c5d9fe68ddf3bda7d6aec10d2d2aa4d0ed252804
--- /dev/null
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/ConcurrentRefUpdateException.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2010, Christian Halstrick <christian.halstrick@sap.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 org.eclipse.jgit.lib.Ref;
+import org.eclipse.jgit.lib.RefUpdate;
+
+/**
+ * Exception thrown when a command want's to update a ref but failed because
+ * another process is accessing (or even also updating) the ref.
+ *
+ * @see RefUpdate.Result#LOCK_FAILURE
+ */
+public class ConcurrentRefUpdateException extends GitAPIException {
+	private static final long serialVersionUID = 1L;
+	private RefUpdate.Result rc;
+	private Ref ref;
+
+	ConcurrentRefUpdateException(String message, Ref ref,
+			RefUpdate.Result rc, Throwable cause) {
+		super((rc == null) ? message : message
+				+ ". RefUpdate return code was: " + rc, cause);
+		this.rc = rc;
+		this.ref = ref;
+	}
+
+	ConcurrentRefUpdateException(String message, Ref ref,
+			RefUpdate.Result rc) {
+		super((rc == null) ? message : message
+				+ ". RefUpdate return code was: " + rc);
+		this.rc = rc;
+		this.ref = ref;
+	}
+
+	/**
+	 * @return the {@link Ref} which was tried to by updated
+	 */
+	public Ref getRef() {
+		return ref;
+	}
+
+	/**
+	 * @return the result which was returned by {@link RefUpdate#update()} and
+	 *         which caused this error
+	 */
+	public RefUpdate.Result getResult() {
+		return rc;
+	}
+}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/Git.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/Git.java
new file mode 100644
index 0000000000000000000000000000000000000000..30dcbd75b23c948751d15b87b7e0f6e4ee8c2325
--- /dev/null
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/Git.java
@@ -0,0 +1,128 @@
+/*
+ * Copyright (C) 2010, Christian Halstrick <christian.halstrick@sap.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 org.eclipse.jgit.lib.Repository;
+
+/**
+ * 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 {
+	/** The git repository this class is interacting with */
+	private final Repository repo;
+
+	/**
+	 * Constructs a new {@link Git} class which can interact with the specified
+	 * git repository. All command classes returned by methods of this class
+	 * will always interact with this git repository.
+	 *
+	 * @param repo
+	 *            the git repository this class is interacting with.
+	 *            {@code null} is not allowed
+	 */
+	public Git(Repository repo) {
+		if (repo == null)
+			throw new NullPointerException();
+		this.repo = repo;
+	}
+
+	/**
+	 * Returns a command class 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 CommitCommand} used to collect all optional parameters
+	 *         and to finally execute the {@code Commit} command
+	 */
+	public CommitCommand commit() {
+		return new CommitCommand(repo);
+	}
+
+	/**
+	 * Returns a command class 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 LogCommand} used to collect all optional parameters and
+	 *         to finally execute the {@code Log} command
+	 */
+	public LogCommand log() {
+		return new LogCommand(repo);
+	}
+
+	/**
+	 * @return the git repository this class is interacting with
+	 */
+	public Repository getRepository() {
+		return repo;
+	}
+}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/GitAPIException.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/GitAPIException.java
new file mode 100644
index 0000000000000000000000000000000000000000..9991502aaaa5f6f7a1bb8f7a3534bade0323ea74
--- /dev/null
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/GitAPIException.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2010, Christian Halstrick <christian.halstrick@sap.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;
+
+/**
+ * Superclass of all exceptions thrown by the API classes in
+ * {@code org.eclipse.jgit.api}
+ *
+ */
+public abstract class GitAPIException extends Exception {
+	private static final long serialVersionUID = 1L;
+
+	GitAPIException(String message, Throwable cause) {
+		super(message, cause);
+	}
+
+	GitAPIException(String message) {
+		super(message);
+	}
+}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/GitCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/GitCommand.java
new file mode 100644
index 0000000000000000000000000000000000000000..4df5b4437b00f53ead62091a24e0738a75767df5
--- /dev/null
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/GitCommand.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2010, Christian Halstrick <christian.halstrick@sap.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.util.concurrent.Callable;
+
+import org.eclipse.jgit.lib.Repository;
+
+/**
+ * Common superclass of all commands in the package {@code org.eclipse.jgit.api}
+ * <p>
+ * This class ensures that all commands fulfill the {@link Callable} interface.
+ * It also has a property {@link #repo} holding a reference to the git
+ * {@link Repository} this command should work with.
+ * <p>
+ * Finally this class stores a state telling whether it is allowed to call
+ * {@link #call()} on this instance. Instances of {@link GitCommand} can only be
+ * used for one single successful call to {@link #call()}. Afterwards this
+ * instance may not be used anymore to set/modify any properties or to call
+ * {@link #call()} again. This is achieved by setting the {@link #callable}
+ * property to false after the successful execution of {@link #call()} and to
+ * check the state (by calling {@link #checkCallable()}) before setting of
+ * properties and inside {@link #call()}.
+ *
+ * @param <T>
+ *            the return type which is expected from {@link #call()}
+ */
+public abstract class GitCommand<T> implements Callable<T> {
+	/** The repository this command is working with */
+	final protected Repository repo;
+
+	/**
+	 * a state which tells whether it is allowed to call {@link #call()} on this
+	 * instance.
+	 */
+	private boolean callable = true;
+
+	/**
+	 * Creates a new command which interacts with a single repository
+	 *
+	 * @param repo
+	 *            the {@link Repository} this command should interact with
+	 */
+	protected GitCommand(Repository repo) {
+		this.repo = repo;
+	}
+
+	/**
+	 * @return the {@link Repository} this command is interacting with
+	 */
+	public Repository getRepository() {
+		return repo;
+	}
+
+	/**
+	 * Set's the state which tells whether it is allowed to call {@link #call()}
+	 * on this instance. {@link #checkCallable()} will throw an exception when
+	 * called and this property is set to {@code false}
+	 *
+	 * @param callable
+	 *            if <code>true</code> it is allowed to call {@link #call()} on
+	 *            this instance.
+	 */
+	protected void setCallable(boolean callable) {
+		this.callable = callable;
+	}
+
+	/**
+	 * Checks that the property {@link #callable} is {@code true}. If not then
+	 * an {@link IllegalStateException} is thrown
+	 *
+	 * @throws IllegalStateException
+	 *             when this method is called and the property {@link #callable}
+	 *             is {@code false}
+	 */
+	protected void checkCallable() {
+		if (!callable)
+			throw new IllegalStateException("Command "
+					+ this.getClass().getName()
+					+ " was called in the wrong state");
+	}
+}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/JGitInternalException.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/JGitInternalException.java
new file mode 100644
index 0000000000000000000000000000000000000000..a0475da1355042b1eca50b15bada3345aad32a05
--- /dev/null
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/JGitInternalException.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2010, Christian Halstrick <christian.halstrick@sap.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;
+
+/**
+ * Exception thrown when during command execution a low-level exception from the
+ * JGit library is thrown. Also when certain low-level error situations are
+ * reported by JGit through return codes this Exception will be thrown.
+ * <p>
+ * During command execution a lot of exceptions may be thrown. Some of them
+ * represent error situations which can be handled specifically by the caller of
+ * the command. But a lot of exceptions are so low-level that is is unlikely
+ * that the caller of the command can handle them effectively. The huge number
+ * of these low-level exceptions which are thrown by the commands lead to a
+ * complicated and wide interface of the commands. Callers of the API have to
+ * deal with a lot of exceptions they don't understand.
+ * <p>
+ * To overcome this situation this class was introduced. Commands will wrap all
+ * exceptions they declare as low-level in their context into an instance of
+ * this class. Callers of the commands have to deal with one type of low-level
+ * exceptions. Callers will always get access to the original exception (if
+ * available) by calling {@code #getCause()}.
+ */
+public class JGitInternalException extends RuntimeException {
+	private static final long serialVersionUID = 1L;
+
+	JGitInternalException(String message, Throwable cause) {
+		super(message, cause);
+	}
+
+	JGitInternalException(String message) {
+		super(message);
+	}
+}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/LogCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/LogCommand.java
new file mode 100644
index 0000000000000000000000000000000000000000..4ce57201d3ec40d840170b22714592db2b95c8fb
--- /dev/null
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/LogCommand.java
@@ -0,0 +1,222 @@
+/*
+ * Copyright (C) 2010, Christian Halstrick <christian.halstrick@sap.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.IOException;
+
+import org.eclipse.jgit.errors.IncorrectObjectTypeException;
+import org.eclipse.jgit.errors.MissingObjectException;
+import org.eclipse.jgit.lib.AnyObjectId;
+import org.eclipse.jgit.lib.Constants;
+import org.eclipse.jgit.lib.ObjectId;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.revwalk.RevCommit;
+import org.eclipse.jgit.revwalk.RevWalk;
+
+/**
+ * A class used to execute a {@code Log} command. It has setters for all
+ * supported options and arguments of this command and a {@link #call()} method
+ * to finally execute the command. Each instance of this class should only be
+ * used for one invocation of the command (means: one call to {@link #call()})
+ * <p>
+ * This is currently a very basic implementation which takes only one starting
+ * revision as option.
+ *
+ * @TODO add more options (revision ranges, sorting, ...)
+ *
+ * @see <a href="http://www.kernel.org/pub/software/scm/git/docs/git-log.html"
+ *      >Git documentation about Log</a>
+ */
+public class LogCommand extends GitCommand<Iterable<RevCommit>> {
+	private RevWalk walk;
+
+	private boolean startSpecified = false;
+
+	/**
+	 * @param repo
+	 */
+	protected LogCommand(Repository repo) {
+		super(repo);
+		walk = new RevWalk(repo);
+	}
+
+	/**
+	 * Executes the {@code Log} command with all the options and parameters
+	 * collected by the setter methods (e.g. {@link #add(AnyObjectId)},
+	 * {@link #not(AnyObjectId)}, ..) of this class. Each instance of this class
+	 * should only be used for one invocation of the command. Don't call this
+	 * method twice on an instance.
+	 *
+	 * @return an iteration over RevCommits
+	 */
+	public Iterable<RevCommit> call() throws NoHeadException,
+			JGitInternalException {
+		checkCallable();
+		if (!startSpecified) {
+			try {
+				ObjectId headId = repo.resolve(Constants.HEAD);
+				if (headId == null)
+					throw new NoHeadException(
+							"No HEAD exists and no explicit starting revision was specified");
+				add(headId);
+			} catch (IOException e) {
+				// all exceptions thrown by add() shouldn't occur and represent
+				// severe low-level exception which are therefore wrapped
+				throw new JGitInternalException(
+						"An exception occured while trying to add the Id of HEAD",
+						e);
+			}
+		}
+		setCallable(false);
+		return walk;
+	}
+
+	/**
+	 * Mark a commit to start graph traversal from.
+	 *
+	 * @see RevWalk#markStart(RevCommit)
+	 * @param start
+	 * @return {@code this}
+	 * @throws MissingObjectException
+	 *             the commit supplied is not available from the object
+	 *             database. This usually indicates the supplied commit is
+	 *             invalid, but the reference was constructed during an earlier
+	 *             invocation to {@link RevWalk#lookupCommit(AnyObjectId)}.
+	 * @throws IncorrectObjectTypeException
+	 *             the object was not parsed yet and it was discovered during
+	 *             parsing that it is not actually a commit. This usually
+	 *             indicates the caller supplied a non-commit SHA-1 to
+	 *             {@link RevWalk#lookupCommit(AnyObjectId)}.
+	 * @throws JGitInternalException
+	 *             a low-level exception of JGit has occurred. The original
+	 *             exception can be retrieved by calling
+	 *             {@link Exception#getCause()}. Expect only
+	 *             {@code IOException's} to be wrapped. Subclasses of
+	 *             {@link IOException} (e.g. {@link MissingObjectException}) are
+	 *             typically not wrapped here but thrown as original exception
+	 */
+	public LogCommand add(AnyObjectId start) throws MissingObjectException,
+			IncorrectObjectTypeException, JGitInternalException {
+		return add(true, start);
+	}
+
+	/**
+	 * Same as {@code --not start}, or {@code ^start}
+	 *
+	 * @param start
+	 * @return {@code this}
+	 * @throws MissingObjectException
+	 *             the commit supplied is not available from the object
+	 *             database. This usually indicates the supplied commit is
+	 *             invalid, but the reference was constructed during an earlier
+	 *             invocation to {@link RevWalk#lookupCommit(AnyObjectId)}.
+	 * @throws IncorrectObjectTypeException
+	 *             the object was not parsed yet and it was discovered during
+	 *             parsing that it is not actually a commit. This usually
+	 *             indicates the caller supplied a non-commit SHA-1 to
+	 *             {@link RevWalk#lookupCommit(AnyObjectId)}.
+	 * @throws JGitInternalException
+	 *             a low-level exception of JGit has occurred. The original
+	 *             exception can be retrieved by calling
+	 *             {@link Exception#getCause()}. Expect only
+	 *             {@code IOException's} to be wrapped. Subclasses of
+	 *             {@link IOException} (e.g. {@link MissingObjectException}) are
+	 *             typically not wrapped here but thrown as original exception
+	 */
+	public LogCommand not(AnyObjectId start) throws MissingObjectException,
+			IncorrectObjectTypeException, JGitInternalException {
+		return add(false, start);
+	}
+
+	/**
+	 * Adds the range {@code since..until}
+	 *
+	 * @param since
+	 * @param until
+	 * @return {@code this}
+	 * @throws MissingObjectException
+	 *             the commit supplied is not available from the object
+	 *             database. This usually indicates the supplied commit is
+	 *             invalid, but the reference was constructed during an earlier
+	 *             invocation to {@link RevWalk#lookupCommit(AnyObjectId)}.
+	 * @throws IncorrectObjectTypeException
+	 *             the object was not parsed yet and it was discovered during
+	 *             parsing that it is not actually a commit. This usually
+	 *             indicates the caller supplied a non-commit SHA-1 to
+	 *             {@link RevWalk#lookupCommit(AnyObjectId)}.
+	 * @throws JGitInternalException
+	 *             a low-level exception of JGit has occurred. The original
+	 *             exception can be retrieved by calling
+	 *             {@link Exception#getCause()}. Expect only
+	 *             {@code IOException's} to be wrapped. Subclasses of
+	 *             {@link IOException} (e.g. {@link MissingObjectException}) are
+	 *             typically not wrapped here but thrown as original exception
+	 */
+	public LogCommand addRange(AnyObjectId since, AnyObjectId until)
+			throws MissingObjectException, IncorrectObjectTypeException,
+			JGitInternalException {
+		return not(since).add(until);
+	}
+
+	private LogCommand add(boolean include, AnyObjectId start)
+			throws MissingObjectException, IncorrectObjectTypeException,
+			JGitInternalException {
+		checkCallable();
+		try {
+			if (include) {
+				walk.markStart(walk.lookupCommit(start));
+				startSpecified = true;
+			} else
+				walk.markUninteresting(walk.lookupCommit(start));
+			return this;
+		} catch (MissingObjectException e) {
+			throw e;
+		} catch (IncorrectObjectTypeException e) {
+			throw e;
+		} catch (IOException e) {
+			throw new JGitInternalException(
+					"Exception occured during adding of " + start
+							+ " as option to a Log command", e);
+		}
+	}
+}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/NoHeadException.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/NoHeadException.java
new file mode 100644
index 0000000000000000000000000000000000000000..5d79233cf50c00867b916018b2b55315a6a044be
--- /dev/null
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/NoHeadException.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2010, Christian Halstrick <christian.halstrick@sap.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;
+
+/**
+ * Exception thrown when a command expected the {@code HEAD} reference to exist
+ * but couldn't find such a reference
+ */
+public class NoHeadException extends GitAPIException {
+	private static final long serialVersionUID = 1L;
+
+	NoHeadException(String message, Throwable cause) {
+		super(message, cause);
+	}
+
+	NoHeadException(String message) {
+		super(message);
+	}
+}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/NoMessageException.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/NoMessageException.java
new file mode 100644
index 0000000000000000000000000000000000000000..7c6a184e0c7f63f8e17a8ca5496d2fc385920ef0
--- /dev/null
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/NoMessageException.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2010, Christian Halstrick <christian.halstrick@sap.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;
+
+/**
+ * Exception thrown when the options given to a command doesn't include a
+ * specification of a message text (e.g. a commit was called without explicitly
+ * specifying a commit message (or other options telling where to take the
+ * message from.
+ */
+public class NoMessageException extends GitAPIException {
+	private static final long serialVersionUID = 1L;
+
+	NoMessageException(String message, Throwable cause) {
+		super(message, cause);
+	}
+
+	NoMessageException(String message) {
+		super(message);
+	}
+}