storage: filesystem, Add support for worktreeConfig extension#1877
Merged
storage: filesystem, Add support for worktreeConfig extension#1877
worktreeConfig extension#1877Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
Adds extensions.worktreeConfig support to the filesystem-backed storage so linked worktrees can read and overlay per-worktree config.worktree onto the common .git/config, aligning behavior with upstream Git worktree configuration.
Changes:
- Overlay
.git/worktrees/<name>/config.worktreeonto the base repo config whenextensions.worktreeConfig=true(filesystem storage only). - Fix
config.Mergebehavior for map fields sonil/empty maps don’t wipe previously-merged entries. - Remove
PlainOpenOptions.EnableDotGitCommonDirand makecommondirdetection unconditional.
Reviewed changes
Copilot reviewed 11 out of 11 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
storage/filesystem/config.go |
Reads config.worktree (when enabled) and merges it into the returned config. |
config/config.go |
Adds Extensions.WorktreeConfig, improves map merge semantics, and marshals/unmarshals the new extension key. |
storage/filesystem/storage.go |
Declares filesystem storage support for worktreeconfig extension. |
storage/filesystem/dotgit/dotgit.go |
Adds helpers to open/create config.worktree. |
repository.go |
Makes commondir detection unconditional; improves nil options handling and not-exist checks. |
options.go |
Removes EnableDotGitCommonDir from PlainOpenOptions. |
repository_extensions.go |
Normalizes v0-valid extension keys to lowercase and documents the requirement. |
config/config_test.go |
Expands merge tests to cover map merge behavior and new extension field. |
x/plumbing/worktree/worktree_test.go |
Adds coverage for reading overlaid config.worktree in linked worktrees. |
worktree_test.go |
Updates linked-worktree open tests to reflect new PlainOpen behavior. |
COMPATIBILITY.md |
Documents worktreeConfig and config --worktree behavior. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
1 task
The extension matching is case insensitive, so keep references to them in lower case format, as that is what is used during the matching process. Signed-off-by: Paulo Gomes <[email protected]>
EnableDotGitCommonDir was an opt-in flag to detect and honor the commondir mechanism used by Git linked worktrees. Requiring callers to explicitly enable this behavior is both surprising and error-prone. Consumers of PlainOpen should not need to know whether a repository is a primary working tree or a linked worktree, nor whether it relies on a shared common directory. This distinction directly impacts core repository semantics, including object resolution and configuration lookup. Leaving it opt-in can lead to subtle and inconsistent behavior. Making commondir detection unconditional, abstracting this complexity away from callers, ensures a consistent and predictable repository handling which aligns with upstream Git. Signed-off-by: Paulo Gomes <[email protected]>
Signed-off-by: Paulo Gomes <[email protected]>
Previous to #1850, go-git was oblivious to Git extensions, which meant that at times it would try to handle repositories where the underlying feature was not fully supported. An example of that being worktreeConfig, meaning that any worktree specific config were being ignored. This commit adds that support to storage/filesystem, resulting into worktree configs being overlayed the local config, providing upstream parity with upstream Git. References: - https://git-scm.com/docs/git-worktree#_configuration_file Signed-off-by: Paulo Gomes <[email protected]>
The internal merge helper had no case for reflect.Map, so map-typed fields (Remotes, Branches, Submodules, URLs) fell through to the default branch which called df.Set(sf), replacing the destination map wholesale. This caused two bugs: * An empty but non-nil source map (as produced by NewConfig) would overwrite a populated destination map, silently discarding all accumulated entries. * A non-empty source map would replace the destination map entirely, dropping any destination keys absent from the source instead of merging them together. Add a reflect.Map case that skips empty source maps unchanged and otherwise copies entries one-by-one, so destination keys not present in the source are preserved and source entries override same-key destination entries. Add table-driven tests covering nil source map, empty source map, disjoint key sets, and same-key override. Signed-off-by: Paulo Gomes <[email protected]>
Signed-off-by: Paulo Gomes <[email protected]>
When the worktreeConfig extension is active and a config.worktree file already exists, only the delta — options whose values are absent from or differ from the base config — is written to config.worktree. The base config is left untouched in that case. This mirrors the behaviour of 'git config --worktree' to some extend, and enable the use case whereby worktree-specific overrides live in config.worktree while shared settings remain in the common config. Signed-off-by: Paulo Gomes <[email protected]>
charithe
added a commit
to charithe/cerbos
that referenced
this pull request
Mar 9, 2026
v5.17.0 includes strict extension checks (go-git/go-git#1861) but it causes problems for `worktreeconfig` because it wasn't added to the supported extension list until go-git/go-git#1877. Until it's released, we need to keep the version back. Signed-off-by: Charith Ellawala <[email protected]>
charithe
added a commit
to cerbos/cerbos
that referenced
this pull request
Mar 9, 2026
v5.17.0 includes strict extension checks (go-git/go-git#1861) but it causes problems for `worktreeconfig` because it wasn't added to the supported extension list until go-git/go-git#1877. Until it's released, we need to keep the version back. Signed-off-by: Charith Ellawala <[email protected]> Signed-off-by: Charith Ellawala <[email protected]>
haines
pushed a commit
to haines/cerbos
that referenced
this pull request
Mar 16, 2026
v5.17.0 includes strict extension checks (go-git/go-git#1861) but it causes problems for `worktreeconfig` because it wasn't added to the supported extension list until go-git/go-git#1877. Until it's released, we need to keep the version back. Signed-off-by: Charith Ellawala <[email protected]>
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.
Previous to #1850, go-git was oblivious to Git extensions, which meant that at times it would try to handle repositories where the underlying feature was not fully supported.
An example of that being worktreeConfig, meaning that any worktree-specific config were being ignored.
This PR adds that support to
storage/filesystem, resulting into worktree configs being overlayed over the local config, providing parity with upstream Git.Other changes were required in order to support this feature properly:
config.Mergebug whereby aniloremptymap resulted in incorrect merge. For example, iflocalconfig had remotes andworktreedidn't, the resulting merge would not contain any remotes.PlainOpenOptions.EnableDotGitCommonDir, makingcommondirdetection unconditional, abstracting this complexity away from callers.SetConfigso that it can distinguish delta changes and save them to the worktree-specific config only.Follow-up from #1850 and #1808.
Relates to #1812.