JGit Library Examples in Java
Here, we have a brief introduction to the JGit library with useful examples to use in a live production.
Join the DZone community and get the full member experience.
Join For FreeIntroduction
This article will cover the basic methods from the JGit library that you can use to do git actions from Java code.
Introduction to JGit: JGit library is an open-source library under the Eclipse Licence (Eclipse Distribution Licence). This library has very few dependencies and it can be easily integrated into a Java application. It was implemented in Java to handle all the SCM action commands for Git.
How you can use it: For the library to be accessible in the Java code, you have to add the dependencies in Gradle or Maven. This library works with Java 8 or newer versions. In this tutorial, we will use the JGit Core version: 5.10.0.202012080955-r.
- Where to find all the JGit versions? In the maven repository here.
- Add Gradle dependencies: Add this library in the "build.gradle" dependencies area.
implementation group: 'org.eclipse.jgit', name: 'org.eclipse.jgit', version: '5.10.0.202012080955-r'
- Add Maven dependencies: Add this library in the "pom.xml", dependencies area.
<dependency>
<groupId>org.eclipse.jgit</groupId>
<artifactId>org.eclipse.jgit</artifactId>
<version>5.10.0.202012080955-r</version>
</dependency>
Based on your project you can choose one of the above dependencies.
Please Note: This library comes with compile dependencies (which are: JavaEWAH and slf4j-api).
Basic examples with JGit: The examples below were done in Java with Spring Boot (v2.4.2) and Spring (v5.3.3).
- Init ssh session to use for Git Clone
@PostConstruct
public void setUp() {
File sshDir = new File(FS.DETECTED.userHome(), SSH_DIR);
SshdSessionFactory sshdSessionFactory = new SshdSessionFactoryBuilder()
.setPreferredAuthentications("publickey,keyboard-interactive,password")
.setHomeDirectory(FS.DETECTED.userHome())
.setSshDirectory(sshDir).build(new JGitKeyCache());
SshSessionFactory.setInstance(sshdSessionFactory);
}
In the init setup we defined the SSH dir that is present in the user's home.
The preferred authentication via ssh will be in the following order. First, it will try to connect through ssh public key; if this is not present the second way to initialize the session is through keyboard interaction and the last one is through giving a password to finalize the authentication.
NOTE: Please make sure you have defined an ssh public/private key in the user's home directory and a public key is presented on the remote machine.
If you want to clone a repository via HTTPS you have to skip the previous step and use the other way around.
- Clone a repository
public void cloneRepo(String remotePath, File localPath) {
try {
CloneCommand cloneCommand = new CloneCommand();
cloneCommand.setURI(remotePath);
cloneCommand.setProgressMonitor(new SimpleProgressMonitor());
cloneCommand.setDirectory(localPath);
cloneCommand.setBranch(DEFAULT_REMOTE_BRANCH);
cloneCommand.call();
} catch (Exception e) {
logger.error(e.getMessage());
}
}
This Git Library provides a nice way to monitor all the actions that are done by it through the interface ProgressMonitor
. You can do your implementation for this to handle different actions for the JGit Library.
The command to clone is very simple. You only have to define the ssh remote URI, a directory where you want to clone the remote repo, and the branch from where you want to clone the given repository.
- Git pull
public boolean gitPull(File localRepoPath, String branch) {
boolean pullSuccessful;
try (Git git = Git.open(repositoryLocalPath)) {
PullCommand pull = git.pull();
pull.setRemoteBranchName(remoteBranchName);
pull.setStrategy(MergeStrategy.RECURSIVE);
pull.setRebase(true);
pull.setProgressMonitor(new SimpleProgressMonitor());
PullResult result = pull.call();
pullSuccessful = result.isSuccessful();
} catch (Exception e) {
pullSuccessful = false;
logger.error(e.getMessage());
}
return pullSuccessful;
}
To do a git pull, we have to open the local repo (that was cloned previously) and instantiate the class PullCommand
to do this action. In this example, we use the git pull with rebase strategy, which means we will try to include the previous commits in the local commits.
- Git add
public void addFileToCommit(File repositoryLocalPath, String file) {
try (Git git = Git.open(repositoryLocalPath)) {
git.add().addFilepattern(file).setUpdate(true).call();
} catch (Exception e) {
logger.error(e.getMessage());
}
}
Add the changed file from the stage, to commit the changes. You will be able to configure the add command. The boolean update set on true mean:
If set to true, the command only matches file pattern against already tracked files in the index rather than the working tree. That means that it will never stage new files, but that it will stage modified new contents of tracked files and that it will remove files from the index if the corresponding files in the working tree have been removed. In contrast to the git command line, a file pattern must exist also if 'update' is set to true as there is no concept of a working directory here.— the definition from the JGit Java doc for that method.
- Git commit
public boolean commit(File repositoryLocalPath, String commitMessage) {
boolean actionSuccessful = false;
try (Git git = Git.open(repositoryLocalPath)) {
Status status = git.status().call();
if (status.hasUncommittedChanges()) {
git.commit().setMessage(commitMessage).call();
actionSuccessful = true;
}
} catch (Exception e) {
logger.error(e.getMessage());
}
return actionSuccessful;
}
You can commit your changes by simply call the commit method and set a specific message. To be more accurate I check the stage if there are any changes to do the commit action.
- Git push
public Iterable<PushResult> pushChanges(File repositoryLocalPath) {
Iterable<PushResult> pushResults = null;
try (Git git = Git.open(repositoryLocalPath)) {
PushCommand pushCommand = git.push();
pushCommand.setProgressMonitor(new SimpleProgressMonitor());
pushCommand.setPushAll();
pushResults = pushCommand.call();
} catch (Exception e) {
logger.error(e.getMessage());
}
return pushResults;
}
To push the changes remotely you have only to call the class PushCommand
. If you want to track all the actions that are done remotely, you can simply configure the interface SimpleProgressMonitor with his specific methods, exposed by this library. This method returns a PushResult if you want to check the result of the push command.
- Checkout to a branch
public boolean checkoutToBranch(File repositoryLocalPath, String branchName, boolean createNewBranch, boolean forceRefUpdate) {
boolean actionCompleted = false;
try (Git git = Git.open(repositoryLocalPath)) {
git.checkout()
.setCreateBranch(createNewBranch)
.setName(branchName)
.setProgressMonitor(new SimpleProgressMonitor())
.setForceRefUpdate(forceRefUpdate)
.call();
actionCompleted = true;
} catch (Exception e) {
logger.error(e.getMessage());
}
return actionCompleted;
}
You can check out to a new branch or use the existing one.
While moving to a new branch you can have different options to customize the checkout command. The boolean forceRefUpdate means: if true 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. — the definition from the JGit Java doc for that method.
- Get changed file from Git Stage
public Set<String> getModifiedFiles(File repositoryLocalPath) {
Set<String> modifiedFilesSet = null;
try (Git git = Git.open(repositoryLocalPath)) {
Status status = git.status().call();
Set<String> modifiedFiles = status.getModified();
modifiedFilesSet = new HashSet<>(modifiedFiles);
} catch (Exception e) {
logger.error(e.getMessage());
}
return modifiedFilesSet;
}
You can get the different status types from the git stage like deleted, untracked, missing files through the same class Status but calling a different method.
Conclusion
This library is very useful because exposes different APIs that handle different actions on git in Java application. This library has a big community that keeps it up to date.
If you want to handle different actions of Git command automatically, you can build your tool that only calls specific classes from this library without constructing the git command and execute that command through another process from java and to extract the output for the executed command and parse it. There are simple classes for each specific command that you can easily guess.
There more other classes and methods (more that was presented in the examples above) that you can handle more complex Git actions through this library.
If you have any questions join the Eclipse Foundation!
Opinions expressed by DZone contributors are their own.
Comments