Repository navigation
Add directory-tree identity bindings - #14922
Draft
williammartin wants to merge 2 commits into
Draft
williammartin wants to merge 2 commits into
williammartin wants to merge 2 commits into
Conversation
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 965836ef-19ac-4473-ba1f-e326ce0f106b
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 965836ef-19ac-4473-ba1f-e326ce0f106b
2 of 6 tasks
Contributor
There was a problem hiding this comment.
🟡 Changes recommended
Directory identity bindings lack validation for affected checkouts with local SSH overrides and incorrectly allow inherited identity selection in bare repositories.
2 open issues
What changed in this PR
This draft prototype extends repository-family identities with recursive directory bindings. It builds on #14921 so existing and future repositories can inherit an identity without changing the saved active account.
Changes:
- Adds directory binding storage, recursive Git includes, and precedence: repository choices override the deepest matching directory.
- Preserves linked-worktree inheritance from the main checkout and updates command help and cleanup output.
- Adds inheritance, fallback, and cleanup tests plus isolated macOS replay scripts.
| File | Description |
|---|---|
| script/multiaccount-review/fixture.sh | Adds shared, isolated offline replay support. |
| script/multiaccount-review/03-directories.sh | Demonstrates nested directory and external-worktree inheritance. |
| pkg/cmd/root/reset_experiment_test.go | Exercises reset with a directory binding. |
| pkg/cmd/auth/use/worktrees_test.go | Tests main-checkout inheritance and repository overrides. |
| pkg/cmd/auth/use/use.go | Documents directory selection and precedence. |
| pkg/cmd/auth/use/use_test.go | Adds future-descendant inheritance and unset coverage. |
| pkg/cmd/auth/identity/delete.go | Includes directory bindings in cleanup descriptions. |
| pkg/cmd/auth/gitcredential/gist_production_test.go | Uses directory identities in production-config credential tests. |
| pkg/cmd/auth/gitcredential/gist_identity_test.go | Uses a directory identity for canonical-host credential coverage. |
| internal/identity/store.go | Implements directory persistence, recursive includes, and resolution. |
| internal/identity/store_test.go | Tests binding precedence, fallback, and explicit Git-directory selection. |
| internal/identity/hardening_test.go | Tests removal of stale directory bindings without disturbing others. |
Review effort: Balanced
Comment on lines
+599
to
+601
| pattern := strings.TrimSuffix(filepath.ToSlash(binding.Directory), "/") + "/**/.git" | ||
| fmt.Fprintf(&config, "[includeIf %s]\n\tpath = %s\n", gitQuote("gitdir:"+pattern), gitQuote(path)) | ||
| fmt.Fprintf(&config, "[includeIf %s]\n\tpath = %s\n", gitQuote("gitdir:"+pattern+"/worktrees/*"), gitQuote(path)) |
Comment on lines
+741
to
+742
| if under(scopeDir, b.Directory) { | ||
| result.Matches = append(result.Matches, *b) |
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

Description
Follow on from #14921
Developers often organise repositories under work and personal directory trees, so selecting each repository repeats the same decision. This PR adds recursive directory bindings with more specific choices taking precedence.
Layer 3 of an eight-part prototype review stack. This is a way to review the design and implementation in smaller pieces, not a proposal to merge the current stack as-is.
How did you test this change?
I inspected the actual directory binding file, checked selection inside the tree, and exercised nested and repository overrides. I also checked that an external worktree inherits from the main checkout rather than its visible directory.
A directory binding generates recursive gitdir rules
multiaccount-layer-3-01-Wiring---Layer-3---Directory-binding-file.mp4
A work-folder choice reaches existing and future repositories without changing the default account
multiaccount-layer-3-02-A-work-folder-choice-reaches-existing-and-future-repositories-without-changing-the-default-account.mp4
An external worktree inherits from the main checkout location, not its own folder
multiaccount-layer-3-03-An-external-worktree-inherits-from-the-main-checkout-location-not-its-own-folder.mp4
The deepest directory wins; a repository choice wins over directories; removing it restores the deeper fallback
multiaccount-layer-3-04-The-deepest-directory-wins-a-repository-choice-wins-over-directories-removing-it-restores-the-deeper-fallback.mp4
Key points
The managed file stores the directory scope and uses recursive
includeIfconditions for.gitand.git/worktrees/*. An explicit repository binding still wins, followed by the deepest matching directory.The main repository location determines directory inheritance for linked worktrees. Moving a worktree outside the tree does not give it a different account.
Notes for reviewers
Compare the generated directory patterns with the repository-specific patterns in the previous layer. Removing a more specific choice should expose the remaining fallback rather than alter the saved active account.
The recordings use the product code at this layer, not a later stack endpoint. The included offline replay scripts are supplementary and do not reproduce the live-account recordings.
Offline replay on macOS
Build this layer, then run its synthetic scenario with an absolute executable path. This is a replay instruction, not a claim that the command below was used to make the videos.
Authorship and follow-up
Who wrote this:
Who answers review comments:
Acceptance Criteria
Prototype behaviour under review:
Given an identity is bound to a directory tree.
When I use an existing or newly created repository beneath that tree.
Then it inherits that identity unless a more specific binding applies.
DO NOT MERGE