My new website on Artificial Intelligence and Machine Learning www.aimlfront.com

Setup JGit(Git with Java)

1. Add maven entry in pom.xml: There are a number of ways to connect your project with JGit and start writing code against it. Probably the easiest is to use Maven - the integration is accomplished by adding the following snippet to the <dependencies> tag in your pom.xml file:

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

The version will most likely have advanced by the time you read this; check http://mvnrepository.com/artifact/org.eclipse.jgit/org.eclipse.jgit for updated repository information. Once this step is done, Maven will automatically acquire and use the JGit libraries that you'll need.


2. Create Repository for Git: The starting point for most JGit sessions is the Repository class, and the first thing you'll want to do is create an instance of it. For a filesystem-based repository (yes, JGit allows for other storage models), this is accomplished using FileRepositoryBuilder:

import java.io.File;
import java.io.IOException;

import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.storage.file.FileRepositoryBuilder;

/**
 * Simple snippet which shows how to create a new repository
 * 
 * @author Soha
 */
public class JGitHelper {

    public static Repository openJGitCookbookRepository() throws IOException {
        FileRepositoryBuilder builder = new FileRepositoryBuilder();
        Repository repository = builder
                .readEnvironment() // scan environment GIT_* variables
                .findGitDir() // scan up the file system tree
                .build();
        return repository;
    }

    public static Repository createNewRepository() throws IOException {
        // prepare a new folder
        Repository repository = FileRepositoryBuilder.create( new File("/tmp/new_repo/.git"));
        repository.create();

        return repository;
    }
}

3. Open an existing repository:

import java.io.File;
import java.io.IOException;

import org.dstadler.jgit.helper.CookbookHelper;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.storage.file.FileRepositoryBuilder;



/**
 * Simple snippet which shows how to open an existing repository
 * 
 * @author Soha
 */
public class OpenRepository {

    public static void main(String[] args) throws IOException, GitAPIException {
        // first create a test-repository, the return is including the .get directory here!
        File repoDir = createSampleGitRepo();
        
        // now open the resulting repository with a FileRepositoryBuilder
        FileRepositoryBuilder builder = new FileRepositoryBuilder();
        try (Repository repository = builder.setGitDir(repoDir)
                .readEnvironment() // scan environment GIT_* variables
                .findGitDir() // scan up the file system tree
                .build()) {
            System.out.println("Having repository: " + repository.getDirectory());
    
            // the Ref holds an ObjectId for any type of object (tree, commit, blob, tree)
            Ref head = repository.getRef("refs/heads/master");
            System.out.println("Ref of refs/heads/master: " + head);
        }
    }

    private static File createSampleGitRepo() throws IOException, GitAPIException {
        try (Repository repository = JGitHelper.createNewRepository()) {
            System.out.println("Temporary repository at " + repository.getDirectory());
    
            // create the file
            File myfile = new File(repository.getDirectory().getParent(), "testfile");
            myfile.createNewFile();
    
            // run the add-call
            try (Git git = new Git(repository)) {
                git.add()
                        .addFilepattern("testfile")
                        .call();
        
        
                // and then commit the changes
                git.commit()
                        .setMessage("Added testfile")
                        .call();
            }
            
            System.out.println("Added file " + myfile + " to repository at " + repository.getDirectory());
            
            File dir = repository.getDirectory();
            
            return dir;
        }
    }
}

The builder has a fluent API for providing all the things it needs to find a Git repository, whether or not your program knows exactly where it's located. It can use environment variables (.readEnvironment()), start from a place in the working directory and search (.setWorkTree(...).findGitDir()), or just open a known .git directory as above.
Once you have a Repository instance, you can do all sorts of things with it. Here's a quick sampling:

// Get a reference
Ref master = repo.getRef("master");

// Get the object the reference points to
ObjectId masterTip = master.getObjectId();

// Rev-parse
ObjectId obj = repo.resolve("HEAD^{tree}");

// Load raw object contents
ObjectLoader loader = repo.open(masterTip);
loader.copyTo(System.out);

// Create a branch
RefUpdate createBranch1 = repo.updateRef("refs/heads/branch1");
createBranch1.setNewObjectId(masterTip);
createBranch1.update();

// Delete a branch
RefUpdate deleteBranch1 = repo.updateRef("refs/heads/branch1");
deleteBranch1.setForceUpdate(true);
deleteBranch1.delete();

// Config
Config cfg = repo.getConfig();
String name = cfg.getString("user", null, "name");

here's quite a bit going on here, so let's go through it one section at a time.

