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
# 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?)"
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