情况一:之前的 mirror 裸仓库还在
如果你之前的 cuda-quantum.git(mirror 裸仓库)目录还保留着,两步搞定:
bash
cd ~/cuda-quantum.git
# Step 1: 从 a 仓库拉取最新内容(包括新 tag、新分支、新提交)
# 因为当初 mirror 时 fetch URL 仍指向 a,所以直接 fetch 即可
git fetch origin
# Step 2: 推送到 b 仓库(push URL 已指向 b)
git push --mirror
原理说明:
git clone --mirror https://a.git 创建的裸仓库有两个隐含配置:
bash
$ git config --get remote.origin.url # fetch URL → 仍是 a
https://a.git
$ git config --get remote.origin.pushurl # push URL → 你改成了 b
ssh://b.git
$ git config --get remote.origin.mirror # mirror 模式开启
true
所以 git fetch origin 从 a 拉取 ,git push --mirror 往 b 推送,天然就是增量同步。
情况二:mirror 裸仓库已被删除
如果之前的裸仓库已经删了,不要重新 clone --mirror ,否则会把 Bitbucket 的 refs/pull-requests/* 又拉回来导致推送失败。
正确做法是创建一个新的裸仓库,只 fetch 分支和标签:
bash
# 创建新的裸仓库
git clone --bare https://a.git project.git
cd project.git
# 配置推送到 b
git remote set-url --push origin ssh://b.git
# 推送所有分支和标签(跳过 Bitbucket 内部保留的 refs)
git push origin 'refs/heads/*:refs/heads/*'
git push origin 'refs/tags/*:refs/tags/*'
如果之前的裸仓库已经推送成功过一次,现在只剩增量问题,推荐用情况一保留裸仓库作为长期同步桥。
情况三:只想同步新 tag,不碰已有内容
如果 b 仓库已经有大部分内容,只想把 a 的新 tag 同步过去:
bash
cd ~/cuda-quantum.git
# 获取 a 的所有新内容
git fetch origin
# 只推送新 tag
git push origin --tags
# 或:推送所有分支(只推送 b 上没有的)
git push origin 'refs/heads/*:refs/heads/*'
长期维护:建一个简单的同步脚本
如果 a 和 b 两个仓库需要长期保持同步,建议保留那个 mirror 裸仓库,并写一个定时脚本:
bash
#!/bin/bash
# ~/sync-mirror.sh
REPO_DIR="$HOME/cuda-quantum.git"
cd "$REPO_DIR" || exit 1
echo "Fetching from source (a)..."
git fetch origin
echo "Pushing to mirror (b)..."
# 排除 Bitbucket 内部保留的命名空间
git push origin 'refs/heads/*:refs/heads/*'
git push origin 'refs/tags/*:refs/tags/*'
echo "Done."
加 crontab 每周自动同步:
bash
crontab -e
# 添加
0 2 * * 1 /home/eili/sync-mirror.sh >> /home/eili/sync-mirror.log 2>&1
关键命令速查
| 需求 | 命令 |
|---|---|
| 从 a 增量拉取 | git fetch origin(在 mirror 裸仓库中执行) |
| 全量推送到 b | git push --mirror |
| 只推送分支+标签(安全) | git push origin 'refs/heads/*:refs/heads/*' && git push origin --tags |
| 查看 fetch/push URL | git remote -v |
| 查看新 tag | `git ls-remote --tags origin |