CtrlK
BlogDocsLog inGet started
Tessl Logo

finkel/jgit

JGit documentation and API reference with code examples

92

1.09x
Quality

Pending

Does it follow best practices?

Impact

92%

1.09x

Average score across 10 eval scenarios

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

index.mddocs/basics/

Repository Basics

This section covers fundamental operations for working with Git repositories using JGit.

JGit Concepts

Repository

A Repository holds all objects and refs used for managing source code. Use RepositoryBuilder to create repository instances.

import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.storage.file.FileRepositoryBuilder;
import java.io.File;

public class RepositoryBuilderExample {
    public static void main(String[] args) throws Exception {
        FileRepositoryBuilder builder = new FileRepositoryBuilder();
        Repository repository = builder
            .setGitDir(new File("/my/git/directory"))
            .readEnvironment() // Scan environment GIT_* variables
            .findGitDir() // Scan up the file system tree
            .build();
    }
}

Git Objects

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

Object Types:

  • Blob: Stores file data
  • Tree: Acts like a directory; references other trees and blobs
  • Commit: Points to a single tree
  • Tag: Marks a commit as special (e.g., releases)
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.lib.ObjectId;

public class ResolveObjectExample {
    public static void main(String[] args) throws Exception {
        Repository repository = // ... get repository

        // Resolve object from revision string
        ObjectId head = repository.resolve("HEAD");
        System.out.println("HEAD SHA-1: " + head.getName());
    }
}

Ref

A ref is a variable that holds a single object identifier (blob, tree, commit, or tag).

import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.lib.Ref;

public class RefExample {
    public static void main(String[] args) throws Exception {
        Repository repository = // ... get repository

        // Query reference
        Ref HEAD = repository.exactRef("refs/heads/master");
        System.out.println("Master ref: " + HEAD.getObjectId().getName());
    }
}

RevWalk

A RevWalk walks a commit graph and produces matching commits in order.

import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevWalk;

public class RevWalkExample {
    public static void main(String[] args) throws Exception {
        Repository repository = // ... get repository

        RevWalk walk = new RevWalk(repository);
        // Configure walk with filters, start points, etc.
    }
}

RevCommit

A RevCommit represents a commit in the Git object model.

import org.eclipse.jgit.revwalk.RevWalk;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.lib.ObjectId;

public class ParseCommitExample {
    public static void main(String[] args) throws Exception {
        Repository repository = // ... get repository
        ObjectId commitId = repository.resolve("HEAD");

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

        System.out.println("Commit message: " + commit.getFullMessage());
        System.out.println("Author: " + commit.getAuthorIdent().getName());
        walk.dispose();
    }
}

RevTag and RevTree

  • RevTag: Represents a tag in the Git object model
  • RevTree: Represents a tree in the Git object model
import org.eclipse.jgit.revwalk.RevWalk;
import org.eclipse.jgit.revwalk.RevTag;
import org.eclipse.jgit.revwalk.RevTree;

public class ParseTagAndTreeExample {
    public static void main(String[] args) throws Exception {
        Repository repository = // ... get repository
        RevWalk walk = new RevWalk(repository);

        // Parse tag
        ObjectId tagId = repository.resolve("refs/tags/v1.0");
        RevTag tag = walk.parseTag(tagId);

        // Parse tree
        ObjectId treeId = repository.resolve("HEAD^{tree}");
        RevTree tree = walk.parseTree(treeId);

        walk.dispose();
    }
}

Opening Repositories

Open an Existing Repository

import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.storage.file.FileRepositoryBuilder;
import java.io.File;

public class OpenRepositoryExample {
    public static void main(String[] args) throws Exception {
        FileRepositoryBuilder builder = new FileRepositoryBuilder();

        try (Repository repository = builder
                .setGitDir(new File("/path/to/your/.git"))
                .readEnvironment() // Read GIT_* environment variables
                .findGitDir() // Scan up the file system tree
                .build()) {

            System.out.println("Repository opened: " + repository.getDirectory());
            System.out.println("Work directory: " + repository.getWorkTree());

            // Get the current HEAD reference
            var head = repository.exactRef("refs/heads/main");
            System.out.println("HEAD: " + head);
        }
    }
}

Open Repository with Various Methods

import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.storage.file.FileRepositoryBuilder;
import java.io.File;

public class OpenRepositoryVariations {
    public static void main(String[] args) throws Exception {
        // Method 1: Direct path to .git directory
        Repository repo1 = new FileRepositoryBuilder()
            .setGitDir(new File("/path/to/.git"))
            .build();

        // Method 2: Path to working directory
        Repository repo2 = new FileRepositoryBuilder()
            .readEnvironment()
            .findGitDir(new File("/path/to/working/dir"))
            .build();

        // Method 3: Bare repository
        Repository repo3 = new FileRepositoryBuilder()
            .setGitDir(new File("/path/to/bare.git"))
            .setMustExist(true)
            .setBare()
            .build();

        // Always close repositories
        repo1.close();
        repo2.close();
        repo3.close();
    }
}