The first line gets a pointer to the master reference. JGit automatically grabs the actual master ref, which lives at refs/heads/master, and returns an object that lets you fetch information about the reference. You can get the name (.getName()), and either the target object of a direct reference (.getObjectId()) or the reference pointed to by a symbolic ref (.getTarget()). Ref objects are also used to represent tag refs and objects, so you can ask if the tag is "peeled," meaning that it points to the final target of a (potentially long) string of tag objects.

The second line gets the target of the master reference, which is returned as an ObjectId instance. ObjectId represents the SHA-1 hash of an object, which might or might not exist in Git's object database. The third line is similar, but shows how JGit handles the rev-parse syntax (for more on this, see Branch References); you can pass any object specifier that Git understands, and JGit will return either a valid ObjectId for that object, or null.

The next two lines show how to load the raw contents of an object. In this example, we call ObjectLoader.copyTo() to stream the contents of the object directly to stdout, but ObjectLoader also has methods to read the type and size of an object, as well as return it as a byte array. For large objects (where .isLarge() returns true), you can call .openStream() to get an InputStream-like object that can read the raw object data without pulling it all into memory at once.

The next few lines show what it takes to create a new branch. We create a RefUpdate instance, configure some parameters, and call .update() to trigger the change. Directly following this is the code to delete that same branch. Note that .setForceUpdate(true) is required for this to work; otherwise the .delete() call will return REJECTED, and nothing will happen.

4. Connecting Git Remotely : The Git class has a nice set of high-level builder-style methods that can be used to construct some pretty complex behavior. Let's take a look at an example - doing something like git ls-remote:

import java.io.File;
import java.io.IOException;

import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.api.errors.InvalidRemoteException;
import org.eclipse.jgit.api.errors.TransportException;
import org.eclipse.jgit.errors.UnsupportedCredentialItem;
import org.eclipse.jgit.transport.CredentialItem;
import org.eclipse.jgit.transport.CredentialsProvider;
import org.eclipse.jgit.transport.URIish;



/**
 * Simple snippet which shows how to clone a repository from a remote source
 * via ssh protocol and username/password authentication.
 *
 * @author Soha
 */
public class CloneRemoteRepositoryWithAuthentication {
    private static final String REMOTE_URL = "ssh://<user>:<pwd>@<host>:22/<path-to-remote-repo>/";

    public static void main(String[] args) throws IOException, InvalidRemoteException, TransportException, GitAPIException {
        // this is necessary when the remote host does not have a valid certificate, ideally we would install the certificate in the JVM
        // instead of this unsecure workaround!
        CredentialsProvider allowHosts = new CredentialsProvider() {

            @Override
            public boolean supports(CredentialItem... items) {
                for(CredentialItem item : items) {
                    if((item instanceof CredentialItem.YesNoType)) {
                        return true;
                    }
                }
                return false;
            }

            @Override
            public boolean get(URIish uri, CredentialItem... items) throws UnsupportedCredentialItem {
                for(CredentialItem item : items) {
                    if(item instanceof CredentialItem.YesNoType) {
                        ((CredentialItem.YesNoType)item).setValue(true);
                        return true;
                    }
                }
                return false;
            }

            @Override
            public boolean isInteractive() {
                return false;
            }
        };

        // prepare a new folder for the cloned repository
        File localPath = File.createTempFile("TestGitRepository", "");
        localPath.delete();

        // then clone
        System.out.println("Cloning from " + REMOTE_URL + " to " + localPath);
        try (Git result = Git.cloneRepository()
                .setURI(REMOTE_URL)
                .setDirectory(localPath)
                .setCredentialsProvider(allowHosts)
                .call()) {
	        // Note: the call() returns an opened repository already which needs to be closed to avoid file handle leaks!
	        System.out.println("Having repository: " + result.getRepository().getDirectory());

            // workaround for https://bugs.eclipse.org/bugs/show_bug.cgi?id=474093
            result.getRepository().close();
        }
    }
}

This is a common pattern with the Git class; the methods return a command object that lets you chain method calls to set parameters, which are executed when you call .call(). In this case, we're asking the origin remote for tags, but not heads. Also notice the use of a CredentialsProvider object for authentication.

Many other commands are available through the Git class, including but not limited to add, blame, commit, clean, push, rebase, revert, and reset.



GitHub

GitHub is a Web-based Git repository hosting service. It offers all of the distributed revision control and source code management (SCM) functionality of Git as well as adding its own features.

Learn More

Git

Git is a free and open source distributed version control system designed to handle everything from small to very large projects with speed and efficiency.

Learn More

EGit

EGit is an Eclipse Team provider for the Git version control system. Git is a distributed SCM, which means every developer has a full copy of all history of every revision of the code, making queries against the history very fast and versatile.

Learn More