fix(#2916): pin new-branch base to origin/$DEFAULT_BRANCH explicitly
Address CodeRabbit HIGH findings on PR #2921. The previous fix had three unconditional code paths where `git checkout -b "$BRANCH_NAME"` would run from the *current* HEAD when the upstream sync failed silently: - the dirty-tree warn-and-continue path, - the clean path where `git switch` / `git merge --ff-only` errors were swallowed by `2>/dev/null` (still falling through to checkout -b), - any case where `git fetch` failed but the script continued. This rewrites both `execute-phase.md` (handle_branching) and `quick.md` (Step 2.5) to: 1. Fetch origin/$DEFAULT_BRANCH; if fetch fails AND no local copy of origin/$DEFAULT_BRANCH exists, abort with a clear ERROR (exit 1) rather than create the branch off arbitrary HEAD. 2. Always create the new branch with an explicit start point: `git checkout -b "$BRANCH_NAME" "origin/$DEFAULT_BRANCH"`. The base is now deterministic regardless of which branch is currently checked out, regardless of whether the optional local fast-forward succeeded, and regardless of dirty-tree state. 3. Carry uncommitted changes onto the new (origin-pinned) branch instead of inheriting the previous-phase HEAD as a fallback base. The post-creation INHERITED check now references origin/$DEFAULT_BRANCH rather than the (possibly-stale) local default branch, so the warning fires accurately even when the local fast-forward was skipped.
This commit is contained in:
@@ -219,10 +219,7 @@ Check `branching_strategy` from init:
|
||||
|
||||
**"phase" or "milestone":** Use pre-computed `branch_name` from init.
|
||||
|
||||
The new phase branch must fork off the project's default branch (`origin/HEAD`),
|
||||
not off whatever HEAD happens to be checked out — otherwise consecutive phases
|
||||
compound on top of each other and stay unpushed (#2916). If `$BRANCH_NAME`
|
||||
already exists locally, reuse it as-is so resumed work is not rebased.
|
||||
Fork the new phase branch off `origin/HEAD` (the project's default branch), not the current HEAD — otherwise consecutive phases compound and stay unpushed (#2916). If `$BRANCH_NAME` already exists locally, reuse it as-is.
|
||||
|
||||
```bash
|
||||
DEFAULT_BRANCH=$(git symbolic-ref --quiet --short refs/remotes/origin/HEAD 2>/dev/null | sed 's|^origin/||')
|
||||
@@ -231,19 +228,22 @@ DEFAULT_BRANCH=${DEFAULT_BRANCH:-main}
|
||||
if git show-ref --verify --quiet "refs/heads/$BRANCH_NAME"; then
|
||||
git switch "$BRANCH_NAME"
|
||||
else
|
||||
if [ -n "$(git status --porcelain)" ]; then
|
||||
echo "WARNING: Uncommitted changes present. Commit or stash before starting a new phase so it branches off $DEFAULT_BRANCH cleanly. Falling back to current HEAD as base."
|
||||
git checkout -b "$BRANCH_NAME"
|
||||
else
|
||||
git fetch --quiet origin "$DEFAULT_BRANCH" 2>/dev/null || true
|
||||
git switch "$DEFAULT_BRANCH" 2>/dev/null && git merge --ff-only "origin/$DEFAULT_BRANCH" 2>/dev/null
|
||||
git checkout -b "$BRANCH_NAME"
|
||||
if ! git fetch --quiet origin "$DEFAULT_BRANCH"; then # #2916
|
||||
git show-ref --verify --quiet "refs/remotes/origin/$DEFAULT_BRANCH" \
|
||||
|| { echo "ERROR: fetch origin/$DEFAULT_BRANCH failed and no local copy exists. Refusing to create '$BRANCH_NAME' off current HEAD (#2916)." >&2; exit 1; }
|
||||
echo "WARNING: fetch origin/$DEFAULT_BRANCH failed; using local copy as base." >&2
|
||||
fi
|
||||
if [ -n "$(git status --porcelain)" ]; then
|
||||
echo "WARNING: Uncommitted changes will be carried onto '$BRANCH_NAME' (branched off origin/$DEFAULT_BRANCH, not previous HEAD)."
|
||||
else
|
||||
git switch --quiet "$DEFAULT_BRANCH" 2>/dev/null && git merge --ff-only --quiet "origin/$DEFAULT_BRANCH" 2>/dev/null || true
|
||||
fi
|
||||
git checkout -b "$BRANCH_NAME" "origin/$DEFAULT_BRANCH" # pinned base (#2916)
|
||||
fi
|
||||
|
||||
INHERITED=$(git rev-list --count "${DEFAULT_BRANCH}..HEAD" 2>/dev/null || echo "?")
|
||||
INHERITED=$(git rev-list --count "origin/${DEFAULT_BRANCH}..HEAD" 2>/dev/null || echo "?")
|
||||
if [ "$INHERITED" != "0" ] && [ "$INHERITED" != "?" ]; then
|
||||
echo "WARNING: Phase branch '$BRANCH_NAME' contains $INHERITED commit(s) inherited from a non-default base. Verify this is intentional before continuing."
|
||||
echo "WARNING: Phase branch '$BRANCH_NAME' contains $INHERITED commit(s) inherited from a non-default base. Verify this is intentional."
|
||||
fi
|
||||
```
|
||||
|
||||
|
||||
Reference in New Issue
Block a user