jgit
A Guide to JGit
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
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
RevWalk walk = new RevWalk(repository);
RevTag tag = walk.parseTag(objectIdOfTag);
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)
-
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)
-
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)
-
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();
6. Ant Tasks
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.