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/porcelain/

Porcelain Commands

Porcelain commands are high-level JGit APIs that mirror Git CLI commands. They provide a convenient way to perform common Git operations.

Table of Contents

  1. Basic Operations
  2. Commit Operations
  3. Branch Operations
  4. Tag Operations
  5. Diff and Status
  6. Stash Operations
  7. Clean and GC
  8. Notes
  9. Archive
  10. Ant Tasks

Porcelain API Overview

JGit provides a high-level Porcelain API in the org.eclipse.jgit.api package that mimics Git command-line operations. Key command classes include:

AddCommand (git-add)

Adds files to the index with options via setter methods like addFilepattern().

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

CommitCommand (git-commit)

Performs commits with setters for author, committer, message, etc.

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

TagCommand (git-tag)

Supports various tagging options through setter methods.

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

LogCommand (git-log)

Walks commit graphs with methods like add() and addRange().

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

MergeCommand (git-merge)

TODO (not fully documented in reference)

Other Commands

  • CloneCommand: Clone repositories
  • FetchCommand: Fetch from remotes
  • PullCommand: Pull changes
  • PushCommand: Push changes
  • CheckoutCommand: Checkout branches/files
  • BranchCommand: Manage branches
  • MergeCommand: Merge branches

Basic Operations

Add Files to Index

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

public class AddFileExample {
    public static void main(String[] args) throws IOException, GitAPIException {
        try (Repository repository = openRepository()) {
            try (Git git = new Git(repository)) {
                // Create a new file
                File newFile = new File(repository.getWorkTree(), "example.txt");
                newFile.createNewFile();

                // Add file to index
                git.add()
                    .addFilepattern("example.txt")
                    .call();

                System.out.println("Added file to index: " + newFile.getAbsolutePath());
            }
        }
    }

    private static Repository openRepository() throws IOException {
        // Implementation to open repository
        return null;
    }
}

Commit Changes

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

public class CommitExample {
    public static void main(String[] args) throws IOException, GitAPIException {
        try (Repository repository = openRepository()) {
            try (Git git = new Git(repository)) {
                // Stage changes
                git.add()
                    .addFilepattern(".")
                    .call();

                // Create commit
                git.commit()
                    .setMessage("Update example file")
                    .setAuthor("John Doe", "john@example.com")
                    .setCommitter("Jane Smith", "jane@example.com")
                    .call();

                System.out.println("Changes committed successfully");
            }
        }
    }

    private static Repository openRepository() throws IOException {
        // Implementation to open repository
        return null;
    }
}

Commit All Changes

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

public class CommitAllExample {
    public static void main(String[] args) throws IOException, GitAPIException {
        try (Repository repository = openRepository()) {
            try (Git git = new Git(repository)) {
                // Commit all changes (adds and commits in one operation)
                git.commit()
                    .setAll(true)
                    .setMessage("Commit all changes")
                    .call();

                System.out.println("All changes committed");
            }
        }
    }

    private static Repository openRepository() throws IOException {
        // Implementation to open repository
        return null;
    }
}

Error Handling in Porcelain Commands

Porcelain commands throw GitAPIException for Git-specific errors. Proper error handling is essential for robust applications.

