home · contact · privacy
Don't push remote-tracking refs into adopted repo.
authorPlom Heller <plom@plomlompom.com>
Wed, 23 Sep 2026 10:28:08 +0000 (12:28 +0200)
committerPlom Heller <plom@plomlompom.com>
Wed, 23 Sep 2026 10:28:08 +0000 (12:28 +0200)
CLAUDE.md
scripts/adopt_repo.sh

index be6a695dcc82404641700c19cbb2417a33584d95..6e5e816903e63c29bdd443f2cad5e9689856e320 100644 (file)
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -622,9 +622,14 @@ target-side script.
    branch deletion has nothing to recover from, so pushes may only add
    commits. Deliberate friction; lift either by hand on the server for a
    rare, genuine history rewrite.
-3. `git push --mirror` from the local checkout carries over every branch
-   and tag in one shot — the actual content transfer, analogous to a
-   same-host `git clone --bare`.
+3. `git push` with refspecs `refs/heads/*` and `refs/tags/*` from the local
+   checkout carries over every branch and tag in one shot — the actual
+   content transfer, analogous to a same-host `git clone --bare`.
+   Deliberately not `--mirror`: that pushes *every* ref under `refs/`,
+   including the checkout's remote-tracking `refs/remotes/*` (its last-fetch
+   notes on its old origin's branches), which would land as frozen,
+   meaningless refs in a repo that never fetches — and, per
+   `receive.denyDeletes`, couldn't be push-deleted afterwards.
 4. Only once that push has succeeded: point the local checkout's own
    `origin` at the new `ssh://` URL (`remote set-url`, or `remote add` if it
    had none). `set-url` alone never touches a separately configured
index c432f0a7cb0e5ccd47a0d48ea256a280a275b917..5b71e59ef04cb7a4a00648e7768d36a1ab4dbd0c 100755 (executable)
@@ -26,7 +26,7 @@ URL_REMOTE_REPO="ssh://${LOGIN}${PATH_REMOTE_REPO}"
 
 # sanity checks and determination of current active repo branch as NAME_BRANCH
 # (needed for git init's --initial-branch, so the history-free remote repo's
-# HEAD resolves once our later git push --mirror creates that branch)
+# HEAD resolves once our later git push creates that branch)
 check_tools git ssh
 NAME_BRANCH=$(git -C "${PATH_SRC_REPO}" symbolic-ref --quiet --short HEAD)\
     || error "${PATH_SRC_REPO}: not on a branch (detached HEAD?)"
@@ -43,7 +43,8 @@ ssh ${OPTS_SSH_NEW_HOST} "${LOGIN}" "git init --quiet --bare \
 
 msg 'Pushing all branches and tags to %s …' "${SERVER}"
 GIT_SSH_COMMAND="ssh ${OPTS_SSH_NEW_HOST}" \
-    git -C "${PATH_SRC_REPO}" push --quiet --mirror "${URL_REMOTE_REPO}"
+    git -C "${PATH_SRC_REPO}" push --quiet "${URL_REMOTE_REPO}" \
+    'refs/heads/*:refs/heads/*' 'refs/tags/*:refs/tags/*'
 
 msg "Pointing this checkout's origin at %s …" "${SERVER}"
 if try_quiet git -C "${PATH_SRC_REPO}" remote get-url origin; then