I just announced the new Spring Boot 2 material, coming in REST With Spring:

>> CHECK OUT THE COURSE

1. Introduction

JGit is a lightweight, pure Java library implementation of the Git version control system – including repository access routines, network protocols, and core version control algorithms.

JGit is a relatively full-featured implementation of Git written in Java and is widely used in the Java community. The JGit project is under the Eclipse umbrella, and its home can be found at JGit.

In this tutorial, we’ll explain how to work with it.

2. Getting Started

There are a number of ways to connect your project with JGit and start writing code. Probably the easiest way is to use Maven – the integration is accomplished by adding the following snippet to the <dependencies> tag in our pom.xml file:

<dependency>
    <groupId>org.eclipse.jgit</groupId>
    <artifactId>org.eclipse.jgit</artifactId>
    <version>4.6.0.201612231935-r</version>
</dependency>

Please visit the Maven Central repository for the newest version of JGit. Once this step is done, Maven will automatically acquire and use the JGit libraries that we’ll need.

If you prefer OSGi bundles, there is also a p2 repository. Please visit Eclipse JGit to get the necessary information how to integrate this library.

3. Creating a Repository

JGit has two basic levels of API: plumbing and porcelain. The terminology for these comes from Git itself. JGit is divided into the same areas:

  • porcelain APIs – front-end for common user-level actions (similar to Git command-line tool)
  • plumbing APIs – direct interacting with low-level repository objects

The starting point for most JGit sessions is in the Repository class. The first thing we are going to do is the creation of a new Repository instance.

The init command will let us create an empty repository:

Git git = Git.init().setDirectory("/path/to/repo").call();

This will create a repository with a working directory at the location given to setDirectory().

An existing repository can be cloned with the cloneRepository command:

Git git = Git.cloneRepository()
  .setURI("https://github.com/eclipse/jgit.git")
  .setDirectory("/path/to/repo")
  .call();

The code above will clone the JGit repository into the local directory named path/to/repo.

4. Git Objects

All objects are represented by an SHA-1 id in the Git object model. In JGit, this is represented by the AnyObjectId and ObjectId classes.

There are four types of objects in the Git object model:

  • blob – used for storing file data
  • tree – a directory; it references other trees and blobs
  • commit – points to a single tree
  • tag – marks a commit as special; generally used for marking specific releases

To resolve an object from a repository, simply pass the right revision as in the following function:

ObjectId head = repository.resolve("HEAD");

4.1. Ref

The Ref is a variable that holds a single object identifier. The object identifier can be any valid Git object (blob, tree, commit, tag).

For example, to query for the reference to head, you can simply call:

Ref HEAD = repository.getRef("refs/heads/master");

4.2. RevWalk

The RevWalk walks a commit graph and produces the matching commits in order:

RevWalk walk = new RevWalk(repository);

4.3. RevCommit

The RevCommit represents a commit in the Git object model. To parse a commit, use a RevWalk instance:

RevWalk walk = new RevWalk(repository);
RevCommit commit = walk.parseCommit(objectIdOfCommit);

4.4. RevTag

The RevTag represents a tag in the Git object model. You can use a RevWalk instance to parse a tag:

RevWalk walk = new RevWalk(repository);
RevTag tag = walk.parseTag(objectIdOfTag);

4.5. RevTree

The RevTree represents a tree in the Git object model. A RevWalk instance is also used to parse a tree:

RevWalk walk = new RevWalk(repository);
RevTree tree = walk.parseTree(objectIdOfTree);

5. Porcelain API

While JGit contains a lot of low-level code to work with Git repositories, it also contains a higher level API that mimics some of the Git porcelain commands in the org.eclipse.jgit.api package.

5.1. AddCommand (git-add)

The AddCommand allows you to add files to the index via:

  • addFilepattern()

Here’s a quick example of how to add a set of files to the index using the porcelain API:

Git git = new Git(db);
AddCommand add = git.add();
add.addFilepattern("someDirectory").call();

5.2. CommitCommand (git-commit)

The CommitCommand allows you to perform commits and has following options available:

  • setAuthor()
  • setCommitter()
  • setAll()

Here’s a quick example of how to commit using the porcelain API:

Git git = new Git(db);
CommitCommand commit = git.commit();
commit.setMessage("initial commit").call();

5.3. TagCommand (git-tag)

The TagCommand supports a variety of tagging options:

  • setName()
  • setMessage()
  • setTagger()
  • setObjectId()
  • setForceUpdate()
  • setSigned()

Here’s a quick example of tagging a commit using the porcelain API:

Git git = new Git(db);
RevCommit commit = git.commit().setMessage("initial commit").call();
RevTag tag = git.tag().setName("tag").call();

5.4. LogCommand (git-log)

The LogCommand allows you to easily walk a commit graph.

  • add(AnyObjectId start)
  • addRange(AnyObjectId since, AnyObjectId until)

Here’s a quick example of how to get some log messages:

Git git = new Git(db);
Iterable<RevCommit> log = git.log().call();

6. Ant Tasks

JGit also has some common Ant tasks contained in the org.eclipse.jgit.ant bundle.

To use those tasks:

<taskdef resource="org/eclipse/jgit/ant/ant-tasks.properties">
    <classpath>
        <pathelement location="path/to/org.eclipse.jgit.ant-VERSION.jar"/>
        <pathelement location="path/to/org.eclipse.jgit-VERSION.jar"/>
        <pathelement location="path/to/jsch-0.1.44-1.jar"/>
    </classpath>
</taskdef>

This would provide the git-clone, git-init and git-checkout tasks.

6.1. git-clone

<git-clone uri="http://egit.eclipse.org/jgit.git" />

The following attributes are required:

  • uri: the URI to clone from

The following attributes are optional:

  • dest: the destination to clone to (defaults to use a human readable directory name based on the last path component of the URI)
  • bare: true/false/yes/no to indicate if the cloned repository should be bare or not (defaults to false)
  • branch: the initial branch to check out when cloning the repository (defaults to HEAD)

6.2. git-init

<git-init />

No attributes are required to run the git-init task.

The following attributes are optional:

  • dest: the path where a git repository is initialized (defaults to $GIT_DIR or the current directory)
  • bare: true/false/yes/no to indicate if the repository should be bare or not (defaults to false)

6.3. git-checkout

<git-checkout src="path/to/repo" branch="origin/newbranch" />

The following attributes are required:

  • src: the path to the git repository
  • branch: the initial branch to checkout

The following attributes are optional:

  • createbranch: true/false/yes/no to indicate whether the branch should be created if it does not already exist (defaults to false)
  • force: true/false/yes/no: if true/yes and the branch with the given name already exists, the start-point of an existing branch will be set to a new start-point; if false, the existing branch will not be changed (defaults to false)

7. Conclusion

The high-level JGit API isn’t hard to understand. If you know what git command to use, you can easily guess which classes and methods to use in JGit.

There is a collection of ready-to-run JGit code snippets available here.

If you still have difficulties or questions, please leave a comment here or ask the JGit community for assistance.

I just announced the new Spring Boot 2 material, coming in REST With Spring:

>> CHECK OUT THE LESSONS