Skip to content

stacked_table: skip non-segment file names in heads/ - #10062

Open
petejm wants to merge 1 commit into
jj-vcs:mainfrom
petejm:stacked-table-skip-foreign-head-files
Open

stacked_table: skip non-segment file names in heads/#10062
petejm wants to merge 1 commit into
jj-vcs:mainfrom
petejm:stacked-table-skip-foreign-head-files

Conversation

@petejm

@petejm petejm commented Aug 26, 2026

Copy link
Copy Markdown

Fixes #9775.

get_head_tables loaded every directory entry of store/extra/heads as a table segment, so a foreign file (an AppleDouble ._* file left by tar, .DS_Store, anything) made every command that reads commit metadata fail until the file was removed by hand, and a non-UTF8 file name panicked. Entries whose names are not exactly 128 ASCII hex characters are now skipped with a warning, combining the two neighboring idioms: TableStore::gc already filters by segment-name length and SimpleOpHeadsStore::get_op_heads already validates with hex_util::decode_hex. Foreign files are left in place. Head markers are written only from hex_util::encode_hex output, so no legitimate marker can be affected.

If every entry in heads/ turns out to be invalid, get_head_tables now returns the new TableStoreError::NoValidHeads instead of silently manufacturing a fresh empty table, which would otherwise mask lost head metadata. A genuinely empty heads/ (no entries at all) keeps its existing behavior.

Checklist

If applicable:

  • I have updated CHANGELOG.md
  • I have added/updated tests to cover my changes
  • I fully understand the code that I am submitting (what it does,
    how it works, how it's organized), including any code drafted by an LLM.
  • For any prose generated by an LLM, I have proof-read and copy-edited with
    an eye towards deleting anything that is irrelevant, clarifying anything
    that is confusing, and adding details that are relevant. This includes,
    for example, commit descriptions, PR descriptions, and code comments.

@petejm
petejm requested a review from a team as a code owner August 26, 2026 00:59
Foreign files like AppleDouble `._*` (which appear when a macOS-created
archive is extracted on another system) or `.DS_Store` landing in
store/extra/heads made every metadata read fail until removed by hand;
a non-UTF8 name panicked outright. gc() already tolerates foreign
names in the table directory, and SimpleOpHeadsStore::get_op_heads
tolerates non-hex UTF-8 names in its own heads directory (though it
still errors on non-UTF8 ones). Apply the same idea to
get_head_tables(): ignore any entry whose name isn't exactly
SEGMENT_FILE_NAME_LENGTH ASCII hex characters, logging each skip at
warn level (visible under --debug/JJ_LOG), and never touch the
foreign file itself.

If every entry in heads/ turns out to be invalid, return the new
TableStoreError::NoValidHeads instead of silently manufacturing a
fresh empty table, which would otherwise mask lost head metadata. A
genuinely empty heads/ (no entries at all) keeps its existing
behavior.

Fixes jj-vcs#9775

Assisted-by: Claude:claude-fable-5
@petejm
petejm force-pushed the stacked-table-skip-foreign-head-files branch from 5839942 to bd270bb Compare August 26, 2026 01:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

jj fragility in relation to AppleDouble files

1 participant