You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
grit merge conflict hint says 'run grit commit' but commit refuses until 'grit add' (commit usually stages all) #1014
Kind: ux · Severity: medium · Area: merge / commit
Steps to reproduce
export GIT_AUTHOR_NAME=a GIT_AUTHOR_EMAIL=a@x GIT_COMMITTER_NAME=a GIT_COMMITTER_EMAIL=a@x
mkdir mm && cd mm && git init -q -b main && seq 1 10 > f && git add . && git commit -qm base && git branch o
sed -i '' '3s/./M/' f && git commit -qam m && git checkout -q o && sed -i '' '3s/./O/' f && git commit -qam o && git checkout -q main # (GNU sed: drop the '')
grit merge o # CONFLICT (content): f ... 'fix conflicts and run grit commit'
echo R > f # resolve
grit commit -m merge
grit add f && grit commit -m merge
Expected
The hint grit prints (and grit status: 'resolve conflicts, then grit commit "message"') works, as grit commit documents 'Stage every change and record a new commit'; or the hint tells the user to grit add the resolved files.
Actual
grit commit -m merge exits 1: 'error: cannot commit: unresolved merge conflicts remain - resolve each conflicted path (grit add or grit rm), then try again'. After grit add f, grit commit succeeds with two parents. Conflict output and status hint contradict the commit error. Same as closed #971, still present in 0.5.8. (Abort path grit merge --abort and the resulting merge commit tree/parents verified OK against git.)
Environment
grit 0.5.8 (release installer), macOS 15.7 arm64, system git 2.52.0
Real UX bug, not a docs-only mismatch. After grit merge leaves conflict markers, resolving files in the worktree and running grit commit should succeed per merge/status hints and grit commit’s “stage everything” contract (see commit_after_resolved_merge_without_add_succeeds for #971). Reproduced on current main: with core.ignorecase=true (typical on macOS), stage_for_commit does not collapse unmerged index stages when pathspecs are empty, so commit still hits IndexUnmerged; grit add f works because explicit pathspecs run stage_unmerged_paths_matching_pathspecs. Linux CI passes because ignorecase defaults false and the tracked-scan path handles unmerged paths. Same class as closed #971; incomplete fix for ignorecase repos.
Likely approach: Fix in grit-lib/src/porcelain/add.rs stage_inner (used by stage_for_commit): when the index has unmerged entries and opts.pathspecs is empty, always refresh/collapse resolved unmerged paths—either by calling stage_tracked_modifications_in_index’s unmerged loop (stage_tracked.rs refresh_unmerged_tracked_path) before/after the diff path, or by dropping the !ignorecase guard for that unmerged pass while keeping the ignorecase diff path for ordinary tracked files. Add grit-lib test: stage_for_commit clears unmerged stages on a synthetic conflict with core.ignorecase=true in config; extend grit-cli/tests/commit_unmerged_merge.rs with the issue’s exact repro (seq file f, grit merge) and ignorecase enabled. Optional: content/docs/commands/commit.md already says grit add is required for unmerged paths—update only if product choice is hint-only (not recommended). No format/protocol changes.
Activity
schacon commentedon Oct 13, 2026
Automated triage (confidence 88%)
Real UX bug, not a docs-only mismatch. After grit merge leaves conflict markers, resolving files in the worktree and running grit commit should succeed per merge/status hints and grit commit’s “stage everything” contract (see commit_after_resolved_merge_without_add_succeeds for #971). Reproduced on current main: with core.ignorecase=true (typical on macOS), stage_for_commit does not collapse unmerged index stages when pathspecs are empty, so commit still hits IndexUnmerged; grit add f works because explicit pathspecs run stage_unmerged_paths_matching_pathspecs. Linux CI passes because ignorecase defaults false and the tracked-scan path handles unmerged paths. Same class as closed #971; incomplete fix for ignorecase repos.
Likely approach: Fix in grit-lib/src/porcelain/add.rs stage_inner (used by stage_for_commit): when the index has unmerged entries and opts.pathspecs is empty, always refresh/collapse resolved unmerged paths—either by calling stage_tracked_modifications_in_index’s unmerged loop (stage_tracked.rs refresh_unmerged_tracked_path) before/after the diff path, or by dropping the !ignorecase guard for that unmerged pass while keeping the ignorecase diff path for ordinary tracked files. Add grit-lib test: stage_for_commit clears unmerged stages on a synthetic conflict with core.ignorecase=true in config; extend grit-cli/tests/commit_unmerged_merge.rs with the issue’s exact repro (seq file f, grit merge) and ignorecase enabled. Optional: content/docs/commands/commit.md already says grit add is required for unmerged paths—update only if product choice is hint-only (not recommended). No format/protocol changes.