Skip to content

push_to_pull_request_branch: git am fails with add/add conflict when target branch already has the file #30550

@tore-unumed

Description

@tore-unumed

Problem

When using push_to_pull_request_branch to push incremental changes to an existing PR branch, the handler fails with a CONFLICT (add/add) merge conflict if the target file already exists on the branch from a previous push.

How to reproduce

  1. Configure a workflow with push_to_pull_request_branch that targets an existing PR branch.
  2. Run the workflow. The agent creates a new file (e.g. docs/findings.md). The handler applies the patch successfully and pushes to the PR branch.
  3. Run the workflow again for the same PR. The agent again produces a patch that creates the same file, because the agent workspace is checked out from the base branch where the file does not exist. The patch contains create mode 100644 / new file mode 100644 / index 0000000...
  4. The handler checks out the PR branch (where the file already exists from step 2), then runs git am --3way with the patch.
  5. git am sees "create new file" but the file already exists → CONFLICT (add/add) → handler fails.

The same failure occurs when the agent produces a multi-commit patch series where earlier commits are already applied on the branch.

Root cause

The patch is generated against the base branch state (where the file does not exist), but applied to the PR branch state (where the file was created by a previous push). git am cannot reconcile "create from /dev/null" with an existing file.

Expected behavior

push_to_pull_request_branch should successfully apply changes to an existing PR branch, even when the target file was created by a previous push to that same branch.

Suggested solutions (any of these would work)

  1. Diff against PR branch HEAD, not base — Before applying, compute the incremental diff between the patch final tree and the current PR branch HEAD. Apply only the delta.

  2. Extract final file state from the patch and write directly — Instead of replaying commits via git am, materialize the final file contents from the patch, write them to the working tree, and create a single merge commit. This avoids the replay-history problem entirely.

  3. Skip already-applied commits — Before git am, check if each commit in the patch series is an ancestor of the PR branch HEAD (by commit hash or by patch-id). Skip commits that are already applied.

  4. Fall back on git am conflict — If git am --3way fails with an add/add conflict, abort the am session, extract the intended file contents from the patch, write them directly, and commit. This preserves the current happy path while adding resilience for the incremental push case.

Impact

Any workflow that runs multiple times and pushes to the same PR branch will fail on the second run onward, because the handler cannot push incremental updates to a file it already created.

Metadata

Metadata

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