Skip to content

Instantly share code, notes, and snippets.

@wbern
Created August 11, 2026 20:48
Show Gist options
  • Select an option

  • Save wbern/960e0637b8ddfd571332dcd502cfaa1d to your computer and use it in GitHub Desktop.

Select an option

Save wbern/960e0637b8ddfd571332dcd502cfaa1d to your computer and use it in GitHub Desktop.
Sanitized reference bundle from my current Git worktree setup: crash-safe bootstrap, safety notes, privacy checks, and adversarial tests

Worktree hardening reference

This is a small, neutral reference for creating persistent Git worktrees when automation may encounter an already-populated target directory. It is intended to be copied and reviewed as a standalone bundle. It contains no runtime state, repository history, credentials, or deployment inventory.

Contents

  • worktree-bootstrap.sh creates or converges one worktree.
  • worktree-safety.md records the checkout and write-target checks that prevent work from landing in the wrong tree.
  • test-worktree-bootstrap.sh exercises creation, convergence, drift, rollback, and signal handling with synthetic repositories.
  • privacy-scan.sh rejects common private paths, identifiers, addresses, URLs, credential assignments, and optional project-specific terms.
  • ATTRIBUTION.md records the public design reference and license provenance.

Guarantees

The bootstrap:

  • validates that the first argument is the repository root;
  • resolves symlinked path components and refuses a target inside that source repository;
  • disables interactive Git prompts and editors;
  • derives a branch name from both the worker identifier and canonical target path, avoiding a single global branch per worker;
  • starts from the cached remote default branch when one is configured and makes a best-effort non-interactive refresh first;
  • stages pre-existing target files beside the target before git worktree add;
  • restores staged files after command failure or HUP, INT, and TERM;
  • retains a stage with explicit metadata instead of discarding files when a merge conflict prevents automatic restoration;
  • installs runtime-only ignores in Git's local info/exclude; and
  • repairs .gitignore only when the entire unstaged diff consists of known mechanical local-ignore additions. Mixed or staged changes are preserved.

Every warning names the conservative fallback it took.

Non-guarantees

  • This is not a concurrent workspace scheduler. Callers must serialize attempts to create the same target.
  • No process can trap KILL or survive storage loss. If execution stops at that point, a sibling .worktree-stage.* directory and its metadata are the recovery source; inspect and merge it manually.
  • The script never deletes old branches or worktrees. Lifecycle cleanup remains an explicit operator action.
  • --sync refuses a dirty worktree, fetches origin, and fast-forwards only when the branch has an upstream. It does not rebase or resolve divergence.
  • The privacy scanner catches known shapes and supplied terms. It cannot infer an unknown private codename; publication still requires a manual review.

Example

The target parent must already exist:

mkdir -p /tmp/worktrees
./worktree-bootstrap.sh \
  /tmp/example-rig \
  /tmp/worktrees/task-123 \
  worker-1

Re-running the same command converges local excludes and safe mechanical drift. Add --sync only when the worktree is clean and its branch has the intended upstream.

Verification

Run the behavior and privacy checks:

./run-tests.sh

Run the secret scanner independently:

gitleaks dir . --no-banner --redact

Before publication, place any organization-specific private terms in an untracked file outside this bundle, one literal per line, then run:

WORKTREE_PUBLIC_EXTRA_DENYLIST=/tmp/private-terms.txt \
  ./privacy-scan.sh .

Finally, read every candidate line and review the exact file list. Passing an automated scan is evidence, not proof that the reviewer supplied every private term.

Publication boundary

This directory is a local publication candidate. It does not create or update a gist, repository, issue, pull request, or release. Copy only this directory—not its parent repository or Git history—after an explicit publication review.

Attribution

The design was informed by the public Gas City worktree bootstrap, especially its idempotent provisioning, local excludes, and staging-before-create flow:

https://github.com/gastownhall/gascity/blob/19e0862cf8bae6cc631d2828e77bd63878bbe7fd/examples/lifecycle/packs/lifecycle/assets/scripts/worktree-setup.sh

That upstream project is distributed under the MIT License:

https://github.com/gastownhall/gascity/blob/19e0862cf8bae6cc631d2828e77bd63878bbe7fd/LICENSE

This bundle is a neutral behavioral reimplementation. It adds canonical target validation, target-namespaced branches, conservative drift repair, conflict-retaining stage metadata, explicit failure diagnostics, and adversarial tests. It does not include private source files, commits, identifiers, or runtime records.

