feat: directory-based profile assignment via includeIf#17
Merged
aanogueira merged 28 commits intomainfrom May 5, 2026
Merged
Conversation
Captures the includeIf-based approach: per-profile gitconfig files materialized to ~/.config/git-context/profiles/, with ~/.gitconfig becoming a thin manifest of [include] + [includeIf gitdir:...] blocks that git-context regenerates on every mutating command. Signed-off-by: Andre Nogueira <andre.nogueira@mollie.com>
17 TDD-structured tasks covering config schema changes, atomic file writers, the new `dir` subcommand, and updates to existing commands. End-to-end test verifies git resolves the right user.email inside and outside assigned directories. Signed-off-by: Andre Nogueira <aanogueira@protonmail.com>
Signed-off-by: Andre Nogueira <aanogueira@protonmail.com>
Signed-off-by: Andre Nogueira <aanogueira@protonmail.com>
Signed-off-by: Andre Nogueira <aanogueira@protonmail.com>
Signed-off-by: Andre Nogueira <aanogueira@protonmail.com>
Signed-off-by: Andre Nogueira <aanogueira@protonmail.com>
Signed-off-by: Andre Nogueira <aanogueira@protonmail.com>
…ure path Signed-off-by: Andre Nogueira <aanogueira@protonmail.com>
Signed-off-by: Andre Nogueira <aanogueira@protonmail.com>
Signed-off-by: Andre Nogueira <aanogueira@protonmail.com>
Signed-off-by: Andre Nogueira <andre.nogueira@mollie.com>
Signed-off-by: Andre Nogueira <andre.nogueira@mollie.com>
Signed-off-by: Andre Nogueira <andre.nogueira@mollie.com>
Signed-off-by: Andre Nogueira <andre.nogueira@mollie.com>
Signed-off-by: Andre Nogueira <andre.nogueira@mollie.com>
Signed-off-by: Andre Nogueira <andre.nogueira@mollie.com>
Signed-off-by: Andre Nogueira <andre.nogueira@mollie.com>
Signed-off-by: Andre Nogueira <andre.nogueira@mollie.com>
Signed-off-by: Andre Nogueira <andre.nogueira@mollie.com>
Signed-off-by: Andre Nogueira <andre.nogueira@mollie.com>
Signed-off-by: Andre Nogueira <andre.nogueira@mollie.com>
Signed-off-by: Andre Nogueira <andre.nogueira@mollie.com>
The previous determineCurrent() probed git config --global user.name to recover Current on each LoadConfig. After the manifest refactor in Task 9, --global doesn't follow [include] directives, so Current would always read as empty and any subsequent Regenerate would drop the default profile from the manifest. Persisting Current in config.yaml removes the side channel and makes the manifest faithfully reflect the configured default. Signed-off-by: Andre Nogueira <aanogueira@protonmail.com>
Signed-off-by: Andre Nogueira <aanogueira@protonmail.com>
Signed-off-by: Andre Nogueira <aanogueira@protonmail.com>
Signed-off-by: Andre Nogueira <aanogueira@protonmail.com>
Codecov Report❌ Patch coverage is 📢 Thoughts on this report? Let us know! |
Git config rejects backslashes in unquoted 'path =' values, causing WriteRootConfig output to fail on Windows CI. Pipe defaultProfilePath, gitdir keys, and includeIf paths through a small toGitPath helper that unconditionally replaces backslashes with forward slashes — filepath.ToSlash is insufficient because it only swaps the OS-specific separator and is a no-op on POSIX, which would leave the regression test (using literal Windows-shaped paths) failing on macOS/Linux. Signed-off-by: Andre Nogueira <aanogueira@protonmail.com>
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.
Summary
Adds directory-based profile assignment using git's native
includeIf "gitdir:..."mechanism, so the right git identity applies automatically based on where you are in the filesystem — no need to remember toswitch.git-context dir add/remove/listsubcommands~/.config/git-context/profiles/<name>.gitconfig~/.gitconfigbecomes a thin manifest:[include]for the default +[includeIf]per assigned directoryswitch,add,remove,dir add/remove) regenerates the manifest fromconfig.yaml(single source of truth)currentnow also reports the effective profile in$PWD, surfacing when anincludeIfis overriding the defaultSpec:
docs/superpowers/specs/2026-05-04-directory-based-profile-assignment-design.mdPlan:
docs/superpowers/plans/2026-05-04-directory-based-profile-assignment.mdTest Plan
internal/config,internal/git,cmd(175 passing)cmd/integration_test.go) drives full lifecycle through realgit config --show-origin user.emailresolution inside vs outside an assigned repogit-context init && git-context add work && git-context switch work && git-context dir add ~/projects/personal personal && git-context current(manual)~/.gitconfigto~/.gitconfig.bak; subsequent switches don't clobber it (header-marker guard in `BackupConfig`)removeManagedManifesthelper deletes only files we own)