Version
7.7
Operating System
Linux/Unix
Bug description
Bug description
A valid reftable written by C Git can have a highest index level that
spans multiple sibling index blocks. ReftableReader starts at the index
position recorded in the footer, reads the first index block, and returns
no match when the requested key sorts after that block. It does not
continue to the next index block at the same level.
This makes JGit internally inconsistent: a full ref scan returns a ref,
while point-lookup APIs cannot find that same ref. Native Git resolves the
ref successfully.
I attached jgit-reftable-multi-root-reproducer.zip, which contains the
complete read-only probe source and an example broken repository:
JGitReftableReadProbe.java compares JGit full enumeration, JGit
exactRef, findRef, and resolve, and native Git point lookup.
broken-repository.git is a synthetic bare repository written by C Git
2.54 using extensions.refStorage=reftable.
- The repository has 10,000 generic refs pointing to one empty synthetic
commit. It contains no production source or ref names.
Archive SHA-256:
d6e91da54a8456d6b787ad49932ecc88a441c1987a84b639aef75fe0c9e475a8
Run the complete probe with a JGit runtime classpath:
java --class-path '/path/to/jgit.jar:/path/to/dependencies/*' \
JGitReftableReadProbe.java \
broken-repository.git \
refs/heads/archive/7fff4ea22b8a03452de95dca17404a632d111489
jgit-reftable-multi-root-reproducer.zip
Actual behavior
Actual behavior
With unmodified JGit 7.7:
refDatabase=org.eclipse.jgit.internal.storage.file.FileReftableDatabase
extensions.refStorage=reftable
jgitFullScan.count=10001
jgitFullScanVsExactRef.mismatchCount=4349
ref=refs/heads/archive/7fff4ea22b8a03452de95dca17404a632d111489 enumerated=1485913eca8d3370fc05352a45977a99720acb1c exactRef=null findRef=null resolve=null nativeExit=0 native=1485913eca8d3370fc05352a45977a99720acb1c
BUG_REPRODUCED=true
The failure is deterministic for every ref routed through the second
root-index block.
Expected behavior
Expected behavior
Every ref returned by the full scan should also be found by exactRef,
findRef, and resolve. JGit point lookup should agree with native Git.
With the proposed fix:
jgitFullScan.count=10001
jgitFullScanVsExactRef.mismatchCount=0
ref=refs/heads/archive/7fff4ea22b8a03452de95dca17404a632d111489 enumerated=1485913eca8d3370fc05352a45977a99720acb1c exactRef=1485913eca8d3370fc05352a45977a99720acb1c findRef=1485913eca8d3370fc05352a45977a99720acb1c resolve=1485913eca8d3370fc05352a45977a99720acb1c nativeExit=0 native=1485913eca8d3370fc05352a45977a99720acb1c
BUG_REPRODUCED=false
Relevant log output
Other information
Other information
The footer's index position is the start of the highest index level; it
is not a guarantee that the level consists of only one block. The current
lookup treats the first block as the entire root level.
The proposed fix walks sibling index blocks at the highest level until it
finds the block whose key range contains the requested key, or reaches
the next reftable section. It handles adjacent unaligned blocks,
block-aligned NUL padding, and an oversized root block. The same logic is
used for ref, object, and log indexes.
The accompanying tests cover aligned and unaligned multi-block ref root
indexes, object and log indexes, missing keys, and an oversized
single-level root index.
Version
7.7
Operating System
Linux/Unix
Bug description
Bug description
A valid reftable written by C Git can have a highest index level that
spans multiple sibling index blocks.
ReftableReaderstarts at the indexposition recorded in the footer, reads the first index block, and returns
no match when the requested key sorts after that block. It does not
continue to the next index block at the same level.
This makes JGit internally inconsistent: a full ref scan returns a ref,
while point-lookup APIs cannot find that same ref. Native Git resolves the
ref successfully.
I attached
jgit-reftable-multi-root-reproducer.zip, which contains thecomplete read-only probe source and an example broken repository:
JGitReftableReadProbe.javacompares JGit full enumeration, JGitexactRef,findRef, andresolve, and native Git point lookup.broken-repository.gitis a synthetic bare repository written by C Git2.54 using
extensions.refStorage=reftable.commit. It contains no production source or ref names.
Archive SHA-256:
Run the complete probe with a JGit runtime classpath:
java --class-path '/path/to/jgit.jar:/path/to/dependencies/*' \ JGitReftableReadProbe.java \ broken-repository.git \ refs/heads/archive/7fff4ea22b8a03452de95dca17404a632d111489jgit-reftable-multi-root-reproducer.zip
Actual behavior
Actual behavior
With unmodified JGit 7.7:
The failure is deterministic for every ref routed through the second
root-index block.
Expected behavior
Expected behavior
Every ref returned by the full scan should also be found by
exactRef,findRef, andresolve. JGit point lookup should agree with native Git.With the proposed fix:
Relevant log output
Other information
Other information
The footer's index position is the start of the highest index level; it
is not a guarantee that the level consists of only one block. The current
lookup treats the first block as the entire root level.
The proposed fix walks sibling index blocks at the highest level until it
finds the block whose key range contains the requested key, or reaches
the next reftable section. It handles adjacent unaligned blocks,
block-aligned NUL padding, and an oversized root block. The same logic is
used for ref, object, and log indexes.
The accompanying tests cover aligned and unaligned multi-block ref root
indexes, object and log indexes, missing keys, and an oversized
single-level root index.