Catching and Handling GitAPIException

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 PorcelainErrorHandling {
    
    public static void addFileWithErrorHandling(Repository repository, String filePattern) {
        try (Git git = new Git(repository)) {
            git.add()
                .addFilepattern(filePattern)
                .call();
            System.out.println("Successfully added: " + filePattern);
            
        } catch (GitAPIException e) {
            System.err.println("Failed to add file: " + e.getMessage());
            
            // Handle specific error cases
            if (e.getMessage().contains("does not exist")) {
                System.err.println("File not found: " + filePattern);
            } else if (e.getMessage().contains("cannot add")) {
                System.err.println("Permission denied or invalid file: " + filePattern);
            }
            
            // Consider logging the full exception for debugging
            e.printStackTrace();
        }
    }
    
    public static void commitWithRetry(Repository repository, String message, int maxRetries) {
        for (int attempt = 1; attempt <= maxRetries; attempt++) {
            try (Git git = new Git(repository)) {
                git.commit()
                    .setMessage(message)
                    .call();
                System.out.println("Commit successful");
                return;
                
            } catch (GitAPIException e) {
                System.err.println("Commit attempt " + attempt + " failed: " + e.getMessage());
                
                if (attempt == maxRetries) {
                    throw new RuntimeException("Failed to commit after " + maxRetries + " attempts", e);
                }
                
                // Wait before retry
                try {
                    Thread.sleep(1000 * attempt); // Exponential backoff
                } catch (InterruptedException ie) {
                    Thread.currentThread().interrupt();
                    throw new RuntimeException("Interrupted during retry", ie);
                }
            }
        }
    }
    
    public static void main(String[] args) throws IOException {
        try (Repository repository = new FileRepositoryBuilder()
                .setGitDir(new File("/path/to/.git"))
                .build()) {
            
            // Example 1: Basic error handling
            addFileWithErrorHandling(repository, "README.md");
            
            // Example 2: Retry logic for transient failures
            commitWithRetry(repository, "Important update", 3);
        }
    }
}

Comprehensive Error Handling Pattern

For production code, consider a more structured approach:

import org.eclipse.jgit.api.errors.GitAPIException;
import java.util.function.Supplier;

public class GitOperationExecutor {
    
    public static <T> T executeWithHandling(
            Supplier<T> operation,
            String operationName,
            ErrorHandler<T> errorHandler) {
        
        try {
            return operation.get();
        } catch (GitAPIException e) {
            return errorHandler.handleGitApiError(operationName, e);
        } catch (Exception e) {
            return errorHandler.handleUnexpectedError(operationName, e);
        }
    }
    
    public interface ErrorHandler<T> {
        T handleGitApiError(String operationName, GitAPIException e);
        T handleUnexpectedError(String operationName, Exception e);
    }
    
    // Example usage
    public static class LoggingErrorHandler<T> implements ErrorHandler<T> {
        private final T defaultValue;
        
        public LoggingErrorHandler(T defaultValue) {
            this.defaultValue = defaultValue;
        }
        
        @Override
        public T handleGitApiError(String operationName, GitAPIException e) {
            System.err.println("Git API error in " + operationName + ": " + e.getMessage());
            return defaultValue;
        }
        
        @Override
        public T handleUnexpectedError(String operationName, Exception e) {
            System.err.println("Unexpected error in " + operationName + ": " + e.getMessage());
            e.printStackTrace();
            return defaultValue;
        }
    }
}

Best Practices

  1. Always use try-with-resources for Git objects
  2. Catch GitAPIException close to where it's thrown to provide context
  3. Handle specific error conditions (file not found, permission denied, network errors)
  4. Implement retry logic for transient failures (network operations)
  5. Log meaningful error messages including the operation being performed
  6. Clean up resources even when exceptions occur

See Error Handling in Patterns for more advanced error handling patterns.

Commit Operations

Show Commit Log

import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevCommit;
import java.io.IOException;
import java.util.List;

public class ShowLogExample {
    public static void main(String[] args) throws IOException, GitAPIException {
        try (Repository repository = openRepository()) {
            try (Git git = new Git(repository)) {
                // Get commit log
                Iterable<RevCommit> logs = git.log()
                    .setMaxCount(10)
                    .call();

                System.out.println("Recent commits:");
                for (RevCommit commit : logs) {
                    System.out.println("Commit: " + commit.getName());
                    System.out.println("Author: " + commit.getAuthorIdent().getName());
                    System.out.println("Message: " + commit.getShortMessage());
                    System.out.println("Time: " + commit.getAuthorIdent().getWhen());
                    System.out.println("---");
                }
            }
        }
    }

