Branching off origin/main set the new branch's upstream to origin/main, so a bare `git push` failed with a name-mismatch and suggested the dangerous `git push origin HEAD:main`. Add --no-track so the branch carries no upstream until the first `git push -u origin <branch>` sets the right one — keeping the fresh-from-origin/main base without the tracking side-effect. Add a test-wt.sh assertion that a new branch has no upstream, and note the behaviour + first-push form in ADR-0059 / CLAUDE.md.
88 lines
3.9 KiB
Bash
Executable File
88 lines
3.9 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Smoke-tests wt-new.sh / wt-rm.sh against a local file:// origin.
|
|
set -euo pipefail
|
|
|
|
here="$(cd "$(dirname "$0")" && pwd)"
|
|
WT_NEW="$here/wt-new.sh"
|
|
WT_RM="$here/wt-rm.sh"
|
|
PASS=0 FAIL=0
|
|
check() { if [ "$2" = "$3" ]; then echo "PASS: $1 ($3)"; PASS=$((PASS+1));
|
|
else echo "FAIL: $1 — expected '$2' got '$3'"; FAIL=$((FAIL+1)); fi; }
|
|
exists() { [ -d "$1" ] && echo yes || echo no; }
|
|
has_branch() { git -C "$T/primary" show-ref --verify --quiet "refs/heads/$1" && echo yes || echo no; }
|
|
|
|
T="$(mktemp -d)"
|
|
trap 'rm -rf "$T"' EXIT
|
|
|
|
git init -q --bare "$T/origin.git"
|
|
git clone -q "$T/origin.git" "$T/primary"
|
|
git -C "$T/primary" config user.email t@t.io
|
|
git -C "$T/primary" config user.name tester
|
|
echo seed > "$T/primary/README.md"
|
|
git -C "$T/primary" add -A
|
|
git -C "$T/primary" commit -qm seed
|
|
git -C "$T/primary" branch -M main
|
|
git -C "$T/primary" push -q origin main
|
|
|
|
run() { ( cd "$T/primary" && "$@" ); }
|
|
target1="$T/primary-worktree-thing-one"
|
|
target2="$T/primary-worktree-thing-two"
|
|
|
|
echo "--- wt-new rejects a non-conventional branch name ---"
|
|
set +e; run bash "$WT_NEW" my-thing >/dev/null 2>&1; rc=$?; set -e
|
|
check "bad-prefix rejected" "yes" "$( [ "$rc" -ne 0 ] && echo yes || echo no )"
|
|
|
|
echo "--- wt-new creates branch + sibling worktree ---"
|
|
out="$(run bash "$WT_NEW" feat/thing-one 2>/dev/null)"
|
|
check "prints target path" "$target1" "$out"
|
|
check "worktree dir exists" "yes" "$(exists "$target1")"
|
|
check "worktree on the new branch" "feat/thing-one" "$(git -C "$target1" rev-parse --abbrev-ref HEAD)"
|
|
# It must NOT inherit origin/main as upstream (else a bare `git push` errors
|
|
# with a name-mismatch and suggests the dangerous `HEAD:main`). No upstream
|
|
# until the first `git push -u` sets the right one.
|
|
check "new branch has no upstream" "none" "$(git -C "$target1" rev-parse --abbrev-ref '@{upstream}' 2>/dev/null || echo none)"
|
|
|
|
echo "--- wt-new refuses to clobber an existing branch ---"
|
|
set +e; run bash "$WT_NEW" feat/thing-one >/dev/null 2>&1; rc=$?; set -e
|
|
check "duplicate rejected" "yes" "$( [ "$rc" -ne 0 ] && echo yes || echo no )"
|
|
|
|
# Second worktree, and make the merge states explicit:
|
|
# thing-one → merged into origin/main (push its tip to main),
|
|
# thing-two → ahead of main (unmerged), clean.
|
|
run bash "$WT_NEW" feat/thing-two >/dev/null 2>&1
|
|
git -C "$target1" commit -q --allow-empty -m "thing-one work"
|
|
git -C "$target1" push -q origin HEAD:main
|
|
git -C "$target2" commit -q --allow-empty -m "thing-two work (unmerged)"
|
|
git -C "$T/primary" fetch -q origin
|
|
|
|
echo "--- wt-rm removes ONLY the named worktree (the other is untouched) ---"
|
|
run bash "$WT_RM" feat/thing-one >/dev/null 2>&1
|
|
check "named worktree removed" "no" "$(exists "$target1")"
|
|
check "UNNAMED worktree untouched" "yes" "$(exists "$target2")"
|
|
check "merged branch deleted" "no" "$(has_branch feat/thing-one)"
|
|
|
|
echo "--- wt-rm errors on an unknown branch ---"
|
|
set +e; run bash "$WT_RM" feat/nope >/dev/null 2>&1; rc=$?; set -e
|
|
check "unknown branch rejected" "yes" "$( [ "$rc" -ne 0 ] && echo yes || echo no )"
|
|
|
|
echo "--- wt-rm refuses the primary checkout ---"
|
|
set +e; run bash "$WT_RM" main >/dev/null 2>&1; rc=$?; set -e
|
|
check "primary refused (nonzero)" "yes" "$( [ "$rc" -ne 0 ] && echo yes || echo no )"
|
|
check "primary still present" "yes" "$(exists "$T/primary")"
|
|
|
|
echo "--- wt-rm refuses a dirty worktree ---"
|
|
touch "$target2/untracked-file"
|
|
set +e; run bash "$WT_RM" feat/thing-two >/dev/null 2>&1; rc=$?; set -e
|
|
check "dirty refused (nonzero)" "yes" "$( [ "$rc" -ne 0 ] && echo yes || echo no )"
|
|
check "dirty worktree kept" "yes" "$(exists "$target2")"
|
|
rm -f "$target2/untracked-file"
|
|
|
|
echo "--- wt-rm removes the worktree but KEEPS an unmerged branch ---"
|
|
run bash "$WT_RM" feat/thing-two >/dev/null 2>&1
|
|
check "unmerged worktree removed" "no" "$(exists "$target2")"
|
|
check "unmerged branch preserved" "yes" "$(has_branch feat/thing-two)"
|
|
|
|
echo
|
|
echo "==== $PASS passed, $FAIL failed ===="
|
|
[ "$FAIL" -eq 0 ]
|