forked from bchanot/claude
fix(gitflow): init on an existing repo under the machine-wide hooks lands the socle via a chore/gitflow-adopt merge (T2c)
This commit is contained in:
+17
-1
@@ -50,7 +50,7 @@ chk "tree CLEAN after init" '[ -z "$(git status --porcelain)" ]'
|
||||
chk "hook TRACKED in commit" 'git ls-files --error-unmatch .githooks/pre-commit >/dev/null 2>&1'
|
||||
chk "socle IN root commit" 'git show HEAD:.gitignore | grep -qxF ".claude/deploy/PENDING.json"'
|
||||
|
||||
echo "T2b — init existing (master→main rename + adoption commit, hook inactive during it)"
|
||||
echo "T2b — init existing (master→main rename + adoption via chore/gitflow-adopt merge)"
|
||||
newrepo existing
|
||||
git symbolic-ref HEAD refs/heads/master # force the repo onto 'master'
|
||||
echo a > a.txt; printf 'node_modules/\n' > .gitignore; git add -A
|
||||
@@ -64,6 +64,22 @@ chk "existing tree CLEAN" '[ -z "$(git status --porcelain)" ]'
|
||||
chk "existing hook tracked" 'git ls-files --error-unmatch .githooks/pre-commit >/dev/null 2>&1'
|
||||
chk "kept project rule" 'git show HEAD:.gitignore | grep -qxF "node_modules/"'
|
||||
|
||||
echo "T2c — init existing under a LIVE pre-commit (global hooks simulated): socle lands via merge"
|
||||
newrepo live; git symbolic-ref HEAD refs/heads/master
|
||||
echo a > a.txt; printf 'node_modules/\n' > .gitignore; git add -A
|
||||
git -c core.hooksPath=/dev/null commit -q -m "pre-existing on master"
|
||||
_gitflow_write_hook "$WORK/globalhooks" # the machine-wide hook set, as make link installs it
|
||||
git config core.hooksPath "$WORK/globalhooks" # stands in for git's GLOBAL core.hooksPath during init
|
||||
# shellcheck disable=SC2034
|
||||
live_rc=0; GITFLOW_NO_PUSH=1 gitflow_init >/dev/null 2>&1 || live_rc=$?
|
||||
chk "T2c init succeeds under the live hook (rc 0)" "[ $live_rc -eq 0 ]"
|
||||
chk "T2c socle reached main via a merge commit" 'git log main --oneline -1 | grep -q "Merge chore/gitflow-adopt"'
|
||||
chk "T2c .gitignore socle on main" 'git show main:.gitignore | grep -qxF ".claude/deploy/PENDING.json"'
|
||||
chk "T2c hooks tracked on main" 'git ls-tree -r main --name-only | grep -q "^.githooks/pre-commit$"'
|
||||
chk "T2c adoption branch deleted" '! git rev-parse --verify -q refs/heads/chore/gitflow-adopt >/dev/null'
|
||||
chk "T2c develop created from main" '[ "$(git rev-parse develop)" = "$(git rev-parse main)" ]'
|
||||
chk "T2c repo hook active afterwards" '[ "$(git config core.hooksPath)" = .githooks ]'
|
||||
|
||||
echo "T3 — hook blocks/permits after init"
|
||||
cd "$WORK/fresh" || exit 1
|
||||
git checkout -q main
|
||||
|
||||
+25
-7
@@ -293,20 +293,38 @@ _gitflow_init_existing() { # has commits → ensure main (rename master)
|
||||
fi
|
||||
fi
|
||||
git checkout -q "$GITFLOW_MAIN" || return 1
|
||||
# commit the socle + versioned hook now, while hooksPath is NOT yet active
|
||||
# (activation is the last step of gitflow_init) → never self-blocked.
|
||||
# The socle (.gitignore + versioned hooks) reaches main through a MERGE: the
|
||||
# pre-commit hook is global on the machine (BDR-095), so a direct commit on
|
||||
# main is refused even during init, while a merge commit is hook-exempt.
|
||||
# Any failure aborts BEFORE develop/hook activation so a partial run can't
|
||||
# activate the hook and self-block every re-run.
|
||||
git add -- .gitignore .githooks 2>/dev/null || true
|
||||
# socle commit failure is FATAL — abort BEFORE develop/hook-activation so a
|
||||
# partial run can't activate the hook and self-block every re-run (was a bug:
|
||||
# the `|| commit` form swallowed the failure, then init activated the hook).
|
||||
if ! git diff --cached --quiet -- .gitignore .githooks 2>/dev/null; then
|
||||
git commit -q -m "chore: adopt gitflow socle + pre-commit hook" \
|
||||
|| { echo "gitflow_init: socle commit failed — aborting before hook activation (recoverable)" >&2; return 1; }
|
||||
_gitflow_adopt_socle || return 1
|
||||
fi
|
||||
git rev-parse --verify -q "refs/heads/$GITFLOW_DEVELOP" >/dev/null \
|
||||
|| git branch "$GITFLOW_DEVELOP" "$GITFLOW_MAIN"
|
||||
}
|
||||
|
||||
# Commit the staged socle on chore/gitflow-adopt (a working branch, so the
|
||||
# pre-commit allows it), merge it --no-ff into main (a merge commit runs no
|
||||
# pre-commit), delete the branch. The branch forks off main because develop
|
||||
# does not exist yet at init time.
|
||||
_gitflow_adopt_socle() {
|
||||
local br="chore/gitflow-adopt"
|
||||
if git rev-parse --verify -q "refs/heads/$br" >/dev/null; then
|
||||
echo "gitflow_init: '$br' already exists (earlier run) — merge or delete it, then re-run" >&2
|
||||
return 1
|
||||
fi
|
||||
git checkout -q -b "$br" || return 1
|
||||
git commit -q -m "chore: adopt gitflow socle + versioned hooks" \
|
||||
|| { echo "gitflow_init: socle commit failed — aborting before hook activation (recoverable)" >&2; return 1; }
|
||||
git checkout -q "$GITFLOW_MAIN" || return 1
|
||||
git merge --no-ff -q -m "Merge $br into $GITFLOW_MAIN" "$br" \
|
||||
|| { echo "gitflow_init: socle merge into $GITFLOW_MAIN failed — aborting before hook activation" >&2; return 1; }
|
||||
git branch -q -d "$br"
|
||||
}
|
||||
|
||||
# gitflow_init [msg] → idempotent. Order matters (full BLK-010 closure):
|
||||
# reconcile .gitignore + write the versioned hook FIRST, so the fresh root
|
||||
# commit / existing adoption commit EMBED them; activate the hook LAST so the
|
||||
|
||||
Reference in New Issue
Block a user