MIT License
Copyright (c) 2026 Worktree hardening reference contributors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
#!/bin/sh
# Scan a publication candidate for deployment-specific identifiers and data.
set -eu
ROOT=${1:?usage: privacy-scan.sh <candidate-directory>}
[ -d "$ROOT" ] || {
printf 'privacy-scan: not a directory: %s\n' "$ROOT" >&2
exit 2
}
command -v rg >/dev/null 2>&1 || {
printf 'privacy-scan: ripgrep is required\n' >&2
exit 2
}
FAILED=0
report_regex() {
LABEL=$1
PATTERN=$2
shift 2
set +e
MATCHES=$(rg -n --hidden --glob '!.git/**' "$@" -- "$PATTERN" "$ROOT" 2>&1)
SCAN_STATUS=$?
set -e
case "$SCAN_STATUS" in
0)
printf 'privacy-scan: %s\n%s\n' "$LABEL" "$MATCHES" >&2
FAILED=1
;;
1) ;;
*)
printf 'privacy-scan: scanner error for %s\n%s\n' "$LABEL" "$MATCHES" >&2
exit 2
;;
esac
}
report_fixed() {
LABEL=$1
TEXT=$2
report_regex "$LABEL" "$TEXT" -i -F
}
# Fragments keep the scanner from matching its own denylist definitions.
report_fixed "personal home path" "/Us""ers/"
report_fixed "personal home path" "/ho""me/"
report_fixed "personal home path" "/var/ho""me/"
report_regex "non-synthetic email address" \
'[[:alnum:]._%+-]+@(?!example\.invalid\b)[[:alnum:].-]+\.[[:alpha:]]{2,}' -i --pcre2
report_regex "non-public URL" \
'https?://(?!(github\.com/gastownhall/gascity(?:/|$)|example\.invalid(?:/|$)))[^[:space:]<>)"]+' \
-i --pcre2
report_regex "credential-like assignment" \
'(token|password|api[_-]?key|authorization)[[:space:]]*[:=][[:space:]]*[^[:space:]]+' -i
report_regex "incident-like calendar date" \
'(^|[^[:digit:]])20[[:digit:]]{2}-[01][[:digit:]]-[0-3][[:digit:]]([^[:digit:]]|$)'
if [ -n "${WORKTREE_PUBLIC_EXTRA_DENYLIST:-}" ]; then
[ -f "$WORKTREE_PUBLIC_EXTRA_DENYLIST" ] || {
printf 'privacy-scan: extra denylist is not a file\n' >&2
exit 2
}
while IFS= read -r DENY_TERM || [ -n "$DENY_TERM" ]; do
case "$DENY_TERM" in
""|'#'*) continue ;;
esac
report_fixed "extra private term" "$DENY_TERM"
done < "$WORKTREE_PUBLIC_EXTRA_DENYLIST"
fi
if [ "$FAILED" -ne 0 ]; then
printf 'privacy scan failed\n' >&2
exit 1
fi
printf 'privacy scan passed: %s\n' "$ROOT"
#!/bin/sh
set -eu
TEST_DIR=$(CDPATH='' cd -- "$(dirname "$0")" && pwd -P)
"$TEST_DIR/test-worktree-bootstrap.sh"
"$TEST_DIR/test-privacy-scan.sh"
#!/bin/sh
set -eu
TEST_DIR=$(CDPATH='' cd -- "$(dirname "$0")" && pwd -P)
BUNDLE_DIR=$TEST_DIR
SCANNER="$TEST_DIR/privacy-scan.sh"
fail() {
printf 'FAIL: %s\n' "$*" >&2
exit 1
}
[ -x "$SCANNER" ] || fail "missing executable: $SCANNER"
TMP_ROOT=$(mktemp -d "${TMPDIR:-/tmp}/worktree-privacy-test.XXXXXX")
trap 'rm -rf "$TMP_ROOT"' EXIT HUP INT TERM
mkdir -p "$TMP_ROOT/candidate"
{
printf 'path=%s\n' "/Us""ers/private/example-rig"
printf 'contact=%s\n' "someone@corp""oration.invalid"
printf 'url=%s\n' "ht""tps://production.invalid/internal"
} > "$TMP_ROOT/candidate/contaminated.txt"
set +e
"$SCANNER" "$TMP_ROOT/candidate" >"$TMP_ROOT/red.out" 2>"$TMP_ROOT/red.err"
RED_STATUS=$?
set -e
[ "$RED_STATUS" -ne 0 ] || fail "scanner accepted the contaminated fixture"
grep -q "privacy scan failed" "$TMP_ROOT/red.err" ||
fail "scanner failed without the expected privacy diagnostic"
printf 'RED observed: contaminated fixture rejected\n'
printf 'private-project-alpha\n' > "$TMP_ROOT/extra-denylist.txt"
printf 'repository=private-project-alpha\n' > "$TMP_ROOT/candidate/contaminated.txt"
set +e
WORKTREE_PUBLIC_EXTRA_DENYLIST="$TMP_ROOT/extra-denylist.txt" \
"$SCANNER" "$TMP_ROOT/candidate" >"$TMP_ROOT/extra.out" 2>"$TMP_ROOT/extra.err"
EXTRA_STATUS=$?
set -e
[ "$EXTRA_STATUS" -ne 0 ] || fail "scanner ignored the caller-supplied denylist"
grep -q "extra private term" "$TMP_ROOT/extra.err" ||
fail "extra denylist failed without the expected diagnostic"
printf 'RED observed: caller-supplied private term rejected\n'
printf 'safe synthetic fixture for task-123 at %s\n' "ht""tps://example.invalid" \
> "$TMP_ROOT/candidate/contaminated.txt"
"$SCANNER" "$TMP_ROOT/candidate"
printf 'GREEN observed: sanitized fixture accepted\n'
"$SCANNER" "$BUNDLE_DIR"
printf 'PASS: public bundle privacy scan\n'
#!/bin/sh
set -eu
TEST_DIR=$(CDPATH='' cd -- "$(dirname "$0")" && pwd -P)
BUNDLE_DIR=$TEST_DIR
BOOTSTRAP="$BUNDLE_DIR/worktree-bootstrap.sh"
fail() {
printf 'FAIL: %s\n' "$*" >&2
exit 1
}
assert_contains() {
FILE=$1
TEXT=$2
grep -qF "$TEXT" "$FILE" || fail "$FILE does not contain: $TEXT"
}
assert_not_contains() {
FILE=$1
TEXT=$2
if grep -qF "$TEXT" "$FILE"; then
fail "$FILE unexpectedly contains: $TEXT"
fi
}
[ -x "$BOOTSTRAP" ] || fail "missing executable: $BOOTSTRAP"
TMP_ROOT=$(mktemp -d "${TMPDIR:-/tmp}/worktree-bootstrap-test.XXXXXX")
trap 'rm -rf "$TMP_ROOT"' EXIT HUP INT TERM
REPO="$TMP_ROOT/example-rig"
MANAGED="$TMP_ROOT/managed"
TARGET="$MANAGED/task-123"
mkdir -p "$REPO" "$MANAGED" "$TARGET"
git -C "$REPO" init -q -b main
git -C "$REPO" config user.name "Reference Test"
git -C "$REPO" config user.email "worker-1@example.invalid"
printf 'tracked\n' > "$REPO/tracked.txt"
printf '# Project ignores\n' > "$REPO/.gitignore"
git -C "$REPO" add tracked.txt .gitignore
git -C "$REPO" commit -q -m "initial fixture"
printf 'preserve me\n' > "$TARGET/task-123.txt"
printf 'user-owned metadata name\n' > "$TARGET/.worktree-stage.meta"
mkdir -p "$TMP_ROOT/external-payload"
printf 'linked content\n' > "$TMP_ROOT/external-payload/value.txt"
ln -s "$TMP_ROOT/external-payload" "$TARGET/directory-link"
"$BOOTSTRAP" "$REPO" "$TARGET" worker-1
TARGET_CANON=$(CDPATH='' cd -- "$TARGET" && pwd -P)
[ "$(git -C "$TARGET" rev-parse --show-toplevel)" = "$TARGET_CANON" ] ||
fail "target is not the expected worktree"
case "$(git -C "$TARGET" branch --show-current)" in
wt-worker-1-*) ;;
*) fail "branch is not target-namespaced" ;;
esac
[ "$(cat "$TARGET/task-123.txt")" = "preserve me" ] ||
fail "pre-existing target content was not restored"
[ "$(cat "$TARGET/.worktree-stage.meta")" = "user-owned metadata name" ] ||
fail "a user file colliding with the stage metadata name was lost"
[ -L "$TARGET/directory-link" ] || fail "directory symlink was not preserved as a symlink"
[ "$(cat "$TARGET/directory-link/value.txt")" = "linked content" ] ||
fail "directory symlink target changed"
EXCLUDE=$(git -C "$TARGET" rev-parse --git-path info/exclude)
case "$EXCLUDE" in
/*) ;;
*) EXCLUDE="$TARGET/$EXCLUDE" ;;
esac
assert_contains "$EXCLUDE" "# Local worktree-only files"
assert_contains "$EXCLUDE" ".runtime/"
assert_not_contains "$TARGET/.gitignore" ".runtime/"
# A second run must converge without changing the branch or losing content.
FIRST_BRANCH=$(git -C "$TARGET" branch --show-current)
"$BOOTSTRAP" "$REPO" "$TARGET" worker-1
[ "$(git -C "$TARGET" branch --show-current)" = "$FIRST_BRANCH" ] ||
fail "idempotent run changed branch"
[ "$(cat "$TARGET/task-123.txt")" = "preserve me" ] ||
fail "idempotent run lost local content"
# The same worker at a different target must receive a different branch.
SECOND_TARGET="$MANAGED/task-123-second"
"$BOOTSTRAP" "$REPO" "$SECOND_TARGET" worker-1 >/dev/null
SECOND_BRANCH=$(git -C "$SECOND_TARGET" branch --show-current)
[ "$SECOND_BRANCH" != "$FIRST_BRANCH" ] ||
fail "two target paths collided on one worker branch"
# Purely mechanical ignore drift is repaired into local excludes.
printf '.runtime/\n' >> "$TARGET/.gitignore"
"$BOOTSTRAP" "$REPO" "$TARGET" worker-1 2>"$TMP_ROOT/mechanical.err"
assert_not_contains "$TARGET/.gitignore" ".runtime/"
assert_contains "$TMP_ROOT/mechanical.err" "repaired mechanical .gitignore drift"
# Mixed drift is preserved and reported, never broadly restored.
printf '.runtime/\nimportant-output/\n' >> "$TARGET/.gitignore"
"$BOOTSTRAP" "$REPO" "$TARGET" worker-1 2>"$TMP_ROOT/mixed.err"
assert_contains "$TARGET/.gitignore" ".runtime/"
assert_contains "$TARGET/.gitignore" "important-output/"
assert_contains "$TMP_ROOT/mixed.err" "non-mechanical .gitignore drift"
git -C "$TARGET" restore -- .gitignore
# Staged drift is user-owned and must not be repaired.
printf '.runtime/\n' >> "$TARGET/.gitignore"
git -C "$TARGET" add .gitignore
"$BOOTSTRAP" "$REPO" "$TARGET" worker-1 2>"$TMP_ROOT/staged.err"
git -C "$TARGET" diff --cached --quiet -- .gitignore &&
fail "staged .gitignore drift was unexpectedly removed"
git -C "$TARGET" restore --staged --worktree .gitignore
# A target inside the repository is rejected before anything is created.
if "$BOOTSTRAP" "$REPO" "$REPO/nested/task-123" worker-1 >"$TMP_ROOT/nested.out" 2>"$TMP_ROOT/nested.err"; then
fail "nested target was accepted"
fi
[ ! -e "$REPO/nested" ] || fail "nested target validation wrote into the repository"
assert_contains "$TMP_ROOT/nested.err" "outside the repository"
# A failed worktree add restores all staged target content.
FAIL_REPO="$TMP_ROOT/example-rig-failure"
FAIL_TARGET="$MANAGED/failure-task-123"
mkdir -p "$FAIL_REPO" "$FAIL_TARGET" "$TMP_ROOT/fake-bin"
git -C "$FAIL_REPO" init -q -b main
git -C "$FAIL_REPO" config user.name "Reference Test"
git -C "$FAIL_REPO" config user.email "worker-1@example.invalid"
printf 'tracked\n' > "$FAIL_REPO/tracked.txt"
git -C "$FAIL_REPO" add tracked.txt
git -C "$FAIL_REPO" commit -q -m "initial fixture"
printf 'survives failure\n' > "$FAIL_TARGET/task-123.txt"
REAL_GIT=$(command -v git)
export REAL_GIT
cat > "$TMP_ROOT/fake-bin/git" <<'FAKE_GIT'
#!/bin/sh
case " $* " in
*" worktree add "*) exit 73 ;;
*) exec "$REAL_GIT" "$@" ;;
esac
FAKE_GIT
chmod +x "$TMP_ROOT/fake-bin/git"
if PATH="$TMP_ROOT/fake-bin:$PATH" "$BOOTSTRAP" "$FAIL_REPO" "$FAIL_TARGET" worker-1 >"$TMP_ROOT/failure.out" 2>"$TMP_ROOT/failure.err"; then
fail "injected worktree-add failure unexpectedly succeeded"
fi
[ "$(cat "$FAIL_TARGET/task-123.txt")" = "survives failure" ] ||
fail "rollback lost pre-existing content"
[ ! -e "$FAIL_TARGET/.git" ] || fail "failed creation left a partial worktree"
if find "$MANAGED" -maxdepth 1 -name '.worktree-stage.*' -print | grep -q .; then
fail "rollback left a staging directory"
fi
# A target payload that conflicts with a tracked file is retained in a stage.
CONFLICT_REPO="$TMP_ROOT/example-rig-conflict"
CONFLICT_TARGET="$MANAGED/conflict-task-123"
mkdir -p "$CONFLICT_REPO" "$CONFLICT_TARGET"
git -C "$CONFLICT_REPO" init -q -b main
git -C "$CONFLICT_REPO" config user.name "Reference Test"
git -C "$CONFLICT_REPO" config user.email "worker-1@example.invalid"
printf 'repository version\n' > "$CONFLICT_REPO/tracked.txt"
git -C "$CONFLICT_REPO" add tracked.txt
git -C "$CONFLICT_REPO" commit -q -m "initial fixture"
printf 'target version\n' > "$CONFLICT_TARGET/tracked.txt"
if "$BOOTSTRAP" "$CONFLICT_REPO" "$CONFLICT_TARGET" worker-1 >"$TMP_ROOT/conflict.out" 2>"$TMP_ROOT/conflict.err"; then
fail "conflicting target payload unexpectedly succeeded"
fi
CONFLICT_STAGE=$(find "$MANAGED" -maxdepth 1 -name '.worktree-stage.*' -print | sed -n '1p')
[ -n "$CONFLICT_STAGE" ] || fail "conflicting target payload was not retained"
assert_contains "$CONFLICT_STAGE/metadata" "state=merge-conflict"
[ "$(cat "$CONFLICT_STAGE/data/tracked.txt")" = "target version" ] ||
fail "retained conflict does not contain the original target payload"
[ "$(cat "$CONFLICT_TARGET/tracked.txt")" = "repository version" ] ||
fail "conflict handling changed the checked-out repository version"
rm -rf "$CONFLICT_STAGE"
# TERM during the critical section must restore target content as well.
SIGNAL_REPO="$TMP_ROOT/example-rig-signal"
SIGNAL_TARGET="$MANAGED/signal-task-123"
SIGNAL_READY="$TMP_ROOT/signal-ready"
mkdir -p "$SIGNAL_REPO" "$SIGNAL_TARGET"
git -C "$SIGNAL_REPO" init -q -b main
git -C "$SIGNAL_REPO" config user.name "Reference Test"
git -C "$SIGNAL_REPO" config user.email "worker-1@example.invalid"
printf 'tracked\n' > "$SIGNAL_REPO/tracked.txt"
git -C "$SIGNAL_REPO" add tracked.txt
git -C "$SIGNAL_REPO" commit -q -m "initial fixture"
printf 'survives signal\n' > "$SIGNAL_TARGET/task-123.txt"
export SIGNAL_READY
cat > "$TMP_ROOT/fake-bin/git" <<'SIGNAL_GIT'
#!/bin/sh
case " $* " in
*" worktree add "*)
: > "$SIGNAL_READY"
trap 'exit 143' HUP INT TERM
while :; do sleep 1; done
;;
*) exec "$REAL_GIT" "$@" ;;
esac
SIGNAL_GIT
chmod +x "$TMP_ROOT/fake-bin/git"
PATH="$TMP_ROOT/fake-bin:$PATH" \
"$BOOTSTRAP" "$SIGNAL_REPO" "$SIGNAL_TARGET" worker-1 \
>"$TMP_ROOT/signal.out" 2>"$TMP_ROOT/signal.err" &
BOOTSTRAP_PID=$!
READY_ATTEMPTS=0
while [ ! -e "$SIGNAL_READY" ] && [ "$READY_ATTEMPTS" -lt 50 ]; do
sleep 0.1
READY_ATTEMPTS=$((READY_ATTEMPTS + 1))
done
[ -e "$SIGNAL_READY" ] || fail "signal fixture did not reach worktree add"
set +e
kill -TERM "$BOOTSTRAP_PID" 2>/dev/null
wait "$BOOTSTRAP_PID"
SIGNAL_STATUS=$?
set -e
[ "$SIGNAL_STATUS" -ne 0 ] || fail "TERM fixture unexpectedly succeeded"
[ "$(cat "$SIGNAL_TARGET/task-123.txt")" = "survives signal" ] ||
fail "signal recovery lost pre-existing content"
[ ! -e "$SIGNAL_TARGET/.git" ] || fail "signal left a partial worktree"
if find "$MANAGED" -maxdepth 1 -name '.worktree-stage.*' -print | grep -q .; then
fail "signal recovery left a staging directory"
fi
printf 'PASS: worktree bootstrap behavior\n'
#!/bin/sh
# Create or converge one isolated Git worktree without discarding files that
# already exist at the target path.
#
# Usage: worktree-bootstrap.sh <repository-root> <target-directory> <worker-id> [--sync]
set -eu
die() {
printf 'worktree-bootstrap: %s\n' "$*" >&2
exit 1
}
REPO_INPUT=${1:?usage: worktree-bootstrap.sh <repository-root> <target-directory> <worker-id> [--sync]}
TARGET_INPUT=${2:?missing target-directory}
WORKER_ID=${3:?missing worker-id}
SYNC_MODE=${4:-}
case "$SYNC_MODE" in
""|--sync) ;;
*) die "unknown option: $SYNC_MODE" ;;
esac
case "$WORKER_ID" in
""|.*|*..*|*[!A-Za-z0-9._-]*)
die "worker-id must use letters, digits, dots, underscores, or hyphens"
;;
esac
[ -d "$REPO_INPUT" ] || die "repository root is not a directory: $REPO_INPUT"
REPO_DIR=$(CDPATH='' cd -- "$REPO_INPUT" && pwd -P)
REPO_ROOT=$(git -C "$REPO_DIR" rev-parse --show-toplevel 2>/dev/null) ||
die "not a Git repository: $REPO_INPUT"
REPO_ROOT=$(CDPATH='' cd -- "$REPO_ROOT" && pwd -P)
[ "$REPO_DIR" = "$REPO_ROOT" ] || die "first argument must be the repository root"
case "$TARGET_INPUT" in
/*) RAW_TARGET=$TARGET_INPUT ;;
*) RAW_TARGET=$PWD/$TARGET_INPUT ;;
esac
canonicalize_allow_missing() {
PROBE=$1
SUFFIX=
while [ ! -d "$PROBE" ]; do
COMPONENT=$(basename "$PROBE")
PARENT=$(dirname "$PROBE")
[ "$PARENT" != "$PROBE" ] || die "cannot resolve target-directory: $1"
SUFFIX=/$COMPONENT$SUFFIX
PROBE=$PARENT
done
RESOLVED=$(CDPATH='' cd -- "$PROBE" && pwd -P)
printf '%s%s\n' "$RESOLVED" "$SUFFIX"
}
# Resolve the nearest existing ancestor. This catches both direct and symlinked
# attempts to nest a worktree in the source repository before any path is made.
RAW_TARGET=$(canonicalize_allow_missing "$RAW_TARGET")
case "$RAW_TARGET/" in
"$REPO_ROOT/"*) die "target-directory must be outside the repository" ;;
esac
TARGET_PARENT_INPUT=$(dirname "$RAW_TARGET")
[ -d "$TARGET_PARENT_INPUT" ] ||
die "target parent must already exist: $TARGET_PARENT_INPUT"
TARGET_PARENT=$(CDPATH='' cd -- "$TARGET_PARENT_INPUT" && pwd -P)
TARGET_NAME=$(basename "$RAW_TARGET")
case "$TARGET_NAME" in
""|.|..) die "target-directory must name a child of its parent" ;;
esac
WT=$TARGET_PARENT/$TARGET_NAME
if [ -e "$WT" ] || [ -L "$WT" ]; then
[ -d "$WT" ] || die "target exists and is not a directory: $WT"
WT=$(CDPATH='' cd -- "$WT" && pwd -P)
fi
# Resolve symlinked parents before making the same boundary decision again.
case "$WT/" in
"$REPO_ROOT/"*) die "target-directory must be outside the repository" ;;
esac
# Make every Git operation non-interactive. Network failures remain visible.
export GIT_TERMINAL_PROMPT=0
export GIT_EDITOR=true
export GIT_SEQUENCE_EDITOR=true
export GIT_HTTP_LOW_SPEED_LIMIT="${GIT_HTTP_LOW_SPEED_LIMIT:-1}"
export GIT_HTTP_LOW_SPEED_TIME="${GIT_HTTP_LOW_SPEED_TIME:-15}"
if [ -n "${GIT_SSH_COMMAND:-}" ]; then
export GIT_SSH_COMMAND="$GIT_SSH_COMMAND -o BatchMode=yes -o ConnectTimeout=10"
else
export GIT_SSH_COMMAND="ssh -o BatchMode=yes -o ConnectTimeout=10"
fi
git_common_dir() {
CHECKOUT=$1
COMMON=$(git -C "$CHECKOUT" rev-parse --git-common-dir 2>/dev/null) || return 1
case "$COMMON" in
/*) COMMON_PATH=$COMMON ;;
*) COMMON_PATH=$CHECKOUT/$COMMON ;;
esac
(CDPATH='' cd -- "$COMMON_PATH" && pwd -P)
}
append_local_exclude() {
EXCLUDE_PATTERN=$1
grep -qxF "$EXCLUDE_PATTERN" "$EXCLUDE_FILE" 2>/dev/null ||
printf '%s\n' "$EXCLUDE_PATTERN" >> "$EXCLUDE_FILE"
}
install_local_excludes() {
EXCLUDE_FILE=$(git -C "$WT" rev-parse --git-path info/exclude)
case "$EXCLUDE_FILE" in
/*) ;;
*) EXCLUDE_FILE=$WT/$EXCLUDE_FILE ;;
esac
mkdir -p "$(dirname "$EXCLUDE_FILE")"
touch "$EXCLUDE_FILE"
EXCLUDE_MARKER="# Local worktree-only files"
if ! grep -qF "$EXCLUDE_MARKER" "$EXCLUDE_FILE" 2>/dev/null; then
if [ -s "$EXCLUDE_FILE" ] &&
[ "$(tail -c 1 "$EXCLUDE_FILE" 2>/dev/null || true)" != "" ]; then
printf '\n' >> "$EXCLUDE_FILE"
fi
printf '%s\n' "$EXCLUDE_MARKER" >> "$EXCLUDE_FILE"
fi
append_local_exclude ".runtime/"
append_local_exclude ".logs/"
append_local_exclude ".worktree-local/"
append_local_exclude ".editor-state/"
append_local_exclude "state.local.json"
}
mechanical_ignore_drift() {
git -C "$WT" diff --cached --quiet -- .gitignore 2>/dev/null || return 1
git -C "$WT" diff -- .gitignore 2>/dev/null | awk '
BEGIN { changed = 0; safe = 1 }
/^diff --git / || /^index / || /^--- / || /^\+\+\+ / || /^@@ / || /^\\/ { next }
/^\+/ {
line = substr($0, 2)
changed = 1
if (line == "" ||
line == "# Local worktree-only files" ||
line == ".runtime/" ||
line == ".logs/" ||
line == ".worktree-local/" ||
line == ".editor-state/" ||
line == "state.local.json") {
next
}
safe = 0
next
}
/^-/ { safe = 0; next }
END { exit (changed && safe ? 0 : 1) }
'
}
ignore_diff_mentions_local_rule() {
git -C "$WT" diff -- .gitignore 2>/dev/null |
grep -E '^\+((# Local worktree-only files)|\.runtime/|\.logs/|\.worktree-local/|\.editor-state/|state\.local\.json)$' \
>/dev/null 2>&1
}
repair_ignore_drift() {
git -C "$WT" diff --quiet -- .gitignore 2>/dev/null && return 0
if mechanical_ignore_drift; then
git -C "$WT" restore -- .gitignore
printf '%s\n' \
"worktree-bootstrap: repaired mechanical .gitignore drift; rules live in local excludes" >&2
elif ignore_diff_mentions_local_rule; then
printf '%s\n' \
"worktree-bootstrap: warning: non-mechanical .gitignore drift preserved for review" >&2
fi
}
sync_if_requested() {
[ "$SYNC_MODE" = "--sync" ] || return 0
if ! git -C "$WT" remote get-url origin >/dev/null 2>&1; then
printf '%s\n' "worktree-bootstrap: warning: --sync skipped because origin is absent" >&2
return 0
fi
if [ -n "$(git -C "$WT" status --porcelain)" ]; then
die "--sync requires a clean worktree"
fi
git -C "$WT" fetch origin
UPSTREAM=$(git -C "$WT" rev-parse --abbrev-ref --symbolic-full-name '@{upstream}' 2>/dev/null || true)
if [ -n "$UPSTREAM" ]; then
git -C "$WT" merge --ff-only "$UPSTREAM"
else
printf '%s\n' "worktree-bootstrap: warning: fetched origin; branch has no upstream to merge" >&2
fi
}
verify_existing_worktree() {
EXPECTED_COMMON=$(git_common_dir "$REPO_ROOT") ||
die "cannot resolve repository metadata"
ACTUAL_COMMON=$(git_common_dir "$WT") ||
die "target has .git metadata but is not a usable worktree"
[ "$ACTUAL_COMMON" = "$EXPECTED_COMMON" ] ||
die "target belongs to a different Git repository"
}
converge_worktree() {
verify_existing_worktree
install_local_excludes
repair_ignore_drift
git -C "$WT" submodule init >/dev/null 2>&1 || true
sync_if_requested
}
# Existing worktrees are converged on every run, rather than only at creation.
if [ -d "$WT/.git" ] || [ -f "$WT/.git" ]; then
converge_worktree
exit 0
fi
TARGET_HASH=$(printf '%s' "$WT" | git -C "$REPO_ROOT" hash-object --stdin | cut -c1-12)
BRANCH=wt-$WORKER_ID-$TARGET_HASH
git -C "$REPO_ROOT" check-ref-format --branch "$BRANCH" >/dev/null 2>&1 ||
die "derived branch name is invalid"
# Refresh before staging target data, so a slow network operation never runs
# inside the recovery-critical section.
DEFAULT_REF=$(git -C "$REPO_ROOT" symbolic-ref refs/remotes/origin/HEAD 2>/dev/null || true)
if [ -n "$DEFAULT_REF" ]; then
DEFAULT_BRANCH=${DEFAULT_REF#refs/remotes/origin/}
if ! git -C "$REPO_ROOT" fetch origin "$DEFAULT_BRANCH" >/dev/null 2>&1; then
printf '%s\n' \
"worktree-bootstrap: warning: origin refresh failed; using cached $DEFAULT_REF" >&2
fi
fi
STAGE=
STAGE_META=metadata
ADD_PID=
write_stage_metadata() {
META_DIR=$1
META_STATE=$2
META_TMP=$META_DIR/.metadata.tmp.$$
{
printf 'target=%s\n' "$WT"
printf 'state=%s\n' "$META_STATE"
} > "$META_TMP"
mv "$META_TMP" "$META_DIR/$STAGE_META"
}
merge_staged_entry() {
SOURCE=$1
DESTINATION=$2
if [ -d "$SOURCE" ] && [ ! -L "$SOURCE" ]; then
if [ -e "$DESTINATION" ] && [ ! -d "$DESTINATION" ]; then
return 1
fi
mkdir -p "$DESTINATION"
MERGE_FAILED=0
for CHILD in "$SOURCE"/.[!.]* "$SOURCE"/..?* "$SOURCE"/*; do
[ -e "$CHILD" ] || continue
merge_staged_entry "$CHILD" "$DESTINATION/$(basename "$CHILD")" ||
MERGE_FAILED=1
done
[ "$MERGE_FAILED" -eq 0 ] || return 1
rmdir "$SOURCE"
return 0
fi
[ ! -e "$DESTINATION" ] || return 1
mv "$SOURCE" "$DESTINATION"
}
restore_stage() {
[ -n "$STAGE" ] || return 0
mkdir -p "$WT"
STAGE_DATA=$STAGE/data
RESTORE_FAILED=0
for ENTRY in "$STAGE_DATA"/.[!.]* "$STAGE_DATA"/..?* "$STAGE_DATA"/*; do
[ -e "$ENTRY" ] || continue
merge_staged_entry "$ENTRY" "$WT/$(basename "$ENTRY")" || RESTORE_FAILED=1
done
if [ "$RESTORE_FAILED" -eq 0 ] && rmdir "$STAGE_DATA" 2>/dev/null; then
rm -f "$STAGE/$STAGE_META"
else
RESTORE_FAILED=1
fi
if [ "$RESTORE_FAILED" -ne 0 ] || ! rmdir "$STAGE" 2>/dev/null; then
write_stage_metadata "$STAGE" "restore-conflict"
printf '%s\n' \
"worktree-bootstrap: recovery stage retained because target entries conflict: $STAGE" >&2
STAGE=
return 1
fi
STAGE=
}
on_exit() {
EXIT_STATUS=$1
trap - EXIT
if [ -n "$STAGE" ] && ! restore_stage; then
EXIT_STATUS=1
fi
exit "$EXIT_STATUS"
}
on_signal() {
SIGNAL_STATUS=$1
trap - EXIT HUP INT TERM
if [ -n "$ADD_PID" ]; then
kill -TERM "$ADD_PID" 2>/dev/null || true
wait "$ADD_PID" 2>/dev/null || true
ADD_PID=
fi
restore_stage || true
exit "$SIGNAL_STATUS"
}
run_worktree_add() {
GIT_LFS_SKIP_SMUDGE=1 git "$@" &
ADD_PID=$!
if wait "$ADD_PID"; then
ADD_RESULT=0
else
ADD_RESULT=$?
fi
ADD_PID=
return "$ADD_RESULT"
}
trap 'on_exit $?' EXIT
trap 'on_signal 129' HUP
trap 'on_signal 130' INT
trap 'on_signal 143' TERM
if [ -d "$WT" ] && [ -n "$(find "$WT" -mindepth 1 -maxdepth 1 -print | sed -n '1p')" ]; then
STAGE=$(mktemp -d "$TARGET_PARENT/.worktree-stage.XXXXXX")
mkdir "$STAGE/data"
write_stage_metadata "$STAGE" "moving"
for ENTRY in "$WT"/.[!.]* "$WT"/..?* "$WT"/*; do
[ -e "$ENTRY" ] || continue
mv "$ENTRY" "$STAGE/data/"
done
fi
rmdir "$WT" 2>/dev/null || true
git -C "$REPO_ROOT" worktree prune >/dev/null 2>&1 || true
if git -C "$REPO_ROOT" show-ref --verify --quiet "refs/heads/$BRANCH"; then
if ! run_worktree_add -C "$REPO_ROOT" worktree add "$WT" "$BRANCH"; then
die "failed to create worktree at $WT from existing branch $BRANCH"
fi
elif [ -n "$DEFAULT_REF" ]; then
if ! run_worktree_add -C "$REPO_ROOT" worktree add -b "$BRANCH" "$WT" "$DEFAULT_REF"; then
die "failed to create worktree at $WT from $DEFAULT_REF"
fi
else
if ! run_worktree_add -C "$REPO_ROOT" worktree add -b "$BRANCH" "$WT"; then
die "failed to create worktree at $WT from current HEAD"
fi
fi
if [ -n "$STAGE" ]; then
STAGE_DATA=$STAGE/data
MERGE_FAILED=0
for ENTRY in "$STAGE_DATA"/.[!.]* "$STAGE_DATA"/..?* "$STAGE_DATA"/*; do
[ -e "$ENTRY" ] || continue
merge_staged_entry "$ENTRY" "$WT/$(basename "$ENTRY")" || MERGE_FAILED=1
done
if [ "$MERGE_FAILED" -eq 0 ] && rmdir "$STAGE_DATA" 2>/dev/null; then
rm -f "$STAGE/$STAGE_META"
else
MERGE_FAILED=1
fi
if [ "$MERGE_FAILED" -ne 0 ] || ! rmdir "$STAGE" 2>/dev/null; then
write_stage_metadata "$STAGE" "merge-conflict"
printf '%s\n' \
"worktree-bootstrap: refused to discard conflicting staged entries: $STAGE" >&2
STAGE=
exit 1
fi
STAGE=
fi
trap - EXIT HUP INT TERM
converge_worktree

Worktree safety notes

The current directory and the write target are separate facts. A shell can be inside the correct worktree while a script, editor, or pasted absolute path writes into the shared source checkout.

Before any edit or commit, inspect both:

pwd
git rev-parse --show-toplevel
git branch --show-current
git worktree list
git status --short --branch

Then resolve the file you are about to change. Its path must begin with the assigned worktree root. Treat the shared repository checkout as read-only unless the operation explicitly targets it.

A clean git status while you expect to hold an uncommitted edit is a failure signal: stop and find which checkout contains the changed file.

Recovery after a wrong-target edit

Do not commit merely to save the accidental write, and do not reset the whole checkout. Preserve only the affected paths, restore only those paths in the wrong checkout, apply the patch in the intended worktree, and rerun its checks:

git -C <wrong-checkout> diff -- <path> > /tmp/worktree-recovery.patch
git -C <wrong-checkout> restore -- <path>
git -C <assigned-worktree> apply /tmp/worktree-recovery.patch
git -C <assigned-worktree> status --short

If the wrong checkout already had unrelated changes in the same file, stop and separate the edits manually; a path-level restore would also be destructive.

Commit and formatter checks

  • Confirm a reported commit is on the intended branch with git branch -a --contains <commit>.
  • Scope formatters to the files changed for this task. A repository-wide autofix in a shared or dirty checkout can rewrite unrelated work.
  • Remove a finished worktree with git worktree remove <path> without --force, then run git worktree prune. Never remove its directory behind Git's back.

These checks are intentionally redundant: checkout identity protects commands that use relative paths, while write-target validation protects tools that use absolute paths.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment