Eclipse JGit Documentation
repository·master·Indexed 19 days ago
https://github.com/eclipse-jgit/jgitA pure Java implementation of the Git version control system that allows Java applications to perform operations like cloning, fetching, and pushing without a native Git installation. Documentation covers core library usage, module overviews (including LFS, HTTP, and CLI support), and detailed SSH configuration for Apache MINA sshd and JSch, including SSH agent transports for Windows, Linux, OS X, and BSD, as well as PKCS#11 HSM support.
What's inside Eclipse JGit
- Eclipse JGit is a pure Java implementation of the Git version control system. It allows developers to read and write Git repositories and operate on working directories directly within Java applications without requiring a native Git installation.
Use JGit SSH support via JSch
masterThis bundle provides an implementation of git transport over SSH using the JSch library.
Warning: This bundle is deprecated and essentially unmaintained. The JGit project may remove it at any time. For officially supported SSH transport, use the
org.eclipse.jgit.ssh.apachebundle, which is built upon Apache MINA sshd.What is the reftable format?
masterThe
reftableformat is a portable binary file format designed for efficient Git reference storage. It is intended as a high-performance alternative to the traditionalpacked-refsformat and loose reference files.Key characteristics include:
- Efficient Lookups: Supports near constant-time lookup for single references, SHA-1 verification, and namespace scans (e.g.,
refs/tags/). - Optimized Storage: Uses variable-sized blocks with prefix compression to reduce disk space. It also allows combining reflog storage with ref storage for small transactions.
- Scalability: Designed to handle repositories with massive numbers of references (e.g., hundreds of thousands) without the linear scan penalties of
packed-refsor the inode exhaustion issues of loose references. - Atomic Operations: Supports atomic pushes with $O(\text{size of update})$ complexity, avoiding the need to rewrite the entire file for small changes.
- Efficient Lookups: Supports near constant-time lookup for single references, SHA-1 verification, and namespace scans (e.g.,
SSH Agent support and limitations
masterJGit supports communication with SSH agents using the OpenSSH protocol (the newer SSH2 protocol). It does not support the older SSH1 protocol.
Agent Discovery
JGit discovers agent connectors via the
ServiceLoadermechanism using the SPIorg.eclipse.jgit.transport.sshd.agent.ConnectorFactory. If no implementation is found, JGit will not attempt to use an SSH agent.SSH Config for Agents
When using
~/.ssh/config, the following properties are supported:AddKeysToAgent: Can beno,yes,ask,confirm, or include key lifetimes. Note that on Windows, Pageant and Win32-OpenSSH do not supportconfirmor lifetime constraints.IdentityAgent: Specifies which agent to use, ornoneto disable agent use.IdentitiesOnly: If set toyes, only keys listed in anIdentityFile(and having a corresponding*.pubfile) are considered. This prevents JGit from trying default key names like~/.ssh/id_rsa.
Configure Reftable block size and alignment
masterWhen implementing or reading reftables, consider the following regarding block management:
- Block Size: Determined by the writer. It must be larger than the longest reference name or log entry. Recommended sizes are powers of two (e.g., 4k, 8k) for filesystem friendliness. Larger sizes (64k) improve compression but increase access costs. The maximum allowed block size is
16777215bytes (15.99 MiB). - Alignment: Writers can align blocks at multiples of the block size using
padding(NUL bytes).- If aligned: The
block_sizefield in the header must specify the alignment. - If unaligned: The header must set
block_size = 0and omitpadding. Unaligned files with multiple ref blocks must include aref_indexto support fast lookups.
- If aligned: The
- First Block Exception: The first ref block shares the same block as the file header and is 24 bytes smaller than subsequent blocks.
- Block Size: Determined by the writer. It must be larger than the longest reference name or log entry. Recommended sizes are powers of two (e.g., 4k, 8k) for filesystem friendliness. Larger sizes (64k) improve compression but increase access costs. The maximum allowed block size is
Understand the Reftable file structure
masterA reftable file is a structured binary format used for storing Git references and logs. The high-level structure consists of a header, followed by various data blocks (references, objects, logs) and their corresponding indices, ending with a footer.
Standard Reftable Structure:
first_block(contains the file header and the first reference block)ref_block*(zero or more reference blocks)ref_index*(zero or more reference index blocks)obj_block*(optional object blocks)obj_index*(optional object index blocks)log_block*(zero or more log blocks)log_index*(zero or more log index blocks)footer(contains metadata and pointers to index positions)
Log-only Reftable Structure: If the file only contains logs, it omits reference and object sections:
first_block(contains the file header)log_block*log_index*footer
In log-only files, the first log block immediately follows the header without padding.
first_block { header first_ref_block } ref_block* ref_index* obj_block* obj_index* log_block* log_index* footerUnderstand Log Block and Log Record formats
masterLog blocks (
block_type = 'g') are always unaligned and variable in size. They usezlibdeflate compression.Log Block Structure:
uint24( block_len ): The inflated size (including the 4-byte header). Use this to preallocate the inflation buffer.zlib_deflatepayload containing:log_record+uint24( restart_offset )+uint16( restart_count )
Log Record Format: Log records use a key structured as:
ref_name '\0' reverse_int64( update_index ). Thereverse_int64ensures that higherupdate_indexvalues (more recent) sort first.Log Record Fields:
log_type:0x0(deletion) or0x1(standard git reflog data).- For
log_type = 0x1, thelog_dataincludes:old_id(20-byte SHA-1)new_id(20-byte SHA-1)name(committer name)email(committer email)time_seconds(seconds since epoch)tz_offset(signed minutes from GMT)message(reflog message)
Explore JGit Modules
masterJGit is organized into several modules depending on your requirements:
org.eclipse.jgit: The core pure Java library for reading/writing repositories and working directories. It has no additional support library dependencies.org.eclipse.jgit.ant: Provides Ant tasks based on JGit.org.eclipse.jgit.archive: Supports exporting to various archive formats (e.g., zip).org.eclipse.jgit.http.apache: Provides Apache HttpClient support.org.eclipse.jgit.http.server: A server implementation for the smart and dumb Git HTTP protocol.org.eclipse.jgit.lfs: Support for Git Large File Storage (LFS).org.eclipse.jgit.lfs.server: Basic LFS server support.org.eclipse.jgit.pgm: A command-line interface (CLI) implementing Git commands using JGit.org.eclipse.jgit.ssh.apache: SSH protocol client support based on Apache Mina sshd.org.eclipse.jgit.ssh.apache.agent: Optional SSH agent support for the Apache SSH client.org.eclipse.jgit.ui: A simple UI for displaying the git log.
Understand JGit configuration option symbols
masterJGit configuration options are categorized into two types:
- Native Git options (✅): Options that are defined by and compatible with native Git.
- JGit custom options (⚝): Options that are specific to JGit and are not supported by native Git.
For native Git options, refer to the official git config documentation.
How JGit discovers SSH implementations
masterJGit uses the
java.util.ServiceLoaderto find implementations of theorg.eclipse.jgit.transport.ssh.SshSessionFactoryinterface.- Automatic Discovery: If the service declaration is on the Classpath of the
org.eclipse.jgitbundle, JGit will automatically pick it up. - Selection Logic: JGit simply uses the first
SshSessionFactoryprovided by theServiceLoader. - OSGi Environments: In OSGi, you may need a service loader bridge or an OSGi fragment for the
org.eclipse.jgitbundle to ensure the service declaration is visible on its Classpath. - Manual Override: If discovery fails, you can manually set the factory using
SshSessionFactory.setInstance()(globally) or via aTransportConfigCallback(per command).
- Automatic Discovery: If the service declaration is on the Classpath of the
Implement binary search within a block using restart_offsets
masterTo avoid linear scans of entire blocks, reftables use a
restart_offsettable located at the end of blocks (ref, obj, or index blocks).How it works:
- A block contains a
restart_count(uint16) and a list ofrestart_offsetvalues (uint24). - Each
restart_offsetis relative to the start of the block and points to the first byte of aref_recordwhose name has not been prefix compressed (i.e., itsprefix_lengthis 0). - Search Process:
- Binary search the
restart_offsetlist to find the two restart points between which the target key resides. - Perform a linear scan starting from the identified restart point.
- Terminate the scan once a record is found that sorts after the target key.
- Binary search the
Writer Recommendation: Use a restart interval of 16 for small blocks (4k/8k) and 64 for larger blocks (64k).
- A block contains a
Understand the reftable repository layout
masterReftable files are stored in the
$GIT_DIR/reftable/directory. The repository uses a stack of files to manage references and logs.File Types
.logfiles: Contain only log entries..reffiles: Contain either only references or a mix of references and logs.
The Stack (
tables.list)The file
$GIT_DIR/reftable/tables.listmaintains the order of the stack, from oldest (base) to newest (most recent).Important for Readers: To get the current state of references, readers must read
tables.listand search through the files in reverse order (examining the last file in the list first).# Example of the stack order $ cat .git/reftable/tables.list 00000001-00000001.log 00000002-00000002.ref 00000003-00000003.ref