Skip to content

push_to_pull_request_branch cannot handle merge commits — blocks long-running branch workflows #30286

@mrjf

Description

@mrjf

Problem

When an agent merges the default branch into a PR branch locally (to stay up-to-date), the resulting push_to_pull_request_branch patch includes the merge commit. git am --3way cannot apply merge commits, so the push fails with add/add conflicts even though the agent resolved them locally.

This completely blocks long-running branch workflows like autoloop, where the branch accumulates iterations over time and must periodically merge main.

Reproduction

  1. A long-running PR branch (autoloop/tsb-perf-evolve) is 6 ahead, 22 behind main
  2. Both the branch and main have src/stats/hash_pandas_object.ts (added independently)
  3. The agent checks out the branch, merges main (resolving the add/add conflict locally), commits new work
  4. The agent calls push_to_pull_request_branch
  5. The incremental patch (git format-patch origin/branch..branch) includes the merge commit
  6. git am --3way fails:
    CONFLICT (add/add): Merge conflict in src/stats/hash_pandas_object.ts
    CONFLICT (add/add): Merge conflict in tests/stats/hash_pandas_object.test.ts
    Failed to apply patch
    

Why this keeps happening

The agent cannot push directly — git credentials are cleaned before the agent step (clean_git_credentials.sh). So every git operation that modifies the remote must go through safe-outputs' patch mechanism. But git am fundamentally cannot apply merge commits — it only handles linear patches.

This creates an impossible situation for long-running branches:

  • The branch falls behind main → needs a merge
  • The agent merges main locally → can't push the merge (no credentials)
  • The patch includes the merge → git am fails
  • The branch stays behind → next iteration hits the same problem
  • Evergreen picks it up → same patch failure → infinite retry loop

On githubnext/tsessebe, Evergreen has been failing on this same conflict for days (every run since May 3), burning tokens on every attempt.

Possible fixes

Option A: Let the agent push merges directly

Provide git credentials to the agent (e.g., via GH_AW_CI_TRIGGER_TOKEN) so it can git push merge commits without going through the patch mechanism. The patch mechanism would only be used for create_pull_request (new PRs), not for updating existing branches.

Option B: Handle merge commits in patch generation

Instead of git format-patch (which serializes each commit including merges), generate a single diff patch (git diff origin/branch..branch) that collapses all changes into one patch. This loses individual commit history but avoids the merge commit problem.

Option C: Two-phase push for merges

Split the push into two operations:

  1. First push: merge main into the branch (could use the GitHub merge API POST /repos/{owner}/{repo}/merges which doesn't require local credentials)
  2. Second push: the agent's actual changes on top of the merged branch (clean incremental patch)

Option D: GitHub API merge

Use the GitHub API to merge the default branch into the PR branch (POST /repos/{owner}/{repo}/merges or PUT /repos/{owner}/{repo}/pulls/{pull_number}/update-branch) during the agent step via the GitHub MCP server. This updates the remote branch without needing local git credentials or the patch mechanism.

Impact

Related

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions