Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
512ce70
docs: add design spec for directory-based profile assignment
aanogueira May 4, 2026
608b3a8
docs: add implementation plan for directory-based profile assignment
aanogueira May 4, 2026
8418095
feat(config): add Directories field to Profile
aanogueira May 4, 2026
a9b26b0
feat(config): add NormalizeDir for includeIf path handling
aanogueira May 4, 2026
d044cb5
feat(config): add LookupDir and AssignmentMap
aanogueira May 4, 2026
a3fdbd2
feat(config): add AssignDir/UnassignDir with conflict detection
aanogueira May 4, 2026
085dd7b
feat(config): add ProfilesDir to Paths
aanogueira May 4, 2026
bbfb166
feat(git): add atomic WriteProfileFile
aanogueira May 4, 2026
55781c3
fix(git): clarify WriteProfileFile/atomicWrite docs, cover write-fail…
aanogueira May 4, 2026
a7fd222
feat(git): add WriteRootConfig manifest writer
aanogueira May 4, 2026
a69849c
feat(git): add Regenerate orchestrator
aanogueira May 4, 2026
7d8cf17
docs(git): document Regenerate's non-transactional failure semantics
aanogueira May 4, 2026
c028bc7
refactor(switch): write via Regenerate, emit manifest
aanogueira May 4, 2026
06e6d81
fix(git): preserve pre-migration backup; cover flatten helpers
aanogueira May 4, 2026
760e21e
feat(remove): regenerate manifest, prompt mentions assigned dirs
aanogueira May 4, 2026
a542d25
feat(list): show assigned-directory count column
aanogueira May 4, 2026
f8f7dae
test(cmd): serialize captureStdout, document non-parallel constraint
aanogueira May 4, 2026
0d43296
feat(show): list assigned directories
aanogueira May 4, 2026
5ef99f6
test(cmd): defer captureStdout restoration to survive panics
aanogueira May 4, 2026
b698c2c
feat(current): show effective profile in cwd
aanogueira May 4, 2026
3d54e16
fix(current): require file: origin and resolve symlinks
aanogueira May 4, 2026
f18b3ba
feat(add): optional directory-assignment prompt
aanogueira May 4, 2026
92f8cb6
feat(dir): add 'dir add/remove/list' subcommands
aanogueira May 4, 2026
c88db6f
fix(config): persist Current; remove brittle --global probe
aanogueira May 5, 2026
d0a3228
test: end-to-end directory-based profile lifecycle
aanogueira May 5, 2026
2b7cf0b
docs: document dir commands and new file layout
aanogueira May 5, 2026
b21553e
refactor(git): remove dead WriteConfig and stale doc reference
aanogueira May 5, 2026
c11f5da
fix(git): normalize manifest paths to forward slashes for Windows
aanogueira May 5, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -182,9 +182,32 @@ git-context remove university
| `git-context current` | Show active profile |
| `git-context show <name>` | Show profile details |
| `git-context remove <name>` | Delete a profile |
| `git-context dir add <path> <profile>` | Assign a directory to a profile (auto-applied via includeIf) |
| `git-context dir remove <path>` | Remove a directory assignment |
| `git-context dir list` | List all directory assignments |
| `git-context --help` | Show help |
| `git-context --version` | Show version |

### Directory-Based Profiles

Assign filesystem paths to profiles so git applies the right identity automatically when you're inside them — no need to remember to `switch`.

```bash
# Make 'work' the default profile (used everywhere unless overridden)
git-context switch work

# Assign specific directories to other profiles
git-context dir add ~/projects/personal personal
git-context dir add ~/Mollie work

# See all assignments
git-context dir list
```

Under the hood git-context generates one gitconfig file per profile under `~/.config/git-context/profiles/` and rewrites `~/.gitconfig` as a thin manifest of `[include]` and `[includeIf "gitdir:..."]` blocks that git-context regenerates on every mutating command. The YAML at `~/.config/git-context/config.yaml` is always the source of truth.

> Note: git-context owns `~/.gitconfig` end-to-end — don't run `git config --global` directly. Edit the YAML or use the CLI instead.

## Configuration

The configuration is stored in YAML format at `~/.config/git-context/config.yaml`.
Expand Down
34 changes: 34 additions & 0 deletions cmd/add.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"fmt"

"github.com/aanogueira/git-context/internal/config"
"github.com/aanogueira/git-context/internal/git"
"github.com/aanogueira/git-context/internal/ui"
"github.com/cockroachdb/errors"
"github.com/spf13/cobra"
Expand Down Expand Up @@ -77,6 +78,30 @@ func runAdd(cmd *cobra.Command, args []string) error {
profile.URL = promptURLRewrites()
}

addDirs, _ := ui.PromptConfirm("Assign directories to this profile?")
if addDirs {
for {
path, err := ui.PromptText("Directory path (leave empty to stop)", "")
if err != nil || path == "" {
break
}

normalized, err := config.NormalizeDir(path)
if err != nil {
ui.PrintWarning(fmt.Sprintf("Skipping %q: %v", path, err))

continue
}

profile.Directories = append(profile.Directories, normalized)

more, _ := ui.PromptConfirm("Add another directory?")
if !more {
break
}
}
}

// Add the profile
if err := cfg.AddProfile(profileName, profile); err != nil {
ui.PrintError(fmt.Sprintf("Failed to add profile: %v", err))
Expand All @@ -91,6 +116,15 @@ func runAdd(cmd *cobra.Command, args []string) error {
return errors.Wrap(err, "failed to save config")
}

if len(profile.Directories) > 0 || cfg.Current != "" {
g := git.NewGit(paths.GitConfigFile)
if err := g.Regenerate(cfg, paths.ProfilesDir); err != nil {
ui.PrintError(fmt.Sprintf("Failed to regenerate git config: %v", err))

return errors.Wrap(err, "failed to regenerate git config")
}
}

ui.PrintSuccess(fmt.Sprintf("Profile '%s' created successfully", profileName))

return nil
Expand Down
Loading
Loading