    private static Repository openRepository() throws IOException {
        // Implementation to open repository
        return null;
    }
}

Walk Through All Commits

import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevCommit;
import java.io.IOException;

public class WalkAllCommitsExample {
    public static void main(String[] args) throws IOException, GitAPIException {
        try (Repository repository = openRepository()) {
            try (Git git = new Git(repository)) {
                // Walk through all commits
                Iterable<RevCommit> commits = git.log()
                    .all()
                    .call();

                int count = 0;
                for (RevCommit commit : commits) {
                    count++;
                    System.out.println("Commit #" + count + ": " + commit.getShortMessage());
                }
                System.out.println("Total commits: " + count);
            }
        }
    }

    private static Repository openRepository() throws IOException {
        // Implementation to open repository
        return null;
    }
}

Branch Operations

List Branches

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 java.io.IOException;
import java.util.List;

public class ListBranchesExample {
    public static void main(String[] args) throws IOException, GitAPIException {
        try (Repository repository = openRepository()) {
            try (Git git = new Git(repository)) {
                // List local branches
                List<Ref> branches = git.branchList()
                    .call();

                System.out.println("Local branches:");
                for (Ref branch : branches) {
                    System.out.println("  " + branch.getName());
                }

                // List all branches (including remote)
                List<Ref> allBranches = git.branchList()
                    .setListMode(ListBranchCommand.ListMode.ALL)
                    .call();

                System.out.println("\nAll branches:");
                for (Ref branch : allBranches) {
                    System.out.println("  " + branch.getName());
                }
            }
        }
    }

    private static Repository openRepository() throws IOException {
        // Implementation to open repository
        return null;
    }
}

Create and Delete Branches

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 java.io.IOException;

public class BranchOperationsExample {
    public static void main(String[] args) throws IOException, GitAPIException {
        try (Repository repository = openRepository()) {
            try (Git git = new Git(repository)) {
                // Create a new branch
                Ref newBranch = git.branchCreate()
                    .setName("feature/new-feature")
                    .call();

                System.out.println("Created branch: " + newBranch.getName());

                // Delete a branch
                String branchToDelete = "old-branch";
                try {
                    git.branchDelete()
                        .setBranchNames(branchToDelete)
                        .setForce(true)
                        .call();
                    System.out.println("Deleted branch: " + branchToDelete);
                } catch (Exception e) {
                    System.out.println("Could not delete branch: " + e.getMessage());
                }
            }
        }
    }

    private static Repository openRepository() throws IOException {
        // Implementation to open repository
        return null;
    }
}

Tag Operations

List Tags

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 java.io.IOException;
import java.util.List;

public class ListTagsExample {
    public static void main(String[] args) throws IOException, GitAPIException {
        try (Repository repository = openRepository()) {
            try (Git git = new Git(repository)) {
                // List all tags
                List<Ref> tags = git.tagList()
                    .call();

                System.out.println("Tags:");
                for (Ref tag : tags) {
                    System.out.println("  " + tag.getName());
                }
            }
        }
    }

    private static Repository openRepository() throws IOException {
        // Implementation to open repository
        return null;
    }
}

Create and Delete Tags

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 java.io.IOException;

public class TagOperationsExample {
    public static void main(String[] args) throws IOException, GitAPIException {
        try (Repository repository = openRepository()) {
            try (Git git = new Git(repository)) {
                // Create lightweight tag
                Ref lightweightTag = git.tag()
                    .setName("v1.0.0")
                    .call();

                System.out.println("Created lightweight tag: " + lightweightTag.getName());

                // Create annotated tag
                Ref annotatedTag = git.tag()
                    .setName("v1.0.0-annotated")
                    .setMessage("Release version 1.0.0")
                    .setTagger(new PersonIdent("Tagger", "tagger@example.com"))
                    .call();

                System.out.println("Created annotated tag: " + annotatedTag.getName());

                // Delete tag
                String tagToDelete = "old-tag";
                try {
                    git.tagDelete()
                        .setTags(tagToDelete)
                        .call();
                    System.out.println("Deleted tag: " + tagToDelete);
                } catch (Exception e) {
                    System.out.println("Could not delete tag: " + e.getMessage());
                }
            }
        }
    }

