Skip to content

Post-merge summary misreports merges: fast-forwards show "Already up to date", unrelated merges get misattributed #49

Description

@dashed

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

  1. 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.

  2. 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.

  3. 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).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions