dev: rebase on target branch before every push (#770) (#775)

Fixes #770

The dev agent was pushing fixes without rebasing. If main moved since the branch was created, the PR becomes unmergeable.

This adds a rebase step before every git push in the dev agent workflow:
- Initial push after implementing
- Push after CI fix
- Push after review feedback

Rebasing ensures PRs stay up-to-date with the target branch and avoids merge conflicts.

Co-authored-by: johba <johba@users.codeberg.org>
Reviewed-on: https://codeberg.org/johba/disinto/pulls/775
Reviewed-by: Disinto_bot <disinto_bot@noreply.codeberg.org>
This commit is contained in:
johba 2026-03-26 21:46:21 +01:00
parent e0f977be20
commit f918e26cce
3 changed files with 44 additions and 11 deletions

View file

@ -178,7 +178,7 @@ check_script() {
# Inline-sourced lib files — check that their own function calls resolve. # Inline-sourced lib files — check that their own function calls resolve.
# These are already in LIB_FUNS (their definitions are available to agents), # These are already in LIB_FUNS (their definitions are available to agents),
# but this verifies calls *within* each lib file are also resolvable. # but this verifies calls *within* each lib file are also resolvable.
check_script lib/env.sh check_script lib/env.sh lib/mirrors.sh
check_script lib/agent-session.sh check_script lib/agent-session.sh
check_script lib/ci-helpers.sh check_script lib/ci-helpers.sh
check_script lib/secret-scan.sh check_script lib/secret-scan.sh
@ -186,7 +186,7 @@ check_script lib/file-action-issue.sh lib/secret-scan.sh
check_script lib/tea-helpers.sh lib/secret-scan.sh check_script lib/tea-helpers.sh lib/secret-scan.sh
check_script lib/formula-session.sh lib/agent-session.sh check_script lib/formula-session.sh lib/agent-session.sh
check_script lib/load-project.sh check_script lib/load-project.sh
check_script lib/mirrors.sh check_script lib/mirrors.sh lib/env.sh
check_script lib/guard.sh check_script lib/guard.sh
# Standalone lib scripts (not sourced by agents; run directly or as services). # Standalone lib scripts (not sourced by agents; run directly or as services).
@ -201,9 +201,9 @@ check_script dev/phase-handler.sh dev/dev-agent.sh lib/secret-scan.sh
check_script dev/dev-poll.sh check_script dev/dev-poll.sh
check_script dev/phase-test.sh check_script dev/phase-test.sh
check_script gardener/gardener-run.sh check_script gardener/gardener-run.sh
check_script review/review-pr.sh check_script review/review-pr.sh lib/agent-session.sh
check_script review/review-poll.sh check_script review/review-poll.sh
check_script planner/planner-run.sh check_script planner/planner-run.sh lib/agent-session.sh lib/formula-session.sh
check_script supervisor/supervisor-poll.sh check_script supervisor/supervisor-poll.sh
check_script supervisor/update-prompt.sh check_script supervisor/update-prompt.sh
check_script vault/vault-agent.sh check_script vault/vault-agent.sh

View file

@ -538,6 +538,8 @@ SUMMARY_FILE=\"${IMPL_SUMMARY_FILE}\"
**After committing and pushing your branch:** **After committing and pushing your branch:**
\`\`\`bash \`\`\`bash
# Rebase on target branch before push to avoid merge conflicts
git fetch ${FORGE_REMOTE} ${PRIMARY_BRANCH} && git rebase ${FORGE_REMOTE}/${PRIMARY_BRANCH}
git push ${FORGE_REMOTE} ${BRANCH} git push ${FORGE_REMOTE} ${BRANCH}
# Write a short summary of what you implemented: # Write a short summary of what you implemented:
printf '%s' \"<your summary>\" > \"\${SUMMARY_FILE}\" printf '%s' \"<your summary>\" > \"\${SUMMARY_FILE}\"
@ -553,15 +555,19 @@ echo \"PHASE:awaiting_review\" > \"${PHASE_FILE}\"
Then STOP and wait. The orchestrator will inject review feedback. Then STOP and wait. The orchestrator will inject review feedback.
**When you receive a \"CI failed:\" injection:** **When you receive a \"CI failed:\" injection:**
Fix the CI issue, commit, push, then: Fix the CI issue, then rebase on target branch and push:
\`\`\`bash \`\`\`bash
git fetch ${FORGE_REMOTE} ${PRIMARY_BRANCH} && git rebase ${FORGE_REMOTE}/${PRIMARY_BRANCH}
git push --force-with-lease ${FORGE_REMOTE} ${BRANCH}
echo \"PHASE:awaiting_ci\" > \"${PHASE_FILE}\" echo \"PHASE:awaiting_ci\" > \"${PHASE_FILE}\"
\`\`\` \`\`\`
Then STOP and wait. Then STOP and wait.
**When you receive a \"Review: REQUEST_CHANGES\" injection:** **When you receive a \"Review: REQUEST_CHANGES\" injection:**
Address ALL review feedback, commit, push, then: Address ALL review feedback, then rebase on target branch and push:
\`\`\`bash \`\`\`bash
git fetch ${FORGE_REMOTE} ${PRIMARY_BRANCH} && git rebase ${FORGE_REMOTE}/${PRIMARY_BRANCH}
git push --force-with-lease ${FORGE_REMOTE} ${BRANCH}
echo \"PHASE:awaiting_ci\" > \"${PHASE_FILE}\" echo \"PHASE:awaiting_ci\" > \"${PHASE_FILE}\"
\`\`\` \`\`\`
(CI runs again after each push — always write awaiting_ci, not awaiting_review) (CI runs again after each push — always write awaiting_ci, not awaiting_review)

View file

@ -135,6 +135,8 @@ SUMMARY_FILE="${_sf}"
**After committing and pushing your branch:** **After committing and pushing your branch:**
\`\`\`bash \`\`\`bash
# Rebase on target branch before push to avoid merge conflicts
git fetch ${_remote} ${PRIMARY_BRANCH} && git rebase ${_remote}/${PRIMARY_BRANCH}
git push ${_remote} ${_br} git push ${_remote} ${_br}
# Write a short summary of what you implemented: # Write a short summary of what you implemented:
printf '%s' "<your summary>" > "\${SUMMARY_FILE}" printf '%s' "<your summary>" > "\${SUMMARY_FILE}"
@ -150,15 +152,19 @@ echo "PHASE:awaiting_review" > "${_pf}"
Then STOP and wait. The orchestrator will inject review feedback. Then STOP and wait. The orchestrator will inject review feedback.
**When you receive a "CI failed:" injection:** **When you receive a "CI failed:" injection:**
Fix the CI issue, commit, push, then: Fix the CI issue, then rebase on target branch and push:
\`\`\`bash \`\`\`bash
git fetch ${_remote} ${PRIMARY_BRANCH} && git rebase ${_remote}/${PRIMARY_BRANCH}
git push --force-with-lease ${_remote} ${_br}
echo "PHASE:awaiting_ci" > "${_pf}" echo "PHASE:awaiting_ci" > "${_pf}"
\`\`\` \`\`\`
Then STOP and wait. Then STOP and wait.
**When you receive a "Review: REQUEST_CHANGES" injection:** **When you receive a "Review: REQUEST_CHANGES" injection:**
Address ALL review feedback, commit, push, then: Address ALL review feedback, then rebase on target branch and push:
\`\`\`bash \`\`\`bash
git fetch ${_remote} ${PRIMARY_BRANCH} && git rebase ${_remote}/${PRIMARY_BRANCH}
git push --force-with-lease ${_remote} ${_br}
echo "PHASE:awaiting_ci" > "${_pf}" echo "PHASE:awaiting_ci" > "${_pf}"
\`\`\` \`\`\`
(CI runs again after each push — always write awaiting_ci, not awaiting_review) (CI runs again after each push — always write awaiting_ci, not awaiting_review)
@ -394,7 +400,26 @@ Write PHASE:awaiting_review to the phase file, then stop and wait for review fee
log "infra failure — retrigger CI (retry ${CI_RETRY_COUNT})" log "infra failure — retrigger CI (retry ${CI_RETRY_COUNT})"
(cd "$WORKTREE" && git commit --allow-empty \ (cd "$WORKTREE" && git commit --allow-empty \
-m "ci: retrigger after infra failure (#${ISSUE})" --no-verify 2>&1 | tail -1) -m "ci: retrigger after infra failure (#${ISSUE})" --no-verify 2>&1 | tail -1)
(cd "$WORKTREE" && git push "${FORGE_REMOTE:-origin}" "$BRANCH" --force 2>&1 | tail -3) # Rebase on target branch before push to avoid merge conflicts
if ! (cd "$WORKTREE" && \
git fetch "${FORGE_REMOTE:-origin}" "${PRIMARY_BRANCH}" 2>/dev/null && \
git rebase "${FORGE_REMOTE:-origin}/${PRIMARY_BRANCH}" 2>&1 | tail -5); then
log "rebase conflict detected — aborting, agent must resolve"
(cd "$WORKTREE" && git rebase --abort 2>/dev/null || git reset --hard HEAD 2>/dev/null) || true
agent_inject_into_session "$SESSION_NAME" "REBASE CONFLICT: Cannot rebase onto ${PRIMARY_BRANCH} automatically.
Please resolve merge conflicts manually:
1. Check conflict status: git status
2. Resolve conflicts in the conflicted files
3. Stage resolved files: git add <files>
4. Continue rebase: git rebase --continue
If you cannot resolve conflicts, abort: git rebase --abort
Then write PHASE:escalate with a reason."
return 0
fi
# Rebase succeeded — push the result
(cd "$WORKTREE" && git push --force-with-lease "${FORGE_REMOTE:-origin}" "$BRANCH" 2>&1 | tail -3)
# Touch phase file so we recheck CI on the new SHA # Touch phase file so we recheck CI on the new SHA
# Do NOT update LAST_PHASE_MTIME here — let the main loop detect the fresh mtime # Do NOT update LAST_PHASE_MTIME here — let the main loop detect the fresh mtime
touch "$PHASE_FILE" touch "$PHASE_FILE"
@ -436,7 +461,8 @@ Instructions:
1. Run ci-debug.sh failures to get the full error output. 1. Run ci-debug.sh failures to get the full error output.
2. Read the failing test file(s) — understand what the tests EXPECT. 2. Read the failing test file(s) — understand what the tests EXPECT.
3. Fix the root cause — do NOT weaken tests. 3. Fix the root cause — do NOT weaken tests.
4. Commit your fix and push: git push ${FORGE_REMOTE:-origin} ${BRANCH} 4. Rebase on target branch and push: git fetch ${FORGE_REMOTE:-origin} ${PRIMARY_BRANCH} && git rebase ${FORGE_REMOTE:-origin}/${PRIMARY_BRANCH}
git push --force-with-lease ${FORGE_REMOTE:-origin} ${BRANCH}
5. Write: echo \"PHASE:awaiting_ci\" > \"${PHASE_FILE}\" 5. Write: echo \"PHASE:awaiting_ci\" > \"${PHASE_FILE}\"
6. Stop and wait." 6. Stop and wait."
fi fi
@ -577,7 +603,8 @@ ${REVIEW_TEXT}
Instructions: Instructions:
1. Address each piece of feedback carefully. 1. Address each piece of feedback carefully.
2. Run lint and tests when done. 2. Run lint and tests when done.
3. Commit your changes and push: git push ${FORGE_REMOTE:-origin} ${BRANCH} 3. Rebase on target branch and push: git fetch ${FORGE_REMOTE:-origin} ${PRIMARY_BRANCH} && git rebase ${FORGE_REMOTE:-origin}/${PRIMARY_BRANCH}
git push --force-with-lease ${FORGE_REMOTE:-origin} ${BRANCH}
4. Write: echo \"PHASE:awaiting_ci\" > \"${PHASE_FILE}\" 4. Write: echo \"PHASE:awaiting_ci\" > \"${PHASE_FILE}\"
5. Stop and wait for the next CI result." 5. Stop and wait for the next CI result."
log "review REQUEST_CHANGES received (round ${REVIEW_ROUND})" log "review REQUEST_CHANGES received (round ${REVIEW_ROUND})"