Context
get_merge_commit_info (src/git_chain/merge.rs:272) is used only by report_merge_results (src/git_chain/merge.rs:469) to print the per-branch summary after a git chain merge run. It inspects the latest commit on the branch and reports it as a merge from the parent branch when the commit message loosely matches. That's the right scope for the caller (it should report what this run just did — not history, cf. #42), but the detection itself has three defects:
Defects
-
Fast-forward merges report "Already up to date". A fast-forward leaves a normal (non-merge) commit at the tip, so the function returns an empty result and the summary prints Already up to date for a branch that was in fact just merged.
-
Unrelated merges are misattributed to the parent. The match is:
if commit_info.contains(&format!("Merge branch '{}'", parent_branch))
|| commit_info.contains("Merge branch")
The || contains("Merge branch") fallback accepts a merge of any branch, so if the tip commit happens to be a merge from somewhere else, the summary attributes it to parent ➔ branch. Detection is also message-string-based, so custom merge messages defeat it entirely.
-
Stats are almost always missing. git show --stat <merge-commit> prints no diffstat for merge commits by default (combined diff), so MergeStats is effectively always None and the insertions/deletions across N files line never prints.
Suggested targeted fix
Identify the merge commit created by the current run structurally instead of by message text:
- In the merge loop, capture the branch tip before and after
merge_branch; only report when the tip changed.
- Verify the new tip is a merge commit whose second parent equals the parent branch's tip (e.g.
git rev-parse <tip>^2 == parent tip, or via git2 commit parents) — this fixes the misattribution without any message matching. Keep the commit message purely as display text.
- Treat a changed tip that is not a merge commit as a fast-forward and report it as merged (e.g. "Fast-forwarded to ") rather than "Already up to date".
- For stats, use a merge-aware invocation such as
git show --stat --first-parent <tip> (or git diff --shortstat <old-tip> <new-tip>), which also removes the fragile hand-parsing of the files changed line.
Scope: reporting only — no behavior change to the merge operations themselves. report_merge_results output is asserted with .contains() in tests, so wording adjustments are testable without breaking exact-match assertions.
Closes the loop on #42, which attempted to fix the reporting by scanning the branch's entire history — wrong direction for this call site (over-reports historical merges and adds one git show subprocess per commit in history per branch).
Context
get_merge_commit_info(src/git_chain/merge.rs:272) is used only byreport_merge_results(src/git_chain/merge.rs:469) to print the per-branch summary after agit chain mergerun. It inspects the latest commit on the branch and reports it as a merge from the parent branch when the commit message loosely matches. That's the right scope for the caller (it should report what this run just did — not history, cf. #42), but the detection itself has three defects:Defects
Fast-forward merges report "Already up to date". A fast-forward leaves a normal (non-merge) commit at the tip, so the function returns an empty result and the summary prints
Already up to datefor a branch that was in fact just merged.Unrelated merges are misattributed to the parent. The match is:
The
|| contains("Merge branch")fallback accepts a merge of any branch, so if the tip commit happens to be a merge from somewhere else, the summary attributes it toparent ➔ branch. Detection is also message-string-based, so custom merge messages defeat it entirely.Stats are almost always missing.
git show --stat <merge-commit>prints no diffstat for merge commits by default (combined diff), soMergeStatsis effectively alwaysNoneand theinsertions/deletions across N filesline never prints.Suggested targeted fix
Identify the merge commit created by the current run structurally instead of by message text:
merge_branch; only report when the tip changed.git rev-parse <tip>^2== parent tip, or via git2 commit parents) — this fixes the misattribution without any message matching. Keep the commit message purely as display text.git show --stat --first-parent <tip>(orgit diff --shortstat <old-tip> <new-tip>), which also removes the fragile hand-parsing of thefiles changedline.Scope: reporting only — no behavior change to the merge operations themselves.
report_merge_resultsoutput is asserted with.contains()in tests, so wording adjustments are testable without breaking exact-match assertions.Closes the loop on #42, which attempted to fix the reporting by scanning the branch's entire history — wrong direction for this call site (over-reports historical merges and adds one
git showsubprocess per commit in history per branch).