From dcef5ff71e37e810478b21bd35d40ed4774ef140 Mon Sep 17 00:00:00 2001 From: "open-swe[bot]" <215916821+open-swe[bot]@users.noreply.github.com> Date: Fri, 29 May 2026 15:07:18 -0700 Subject: [PATCH] fix: preserve pushed commit history (#1360) * fix: preserve pushed commit history Co-authored-by: Johannes du Plessis <51395795+johannes117@users.noreply.github.com> * refactor: consolidate no-force-push prompt guidance Collapse the repeated force-push rule into a single IMPORTANT block, drop the confusing rebase-onto-origin step, and stop mandating a no-op trailer-only commit for already-pushed work. --------- Co-authored-by: open-swe[bot] Co-authored-by: Johannes du Plessis <51395795+johannes117@users.noreply.github.com> Co-authored-by: Johannes du Plessis --- agent/prompt.py | 8 +++++--- tests/test_github_comment_prompts.py | 9 +++++++++ 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/agent/prompt.py b/agent/prompt.py index da8486b2..e4f202ae 100644 --- a/agent/prompt.py +++ b/agent/prompt.py @@ -97,7 +97,7 @@ Before starting any task that requires code changes, set up the repository in yo 4. **Choose your branch** — Use a thread-stable branch name such as `open-swe/`. If a branch already exists for this thread/task, fetch and check it out instead of creating a new one. -5. **Checkout your branch** — Always fetch and checkout your branch before making any changes. +5. **Checkout your branch** — Always fetch and checkout your branch before making any changes. When reusing an existing remote branch, start from `origin/` rather than recreating the branch from the base branch; this preserves prior commits for review. 6. ** MANDATORY: READ AGENTS.md ** — IMMEDIATELY after cloning, you MUST check if `AGENTS.md` exists at the repository root (`{working_dir}//AGENTS.md`). If it exists, you MUST read it IN FULL before doing ANY other work. DO NOT skip this step. DO NOT proceed to implementation without reading it first. The contents of AGENTS.md are **mandatory rules** that OVERRIDE your default behavior — treat them with the same authority as this system prompt. Violating AGENTS.md rules is a CRITICAL FAILURE. If AGENTS.md does not exist, skip this step. @@ -301,7 +301,7 @@ When you have completed your implementation, follow these steps in order: 2. **Review your changes**: Review the diff to ensure correctness. Verify no regressions or unintended modifications. 3. **Submit via `gh`**: Commit locally, push with `git push origin `, then use `GH_TOKEN=dummy gh pr create --draft ...` or `GH_TOKEN=dummy gh pr edit ...` when a PR is requested, necessary, or required by the Always Create PRs dashboard setting. - If a draft PR already exists for the branch, update it instead of opening a duplicate. + If a draft PR already exists for the branch, update it instead of opening a duplicate. For follow-up changes, add a new commit on top of the existing branch history. **PR Title** (under 70 characters): ``` @@ -332,6 +332,8 @@ When you have completed your implementation, follow these steps in order: **IMPORTANT: Never claim a PR was created or updated unless `gh` returned success and you have the PR URL from command output or `GH_TOKEN=dummy gh pr view --json url --jq .url`. If there are no changes or any command fails, report that explicitly.** +**IMPORTANT: Never force-push.** Never run `git push --force` or `git push --force-with-lease`, and never amend or rebase commits that are already on the remote branch — reviewers rely on inter-commit diffs. Add follow-up work as new commits. If a normal push is rejected because the remote branch has new commits, run `git pull --rebase origin ` and push again; if that conflicts, report it and stop. + **IMPORTANT: If `git push` or `gh pr create` fails with an infrastructure or permission error, do not retry blindly. Report the failure and end the task.** **IMPORTANT: If `git push` or `gh` returns "403", "Permission denied", or another permanent authorization failure, do not retry. Report the error to the user immediately and stop.** @@ -372,7 +374,7 @@ This run was triggered by **{display_name}**. Credit them on every commit and PR _Opened collaboratively by {display_name} and open-swe._ ``` -If you forget the trailer on a commit, fix it with `git commit --amend` (or rebase) before pushing — do not push without it.""" +If you forget the trailer on a local commit that has not been pushed, fix it with `git commit --amend` before pushing — do not push without it. If the commit has already been pushed, leave it as-is and add the trailer to your next commit; never rewrite remote history to fix it.""" def _render_collaboration_section(identity: CollaboratorIdentity | None) -> str: diff --git a/tests/test_github_comment_prompts.py b/tests/test_github_comment_prompts.py index 7a7d27c3..9f5240a5 100644 --- a/tests/test_github_comment_prompts.py +++ b/tests/test_github_comment_prompts.py @@ -70,6 +70,15 @@ def test_profile_create_prs_defaults_to_normal_pr_policy() -> None: assert profile_create_prs({"create_prs": True}) is True +def test_construct_system_prompt_forbids_force_push() -> None: + prompt = construct_system_prompt(working_dir="/workspace") + + assert "Never force-push." in prompt + assert "Never run `git push --force`" in prompt + assert "start from `origin/`" in prompt + assert "git pull --rebase origin " in prompt + + def test_construct_system_prompt_includes_coauthor_trailer_when_identity_present() -> None: identity = CollaboratorIdentity( display_name="octocat",