Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 22 additions & 3 deletions scripts/agent-branch-finish.sh
Original file line number Diff line number Diff line change
Expand Up @@ -172,9 +172,25 @@ if [[ "$should_require_sync" -eq 1 ]] && git -C "$repo_root" show-ref --verify -
behind_count="${behind_count:-0}"
if [[ "$behind_count" -gt 0 ]]; then
echo "[agent-sync-guard] Branch '${SOURCE_BRANCH}' is behind origin/${BASE_BRANCH} by ${behind_count} commit(s)." >&2
echo "[agent-sync-guard] Run: musafety sync --base ${BASE_BRANCH}" >&2
echo "[agent-sync-guard] Then retry: bash scripts/agent-branch-finish.sh --branch \"${SOURCE_BRANCH}\"" >&2
exit 1
echo "[agent-sync-guard] Auto-syncing '${SOURCE_BRANCH}' onto origin/${BASE_BRANCH} before finish..." >&2
if ! git -C "$source_worktree" rebase "origin/${BASE_BRANCH}"; then
git_dir="$(git -C "$source_worktree" rev-parse --git-dir)"
rebase_active=0
if [[ -e "${git_dir}/rebase-merge" || -e "${git_dir}/rebase-apply" ]]; then
rebase_active=1
fi

echo "[agent-sync-guard] Auto-sync failed while rebasing '${SOURCE_BRANCH}' onto origin/${BASE_BRANCH}." >&2
if [[ "$rebase_active" -eq 1 ]]; then
echo "[agent-sync-guard] Resolve conflicts, then run: git -C \"$source_worktree\" rebase --continue" >&2
echo "[agent-sync-guard] Or abort: git -C \"$source_worktree\" rebase --abort" >&2
fi
exit 1
fi

behind_after="$(git -C "$repo_root" rev-list --left-right --count "${SOURCE_BRANCH}...origin/${BASE_BRANCH}" 2>/dev/null | awk '{print $2}')"
behind_after="${behind_after:-0}"
echo "[agent-sync-guard] Auto-sync complete (behind now: ${behind_after})." >&2
fi
fi

Expand Down Expand Up @@ -334,6 +350,9 @@ fi
if [[ "$source_worktree" == "$repo_root" ]]; then
if is_clean_worktree "$source_worktree"; then
git -C "$source_worktree" checkout "$BASE_BRANCH" >/dev/null 2>&1 || true
if [[ "$PUSH_ENABLED" -eq 1 ]] && git -C "$repo_root" show-ref --verify --quiet "refs/remotes/origin/${BASE_BRANCH}"; then
git -C "$source_worktree" pull --ff-only origin "$BASE_BRANCH" >/dev/null 2>&1 || true
fi
fi
elif [[ "$source_worktree" == "$current_worktree" && "$source_worktree" == "${repo_root}/.omx/agent-worktrees"/* ]]; then
git -C "$source_worktree" checkout --detach >/dev/null 2>&1 || true
Expand Down
25 changes: 22 additions & 3 deletions templates/scripts/agent-branch-finish.sh
Original file line number Diff line number Diff line change
Expand Up @@ -172,9 +172,25 @@ if [[ "$should_require_sync" -eq 1 ]] && git -C "$repo_root" show-ref --verify -
behind_count="${behind_count:-0}"
if [[ "$behind_count" -gt 0 ]]; then
echo "[agent-sync-guard] Branch '${SOURCE_BRANCH}' is behind origin/${BASE_BRANCH} by ${behind_count} commit(s)." >&2
echo "[agent-sync-guard] Run: musafety sync --base ${BASE_BRANCH}" >&2
echo "[agent-sync-guard] Then retry: bash scripts/agent-branch-finish.sh --branch \"${SOURCE_BRANCH}\"" >&2
exit 1
echo "[agent-sync-guard] Auto-syncing '${SOURCE_BRANCH}' onto origin/${BASE_BRANCH} before finish..." >&2
if ! git -C "$source_worktree" rebase "origin/${BASE_BRANCH}"; then
git_dir="$(git -C "$source_worktree" rev-parse --git-dir)"
rebase_active=0
if [[ -e "${git_dir}/rebase-merge" || -e "${git_dir}/rebase-apply" ]]; then
rebase_active=1
fi

echo "[agent-sync-guard] Auto-sync failed while rebasing '${SOURCE_BRANCH}' onto origin/${BASE_BRANCH}." >&2
if [[ "$rebase_active" -eq 1 ]]; then
echo "[agent-sync-guard] Resolve conflicts, then run: git -C \"$source_worktree\" rebase --continue" >&2
echo "[agent-sync-guard] Or abort: git -C \"$source_worktree\" rebase --abort" >&2
fi
exit 1
fi

behind_after="$(git -C "$repo_root" rev-list --left-right --count "${SOURCE_BRANCH}...origin/${BASE_BRANCH}" 2>/dev/null | awk '{print $2}')"
behind_after="${behind_after:-0}"
echo "[agent-sync-guard] Auto-sync complete (behind now: ${behind_after})." >&2
fi
fi

Expand Down Expand Up @@ -334,6 +350,9 @@ fi
if [[ "$source_worktree" == "$repo_root" ]]; then
if is_clean_worktree "$source_worktree"; then
git -C "$source_worktree" checkout "$BASE_BRANCH" >/dev/null 2>&1 || true
if [[ "$PUSH_ENABLED" -eq 1 ]] && git -C "$repo_root" show-ref --verify --quiet "refs/remotes/origin/${BASE_BRANCH}"; then
git -C "$source_worktree" pull --ff-only origin "$BASE_BRANCH" >/dev/null 2>&1 || true
fi
fi
elif [[ "$source_worktree" == "$current_worktree" && "$source_worktree" == "${repo_root}/.omx/agent-worktrees"/* ]]; then
git -C "$source_worktree" checkout --detach >/dev/null 2>&1 || true
Expand Down
14 changes: 11 additions & 3 deletions test/install.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -814,7 +814,7 @@ test('pre-commit sync gate honors maxBehindCommits threshold', () => {
assert.equal(commitAttempt.status, 0, commitAttempt.stderr || commitAttempt.stdout);
});

test('agent-branch-finish blocks when source branch is behind origin/dev', () => {
test('agent-branch-finish auto-syncs source branch when behind origin/dev', () => {
const repoDir = initRepo();
seedCommit(repoDir);
attachOriginRemote(repoDir);
Expand Down Expand Up @@ -848,9 +848,17 @@ test('agent-branch-finish blocks when source branch is behind origin/dev', () =>
['scripts/agent-branch-finish.sh', '--branch', 'agent/test-finish-sync-guard'],
repoDir,
);
assert.equal(finish.status, 1, finish.stderr || finish.stdout);
assert.equal(finish.status, 0, finish.stderr || finish.stdout);
assert.match(finish.stderr, /agent-sync-guard/);
assert.match(finish.stderr, /musafety sync --base dev/);
assert.match(finish.stderr, /Auto-syncing 'agent\/test-finish-sync-guard' onto origin\/dev before finish/);
assert.match(finish.stderr, /Auto-sync complete \(behind now: 0\)/);
assert.match(
finish.stdout,
/Merged 'agent\/test-finish-sync-guard' into 'dev' via direct flow and removed branch\./,
);

result = runCmd('git', ['show-ref', '--verify', '--quiet', 'refs/heads/agent/test-finish-sync-guard'], repoDir);
assert.notEqual(result.status, 0, 'agent branch should be deleted locally after finish');
});

test('agent-branch-finish pr mode continues cleanup when gh merge only fails local branch deletion', () => {
Expand Down
Loading