    private static Repository openRepository() throws IOException {
        // Implementation to open repository
        return null;
    }
}

Diff and Status

Show Status

import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.Status;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.lib.Repository;
import java.io.IOException;
import java.util.Set;

public class ShowStatusExample {
    public static void main(String[] args) throws IOException, GitAPIException {
        try (Repository repository = openRepository()) {
            try (Git git = new Git(repository)) {
                Status status = git.status()
                    .call();

                System.out.println("Repository status:");
                System.out.println("Added: " + status.getAdded());
                System.out.println("Changed: " + status.getChanged());
                System.out.println("Modified: " + status.getModified());
                System.out.println("Removed: " + status.getRemoved());
                System.out.println("Missing: " + status.getMissing());
                System.out.println("Untracked: " + status.getUntracked());
                System.out.println("Conflicting: " + status.getConflicting());
            }
        }
    }

    private static Repository openRepository() throws IOException {
        // Implementation to open repository
        return null;
    }
}

Show Diff Between Commits

import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.diff.DiffEntry;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevCommit;
import java.io.IOException;
import java.util.List;

public class ShowDiffExample {
    public static void main(String[] args) throws IOException, GitAPIException {
        try (Repository repository = openRepository()) {
            try (Git git = new Git(repository)) {
                // Get two commits to compare
                Iterable<RevCommit> commits = git.log()
                    .setMaxCount(2)
                    .call();

                RevCommit[] commitArray = new RevCommit[2];
                int i = 0;
                for (RevCommit commit : commits) {
                    commitArray[i++] = commit;
                    if (i >= 2) break;
                }

                if (commitArray[0] != null && commitArray[1] != null) {
                    List<DiffEntry> diffs = git.diff()
                        .setOldTree(commitArray[1])
                        .setNewTree(commitArray[0])
                        .call();

                    System.out.println("Diff between " + commitArray[1].getName() +
                                     " and " + commitArray[0].getName() + ":");
                    for (DiffEntry diff : diffs) {
                        System.out.println("  " + diff.getChangeType() + ": " +
                                         diff.getOldPath() + " -> " + diff.getNewPath());
                    }
                }
            }
        }
    }

    private static Repository openRepository() throws IOException {
        // Implementation to open repository
        return null;
    }
}

Stash Operations

Create and Apply Stash

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

public class StashOperationsExample {
    public static void main(String[] args) throws IOException, GitAPIException {
        try (Repository repository = openRepository()) {
            try (Git git = new Git(repository)) {
                // Create stash
                git.stashCreate()
                    .call();

                System.out.println("Created stash");

                // List stashes
                var stashList = git.stashList()
                    .call();

                System.out.println("Stashes:");
                for (var stash : stashList) {
                    System.out.println("  " + stash.getName());
                }

                // Apply latest stash
                if (!stashList.isEmpty()) {
                    git.stashApply()
                        .call();
                    System.out.println("Applied latest stash");
                }
            }
        }
    }

    private static Repository openRepository() throws IOException {
        // Implementation to open repository
        return null;
    }
}

Clean and GC

Clean Untracked Files

import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.CleanCommand;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.lib.Repository;
import java.io.IOException;
import java.util.Set;

public class CleanUntrackedFilesExample {
    public static void main(String[] args) throws IOException, GitAPIException {
        try (Repository repository = openRepository()) {
            try (Git git = new Git(repository)) {
                // Clean untracked files
                Set<String> cleaned = git.clean()
                    .setCleanDirectories(true)
                    .setDryRun(false) // Set to true to see what would be cleaned
                    .call();

                System.out.println("Cleaned files: " + cleaned);
            }
        }
    }

