-
Notifications
You must be signed in to change notification settings - Fork 874
Description
When a branch contains merge commits, the diff view shows all changes introduced by the merged branch rather than just the changes unique to the merge itself (conflict resolutions, manual edits). For example, merging origin/dev into a feature branch shows 65 changed files (+973/-3928) in GitButler, while GitHub shows 24 files for the same PR — because GitHub diffs against the merge-base.
Root cause
CommitDetails::from_commit_id() in crates/but-core/src/diff/commit_details.rs and commit_changes_with_line_stats_by_worktree_dir() in crates/but-core/src/diff/ui.rs both take only the first parent for diffing:
let first_parent_commit_id = commit.parent_ids().map(|id| id.detach()).next();For regular commits this is correct. For merge commits, the first parent is the branch being merged into, so the diff includes everything from the other branch.
Proposed fix
For commits with >1 parent, diff against the merge-base of the parents instead of the first parent. This shows only what the merge introduced (conflict resolutions + manual changes), matching GitHub's behavior. The merge-base pattern already exists in the codebase (but-rebase/src/graph_rebase/cherry_pick.rs).
The change would be ~20 lines across the two functions. No frontend changes needed since the JSON serialization already maps diff_with_first_parent to changes.
Happy to put up a PR if this approach makes sense — or if a toggle between first-parent and merge-base diff would be preferred.