diff --git a/pkg/tide/tide.go b/pkg/tide/tide.go index 4e2e07052..15a6856e9 100644 --- a/pkg/tide/tide.go +++ b/pkg/tide/tide.go @@ -1439,7 +1439,15 @@ func (c *syncController) takeAction(sp subpool, batchPending, successes, pending // Merge the batch! if len(batchMerges) > 0 { merged, err = c.provider.mergePRs(sp, batchMerges, c.statusUpdate.dontUpdateStatus) - return MergeBatch, batchMerges, err + // If the entire batch failed to merge (e.g., due to conflicts), fall through + // to attempt merging individual PRs to break the tie. + if len(merged) > 0 { + return MergeBatch, batchMerges, err + } + if ok, pr := pickHighestPriorityPR(sp.log, batchMerges, sp.cc, c.isPassingTests, c.config().Tide.Priority); ok { + merged, err = c.provider.mergePRs(sp, []CodeReviewCommon{pr}, c.statusUpdate.dontUpdateStatus) + return Merge, []CodeReviewCommon{pr}, err + } } // Do not merge PRs while waiting for a batch to complete. We don't want to // invalidate the old batch result. diff --git a/pkg/tide/tide_test.go b/pkg/tide/tide_test.go index d114dca55..17301380b 100644 --- a/pkg/tide/tide_test.go +++ b/pkg/tide/tide_test.go @@ -1959,6 +1959,17 @@ func testTakeAction(clients localgit.Clients, t *testing.T) { action: Trigger, enableScheduling: true, }, + { + name: "batch merge fails, falls back to individual PR merge (issue #474)", + batchMerges: []int{0, 1}, + mergeErrs: map[int]error{ + 0: github.UnmergablePRError("merge conflict"), + 1: github.UnmergablePRError("merge conflict"), + }, + merged: 0, + triggered: 0, + action: Merge, + }, } for _, tc := range testcases {