    private static Repository openRepository() throws IOException {
        // Implementation to open repository
        return null;
    }
}

Run Garbage Collection

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

public class GarbageCollectionExample {
    public static void main(String[] args) throws IOException, GitAPIException {
        try (Repository repository = openRepository()) {
            try (Git git = new Git(repository)) {
                // Run garbage collection
                git.gc()
                    .setAggressive(true)
                    .call();

                System.out.println("Garbage collection completed");
            }
        }
    }

    private static Repository openRepository() throws IOException {
        // Implementation to open repository
        return null;
    }
}

Notes

Add and List Notes

import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.notes.Note;
import java.io.IOException;
import java.util.List;

public class NotesExample {
    public static void main(String[] args) throws IOException, GitAPIException {
        try (Repository repository = openRepository()) {
            try (Git git = new Git(repository)) {
                // Get latest commit
                var commit = git.log()
                    .setMaxCount(1)
                    .call()
                    .iterator()
                    .next();

                // Add note to commit
                git.notesAdd()
                    .setObjectId(commit)
                    .setMessage("Important note about this commit")
                    .call();

                System.out.println("Added note to commit: " + commit.getName());

                // List notes
                List<Note> notes = git.notesList()
                    .call();

                System.out.println("Notes:");
                for (Note note : notes) {
                    System.out.println("  Commit: " + note.getName() +
                                     ", Note: " + note.getData());
                }
            }
        }
    }

    private static Repository openRepository() throws IOException {
        // Implementation to open repository
        return null;
    }
}

Archive

Create Archive

import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.ArchiveCommand;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.lib.Repository;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;

public class CreateArchiveExample {
    public static void main(String[] args) throws IOException, GitAPIException {
        try (Repository repository = openRepository()) {
            try (Git git = new Git(repository)) {
                // Create tar archive
                File archiveFile = new File("/tmp/repo-archive.tar");
                try (FileOutputStream out = new FileOutputStream(archiveFile)) {
                    git.archive()
                        .setTree(repository.resolve("HEAD"))
                        .setFormat("tar")
                        .setOutputStream(out)
                        .call();
                }

                System.out.println("Archive created: " + archiveFile.getAbsolutePath());
            }
        }
    }

    private static Repository openRepository() throws IOException {
        // Implementation to open repository
        return null;
    }
}

Ant Tasks

JGit provides Ant tasks in the org.eclipse.jgit.ant bundle for common operations in build scripts.

Setup in Ant Build File

<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>

git-clone Task

Clone a repository during build.

<git-clone
    uri="http://egit.eclipse.org/jgit.git"
    dest="cloned-repo"
    bare="false"
    branch="main"/>

Attributes:

  • uri (required): URI to clone from
  • dest (optional): Destination directory (default: based on URI)
  • bare (optional): Create bare repository (true/false/yes/no, default: false)
  • branch (optional): Initial branch to checkout (default: HEAD)

git-init Task

Initialize a new repository.

<git-init
    dest="new-repo"
    bare="false"/>

Attributes:

  • dest (optional): Path where repository is initialized (default: $GIT_DIR or current directory)
  • bare (optional): Create bare repository (true/false/yes/no, default: false)

git-checkout Task

Checkout a branch during build.

<git-checkout
    src="path/to/repo"
    branch="origin/experimental"
    createbranch="true"
    force="false"/>

Attributes:

  • src (required): Path to git repository
  • branch (required): Branch to checkout
  • createbranch (optional): Create branch if it doesn't exist (true/false/yes/no, default: false)
  • force (optional): Force checkout even if branch exists (true/false/yes/no, default: false)

git-add Task

Add files to index (TODO in reference documentation).

<!-- Example when available -->
<git-add
    src="path/to/repo"
    file="file/to/add.txt"/>

Next Steps

Explore more advanced porcelain commands or dive into:

docs

porcelain

index.md

tile.json