Repository navigation
Keep an Inherited GIT_DIR From Rerooting the Prose Gate's Subdirectory Git Reads - #3831
Conversation
…y Git Reads A hook in a linked worktree inherits GIT_DIR, under which git takes the directory a command starts in as the work tree's top level. The scanned-tree reads (tracked and untracked paths, the shallow check, the diff, and the dead-path history lookup) now drop the location variables as repo_root does. They keep GIT_INDEX_FILE, since `git commit -a` and `git commit <paths>` hand the hook the index that commit records rather than the checkout's own. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…Does Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
A recorded local strict-review pass covers head |
|
Important
This repository does not receive automatic reviews because it has fewer than 10 stars.
|
There was a problem hiding this comment.
🟢 Approval recommended
No active issues remain, and the reviewed changes stop an inherited GIT_DIR from altering the scanned-tree git reads while keeping GIT_INDEX_FILE, which commit hooks rely on.
No open issues 🎉
What changed in this PR
The prose gate runs git reads against a directory it is scanning. When a hook in a linked worktree runs it, git passes in GIT_DIR. Under that variable, git treats the directory a command starts in as the top of the work tree, so a subdirectory scan could ignore the real top-level ignore rules. This PR gives those reads their own environment that drops the location variables. It keeps GIT_INDEX_FILE, because a commit hands its hook that index, and the commit records it.
Changes:
- Adds
tree_env(), which drops the location variables but keepsGIT_INDEX_FILE, and uses it for the five reads of the scanned tree. - Adds three tests: one for a subdirectory under
GIT_DIR, one that checks each of the five reads against a different shallow repository, and one that runs a realgit commit <paths>with a pre-commit hook.
| File | Description |
|---|---|
| tests/test_prose_lint.py | Adds three regression tests covering the subdirectory case, the five scanned-tree reads, and the commit index handed to a hook. |
| .github/actions/prose-gate/prose_lint.py | Adds tree_env() and applies it to the scanned-tree git reads, so an inherited GIT_DIR no longer changes their answers. |
Review effort: Lite
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## develop #3831 +/- ##
===========================================
+ Coverage 81.60% 82.91% +1.30%
===========================================
Files 26 29 +3
Lines 9070 9750 +680
===========================================
+ Hits 7402 8084 +682
+ Misses 1668 1666 -2
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
…rge on a Running Hosted Review, and Gate Skill Description Length (#3843) Promotes the changes merged into `develop` since promotion #3797 to `main`, the end of an away-mode backlog burndown. - [#3803](#3803) exempts the Roslyn embedded-language marker (`// lang=json`, `language=`) from the prose gate's comment rules as a tool directive. - [#3807](#3807) has `local_review.py record` take `--report`, the file the reviewer wrote, bind the pass to its sha256, and derive the finding count from it. `status` gains `reportPath`. - [#3809](#3809) holds `pr_review.py merge` while a hosted review is still running on the head, and routes a declined Qodo finding to a dismiss request. - [#3811](#3811) dates an anchored `intentRef` by the section its anchor names, and lets a `driftNote` acknowledge a verified intent advisory. - [#3816](#3816) moves the null GraphQL node check into the shared `gh_graphql` transport as `NullNodeError`. - [#3818](#3818) explains the workspace-edit default in `GOVERNANCE.md` and names the aggregator's expression form. - [#3822](#3822) moves the abandon discard to the `backlog-burndown` orchestrator, aligns the abandoned-branch delete, and holds a grown agent-safety set. - [#3823](#3823) scopes the Husky prose gate to staged paths and adds `--skip-generated` so a named file inside a generated tree is skipped. - [#3828](#3828) reads Copilot's `Open findings:` label, drops the duplicate `null_node`, and matches `scripts/README.md` to the Merge Gate. - [#3829](#3829) bumps the two stale hub caller snippet pins and documents the fallback's mixed-pair refusal. - [#3831](#3831) keeps an inherited `GIT_DIR` from rerooting the prose gate's subdirectory git reads. - [#3832](#3832) gives `backlog-burndown` a disposition for a worker's standalone clone and keeps the agent-safety hold past a park. - [#3835](#3835) makes `carry.py check-sections` refuse what `apply-sections` would, and name an open fence. - [#3836](#3836) pins the reusable-workflow stubs by placeholder and ticks the PlexCleaner gates item. - [#3838](#3838) has the `runtime-secrets` audit dimension detect a bare `secrets/` directory from the tracked files that name it. - [#3839](#3839) gates skill descriptions at the 1024-character limit and trims every one over it. - [#3846](#3846) fixes an adjacent doc, an in-file pre-existing defect, and an edge case on new code in the open pull request instead of filing an issue for each, and keeps filing for code that runs elsewhere. - [#3847](#3847) refuses skill frontmatter that parses to a list or a scalar, so the description length gate cannot be bypassed. Fixes #3770 Fixes #3699 Fixes #3705 Fixes #3789 Fixes #1819 Fixes #727 Fixes #3710 Fixes #3706 Fixes #3623 Fixes #3687 Fixes #3617 Fixes #3757 Fixes #3790 Fixes #3786 Fixes #3785 Fixes #3772 Fixes #1657 Fixes #3443 Fixes #3824 Fixes #3817 Fixes #3805 Fixes #1666 Fixes #3700 Fixes #3821 Fixes #3771 Fixes #3794 Fixes #3825 Fixes #3690 Fixes #1472 Fixes #3813 Fixes #3719 Fixes #1592 Fixes #3845 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Summary
A hook in a linked worktree inherits
GIT_DIR. UnderGIT_DIRwith noGIT_WORK_TREE, git takes the directory a command starts in as the work tree's top level. So a run naming a subdirectory, such asprose_lint.py sub, readgit -C sub ls-filesas thoughsub/were the root, and the top level's ignores lapsed.tree_env(). These aretracked_paths,untracked_paths,shallow_checkout,git_bytes, and the dead-path rule'sonce_tracked.tree_env()drops the location variables asgit_env()does forrepo_rootand provenance.once_trackedreads the same tree through the samegit -C, so it is the same class and moves with the rest.tree_env()keepsGIT_INDEX_FILE. Measured on git 2.47,git commit -ahands the hookindex.lock, andgit commit <paths>hands itnext-index-*.lock. That index is what the commit records, and the checkout's own index is not, so dropping it would make the gate read the wrong one. A plain commit in the main worktree hands the hook a relative.git/indexwithGIT_DIRunset, which was already inherited and is unchanged.Tests
The tests are built from the issue's constructed repro, with temporary repositories and synthetic content only.
test_a_hook_in_a_linked_worktree_names_a_subdirectory: underGIT_DIR, an ignored file in the named subdirectory stays unread.test_each_scanned_tree_read_answers_for_the_directory_it_names: withGIT_DIRnaming a different, shallow repository, each of the five reads answers for the directory it names. Reverting any one call site alone fails this case, checked site by site.test_a_commit_naming_paths_keeps_the_index_it_hands_its_hook: a realgit commit <paths>in a linked worktree runs a pre-commit hook that lists a subdirectory. The listing holds the file the commit's index still tracks and the checkout's index dropped. It fails both when the whole environment is inherited and whenGIT_INDEX_FILEis dropped withGIT_DIR. It is skipped off POSIX, as the textconv-driver case is, since the hook is written for a POSIX shell.prose_lint.pygrows by 14 lines and no ceiling moves.Local review
Two recorded
local-strict-reviewpasses. The first raised oneintroducedfinding, the real-hook case running unguarded on the Windows leg, which was fixed in f47ab60. The second raised none.Pre-existing findings, not filed
.github/actions/prose-gate/prose_lint.pyGIT_LOCATION, consolidation: its list differs fromspec/git_env.py'sGIT_LOCATION_VARS, for example inGIT_SHALLOW_FILEandGIT_GRAFT_FILE. No hook sets the missing ones, and the gate cannot importspec/.Closes on promotion: #3821
🤖 Generated with Claude Code