Creating Repositories

Create a New Repository

import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.errors.GitAPIException;
import java.io.File;
import java.io.IOException;

public class CreateRepositoryExample {
    public static void main(String[] args) throws IOException, GitAPIException {
        // Create a directory for the repository
        File repoDir = new File("/tmp/my-repo");

        if (!repoDir.mkdirs()) {
            throw new IOException("Could not create directory: " + repoDir);
        }

        // Initialize the repository
        try (Git git = Git.init()
                .setDirectory(repoDir)
                .setBare(false) // Non-bare repository (has working tree)
                .call()) {

            System.out.println("Repository created at: " + git.getRepository().getDirectory());
            System.out.println("Working tree at: " + git.getRepository().getWorkTree());
        }
    }
}

Create a Bare Repository

import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.errors.GitAPIException;
import java.io.File;
import java.io.IOException;

public class CreateBareRepositoryExample {
    public static void main(String[] args) throws IOException, GitAPIException {
        File repoDir = new File("/tmp/my-bare-repo.git");

        if (!repoDir.mkdirs()) {
            throw new IOException("Could not create directory: " + repoDir);
        }

        try (Git git = Git.init()
                .setDirectory(repoDir)
                .setBare(true) // Bare repository (no working tree)
                .call()) {

            System.out.println("Bare repository created at: " + git.getRepository().getDirectory());
        }
    }
}

Repository Information

Get Repository Metadata

import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.storage.file.FileRepositoryBuilder;
import java.io.File;

public class RepositoryInfoExample {
    public static void main(String[] args) throws Exception {
        try (Repository repository = new FileRepositoryBuilder()
                .setGitDir(new File("/path/to/.git"))
                .build()) {

            System.out.println("Repository directory: " + repository.getDirectory());
            System.out.println("Work tree: " + repository.getWorkTree());
            System.out.println("Is bare: " + repository.isBare());
            System.out.println("Object database: " + repository.getObjectDatabase());

            // Get configured remotes
            var config = repository.getConfig();
            var remotes = config.getSubsections("remote");
            System.out.println("Remotes: " + remotes);

            // Get user configuration
            var user = config.getString("user", null, "name");
            var email = config.getString("user", null, "email");
            System.out.println("User: " + user + " <" + email + ">");
        }
    }
}

Working with References

List All References

import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.storage.file.FileRepositoryBuilder;
import java.io.File;
import java.util.Map;

public class ListReferencesExample {
    public static void main(String[] args) throws Exception {
        try (Repository repository = new FileRepositoryBuilder()
                .setGitDir(new File("/path/to/.git"))
                .build()) {

            // Get all references
            Map<String, Ref> allRefs = repository.getAllRefs();

            System.out.println("All references:");
            for (Map.Entry<String, Ref> entry : allRefs.entrySet()) {
                System.out.println("  " + entry.getKey() + " -> " + entry.getValue().getObjectId().getName());
            }

            // Get specific references
            Ref head = repository.exactRef("HEAD");
            Ref master = repository.exactRef("refs/heads/master");

            System.out.println("\nHEAD: " + head);
            System.out.println("master: " + master);
        }
    }
}

Basic Repository Operations

Check if Repository Exists

import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.storage.file.FileRepositoryBuilder;
import java.io.File;

public class CheckRepositoryExists {
    public static void main(String[] args) {
        File gitDir = new File("/path/to/.git");
        File workDir = new File("/path/to/working/dir");

        FileRepositoryBuilder builder = new FileRepositoryBuilder();

        // Check if .git directory exists
        if (gitDir.exists() && gitDir.isDirectory()) {
            System.out.println(".git directory exists");
        }

        // Try to find Git directory
        try {
            Repository repo = builder
                .readEnvironment()
                .findGitDir(workDir)
                .build();
            System.out.println("Found repository at: " + repo.getDirectory());
            repo.close();
        } catch (Exception e) {
            System.out.println("No repository found: " + e.getMessage());
        }
    }
}

Common Patterns

Safe Repository Access Pattern

import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.storage.file.FileRepositoryBuilder;
import java.io.File;

public class SafeRepositoryAccess {
    public static void withRepository(String path, RepositoryOperation operation) throws Exception {
        FileRepositoryBuilder builder = new FileRepositoryBuilder();

        try (Repository repository = builder
                .setGitDir(new File(path, ".git"))
                .readEnvironment()
                .findGitDir()
                .setMustExist(true)
                .build()) {

            operation.execute(repository);
        }
    }

