Skip to content

Cross-repo safe-output PRs fail: patch generated as "create new file" when target file already exists #17969

Closed
Tarekchehahde/gh-aw
#10

Description

@Yoyokrazy

Note

This issue was AI-generated based on investigation of two failing workflow runs.

Problem

When a workflow's target-repo differs from the source repo (cross-repo safe-output PR), git am fails with exit code 128 because the patch is generated as create mode 100644 (new file) even though the file already exists in the target repo.

Reproduction

This is reproducible in a cross-repo workflow that:

  • runs in a source repo workspace
  • reads a file from a different target repo via GitHub MCP
  • writes/edits that file locally
  • emits a patch via generate_git_patch.sh
  • applies the patch in the target repo via safe-outputs

In this configuration, the patch is generated as create mode 100644, but the file already exists in the target repo, so git am fails with exit code 128.

Root Cause

  1. The agent runs in the source repo workspace
  2. It reads a file from the target repo via GitHub MCP, writes it locally, and edits it
  3. generate_git_patch.sh diffs against the source repo's HEAD — since the file doesn't exist in the source repo, the diff is create mode 100644 (a full new-file patch)
  4. The safe_outputs job checks out the target repo (where the file already exists) and runs git am, which correctly rejects creating a file that already exists

Workflow config

safe-outputs:
    create-pull-request:
        target-repo: 'microsoft/vscode-docs'
        allowed-repos: ['microsoft/vscode-docs']
        base-branch: main

Suggested Fix

Either (or both):

  1. Patch generation: When target-repo differs from the source repo, diff against the target repo's tree instead of the source repo's HEAD. This would produce a proper "modify existing file" patch.

  2. Patch application: Use git am --3way (or fall back to git apply --3way) when applying cross-repo patches, which can resolve the create-vs-modify mismatch using the target repo's index.

Environment

  • gh-aw: v0.46.5 / awf v0.20.1 / awmg v0.1.4
  • Copilot CLI: 0.0.411
  • Model: claude-opus-4.6

Activity

  1. locked and limited conversation to collaborators on Feb 23, 2026
  2. unlocked this conversation on Feb 23, 2026
  3. dsyme commented on Feb 24, 2026

    @dsyme
    Collaborator

    Fixed in #18175 (we hope, testing is hard for theis area)

  4. Yoyokrazy commented on Feb 24, 2026

    @Yoyokrazy
    Author

    Reopening — the fix in #18175 (git am --3way) does not resolve this. We confirmed v0.50.1 is deployed and running (the Setup Scripts step loads setup@fad43e3c91a4e1d43e458f68e96574127934e7d1, and the logs show git am --3way being invoked), but the patch still fails.

    Why --3way doesn't help here: The patch is create mode 100644 with blob 0000000..abc1234. There's no base blob to do a 3-way merge against — the patch says "this file is brand new" but the file already exists in the target repo. git am --3way falls back to regular apply in this case, which still fails.

    Logs from v0.50.1 run:

    [command]/usr/bin/git am --3way /tmp/gh-aw/aw-insiders-relnotes-vscode-295080.patch
    Patch failed at 0001 Add Insiders release note for microsoft/vscode#295080
    ##[error]Failed to apply patch: The process '/usr/bin/git' failed with exit code 128
    

    The patch header:

     create mode 100644 release-notes/v1_110.md
    

    The core issue remains: generate_git_patch.sh diffs against the source repo's HEAD. When target-repo differs, files that exist in the target repo but not the source repo produce create mode patches. The fix needs to be in patch generation (diff against target repo tree) or in application (detect create mode for existing files and convert to a modify patch before applying).

  5. locked and limited conversation to collaborators on Feb 24, 2026
  6. unlocked this conversation on Feb 24, 2026
  7. Yoyokrazy commented on Feb 24, 2026

    @Yoyokrazy
    Author

    To clarify why --3way can't help: the root cause is that generate_git_patch.sh diffs against the source repo's git tree (vscode-engineering), not the target repo's tree (vscode-docs). Since the file doesn't exist in the source repo, the diff produces create mode 100644 with base blob 0000000 (null tree). When git am --3way tries to find a common ancestor for a null blob, there's nothing to merge against.

    This is a patch generation issue in generate_git_patch.sh, not something fixable via prompting. The script runs automatically after the agent finishes — workflow authors and agents have no control over how the patch is produced. When the workflow config specifies a target-repo different from the source repo, generate_git_patch.sh should diff the agent's workspace against the target repo's tree (e.g. by fetching the target repo's HEAD as the base) so that existing files produce modify diffs instead of create diffs.

  8. locked and limited conversation to collaborators on Feb 24, 2026
  9. unlocked this conversation on Feb 24, 2026
  10. reopened this on Feb 24, 2026
  11. Tarekchehahde commented on Jul 11, 2026

    @Tarekchehahde

    Fork PR: Tarekchehahde#10

    Upstream compare: main...Tarekchehahde:gh-aw:fix/17969-cross-repo-patch-modify

    Approach: After format-patch generation, when workflow repo ≠ target repo, rewrite "new file" hunks to modify diffs against origin/<base> in the target checkout (fixes the #18175 --3way gap).

    Local tests: vitest run git_patch_utils.test.cjs — 19/19 pass (includes git am --3way integration test)

  12. locked and limited conversation to collaborators on Jul 11, 2026
  13. unlocked this conversation on Jul 11, 2026
  14. pelikhan commented on Jul 11, 2026

    @pelikhan
    Collaborator

    @Tarekchehahde open new issues, inline patch description in body - thanks

  15. Tarekchehahde commented on Jul 11, 2026

    @Tarekchehahde

    @pelikhan Thanks for the feedback.

  16. pelikhan commented on Jul 11, 2026

    @pelikhan
    Collaborator

    @Tarekchehahde i will certainly miss comments but not new issues. Keep it coming.

  17. added a commit that references this issue on Jul 11, 2026
    a255e08
  18. locked and limited conversation to collaborators on Jul 11, 2026
  19. unlocked this conversation on Jul 11, 2026
  20. pelikhan commented on Oct 7, 2026

    @pelikhan
    Collaborator

    Status (2026-10-07; Contributor proposal): On July 11, a contributor shared a fork PR proposing to rewrite cross-repo new-file patches against the target tree and opened tracking issue #44977 after the maintainer requested a separate issue. The next step is to review that proposal and its target-checkout tests upstream; the fork and tracking issue do not establish a merged fix.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions