Fix linearize fallback for already-applied merge commits

When cherry-pick -m 1 fails because the merge's changes were already
applied by a prior cherry-pick (empty result, clean working tree),
skip the commit instead of trying git-apply which also fails. Only
use the diff-from-first-parent fallback for real conflicts.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-03-17 14:49:10 +03:00
parent c9b37f2477
commit 4861179c6f

View File

@@ -366,16 +366,17 @@ reverse_sync() {
if git cherry-pick -m 1 "$sha" >/dev/null 2>&1; then if git cherry-pick -m 1 "$sha" >/dev/null 2>&1; then
log "INFO" " squash ${sha:0:7}: ${short_msg}" log "INFO" " squash ${sha:0:7}: ${short_msg}"
else else
git cherry-pick --abort 2>/dev/null # Cherry-pick failed — distinguish empty result (changes already
# Diff from first parent — what the merge actually introduced. # applied by a prior cherry-pick) from a real conflict.
# NOT from HEAD (which would capture all tree differences, not if git diff --cached --quiet 2>/dev/null && git diff --quiet 2>/dev/null; then
# just this merge's changes). # Working tree clean — the merge changes are already present
if git diff "${sha}^1" "$sha" --quiet 2>/dev/null; then git cherry-pick --abort 2>/dev/null || git reset --hard HEAD >/dev/null 2>&1
# Empty diff from first parent — the merge introduced no new log "INFO" " skip ${sha:0:7}: ${short_msg} (already applied)"
# changes (e.g., a fast-forward merge or changes already applied
# by a prior cherry-pick). Skip silently.
log "INFO" " skip ${sha:0:7}: ${short_msg} (empty — already applied)"
else else
# Real conflict — apply diff from first parent (what the merge
# actually introduced, NOT from HEAD which would capture all
# tree differences).
git cherry-pick --abort 2>/dev/null
git diff "${sha}^1" "$sha" | git apply --index >/dev/null 2>&1 \ git diff "${sha}^1" "$sha" | git apply --index >/dev/null 2>&1 \
|| die "Failed to apply merge diff for ${sha:0:7}" || die "Failed to apply merge diff for ${sha:0:7}"
GIT_AUTHOR_NAME="$author_name" GIT_AUTHOR_EMAIL="$author_email" \ GIT_AUTHOR_NAME="$author_name" GIT_AUTHOR_EMAIL="$author_email" \