    @FunctionalInterface
    public interface RepositoryOperation {
        void execute(Repository repository) throws Exception;
    }

    public static void main(String[] args) throws Exception {
        withRepository("/path/to/repo", repo -> {
            System.out.println("Repository: " + repo.getDirectory());
            // Perform operations on repository
        });
    }
}

Error Handling

Graceful Error Handling

import org.eclipse.jgit.errors.RepositoryNotFoundException;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.storage.file.FileRepositoryBuilder;
import java.io.File;

public class RepositoryErrorHandling {
    public static Repository openRepositorySafely(String path) {
        try {
            return new FileRepositoryBuilder()
                .setGitDir(new File(path, ".git"))
                .setMustExist(true)
                .build();
        } catch (RepositoryNotFoundException e) {
            System.err.println("Repository not found at: " + path);
            return null;
        } catch (Exception e) {
            System.err.println("Error opening repository: " + e.getMessage());
            return null;
        }
    }

    public static void main(String[] args) {
        Repository repo = openRepositorySafely("/path/to/repo");
        if (repo != null) {
            try {
                System.out.println("Successfully opened: " + repo.getDirectory());
                repo.close();
            } catch (Exception e) {
                System.err.println("Error using repository: " + e.getMessage());
            }
        }
    }
}

Handling GitAPIException and IOException

JGit operations throw two main exception types:

  • GitAPIException: Thrown by high-level porcelain commands (Git class operations)
  • IOException: Thrown by low-level operations and file system access
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.storage.file.FileRepositoryBuilder;
import java.io.File;
import java.io.IOException;

public class GitExceptionHandling {
    
    /**
     * Example showing proper handling of GitAPIException and IOException
     */
    public static void initializeRepositoryWithErrorHandling(File repoDir) {
        try (Repository repository = new FileRepositoryBuilder()
                .setGitDir(new File(repoDir, ".git"))
                .build()) {
            
            try (Git git = new Git(repository)) {
                // Initialize repository if it doesn't exist
                if (!repository.getObjectDatabase().exists()) {
                    git.init()
                        .setDirectory(repoDir)
                        .setBare(false)
                        .call();
                    System.out.println("Repository initialized");
                }
                
                // Add and commit a file
                File newFile = new File(repoDir, "README.md");
                if (newFile.createNewFile()) {
                    git.add()
                        .addFilepattern("README.md")
                        .call();
                    
                    git.commit()
                        .setMessage("Add README")
                        .call();
                    System.out.println("File committed");
                }
                
            } catch (GitAPIException e) {
                // Handle Git-specific errors
                System.err.println("Git operation failed: " + e.getMessage());
                // Consider retry logic for transient errors
                if (e.getMessage().contains("transport")) {
                    System.err.println("Network error - consider retrying");
                }
            }
            
        } catch (IOException e) {
            // Handle file system errors
            System.err.println("IO error accessing repository: " + e.getMessage());
            if (e.getMessage().contains("Permission denied")) {
                System.err.println("Check file permissions");
            }
        }
    }
    
    /**
     * Wrapper method that converts exceptions to meaningful error types
     */
    public static boolean safeGitOperation(File repoDir, GitOperation operation) {
        try (Repository repository = new FileRepositoryBuilder()
                .setGitDir(new File(repoDir, ".git"))
                .setMustExist(true)
                .build()) {
            
            try (Git git = new Git(repository)) {
                operation.execute(git);
                return true;
            } catch (GitAPIException e) {
                System.err.println("Git API error: " + e.getMessage());
                return false;
            }
            
        } catch (IOException e) {
            System.err.println("Repository access error: " + e.getMessage());
            return false;
        }
    }
    
    @FunctionalInterface
    public interface GitOperation {
        void execute(Git git) throws GitAPIException, IOException;
    }
    
    public static void main(String[] args) {
        File repoDir = new File("/path/to/repo");
        
        // Example 1: Direct error handling
        initializeRepositoryWithErrorHandling(repoDir);
        
        // Example 2: Using wrapper with functional interface
        boolean success = safeGitOperation(repoDir, git -> {
            git.add()
                .addFilepattern(".")
                .call();
            git.commit()
                .setMessage("Update files")
                .call();
        });
        
        System.out.println("Operation successful: " + success);
    }
}

Best Practices for Exception Handling

  1. Always close resources: Use try-with-resources for Repository, Git, RevWalk, and TreeWalk objects
  2. Catch specific exceptions: Handle GitAPIException and IOException separately
  3. Provide meaningful error messages: Include context about what operation failed
  4. Consider recovery strategies: For network operations, implement retry logic
  5. Clean up on failure: Ensure resources are released even when exceptions occur

See Error Handling in Patterns for more advanced patterns.

Next Steps

After mastering repository basics, explore:

docs

basics

index.md

index.md

tile.json