家里电脑上积累了很多 Git 项目,自从搭建了 Gitea 后,一直想把这些项目迁移过去。但是几十个项目,挨个迁移实在太麻烦了,所以一直拖着。
上篇文章写了git镜像推送的命令,正好趁热打铁,写个脚本来批量迁移这些仓库。
核心思路
- 遍历目标目录下的每个子目录。
- 判断它是不是 Git 仓库。
- 先拉取原远程的最新分支和标签。
- 调用 Gitea API 创建同名私有仓库。
- 临时添加一个新的 Gitea 远程。
- 执行
git push --mirror 全量推送。
- 推送完成后移除临时远程。
完整迁移脚本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
| #!/bin/bash
set -euo pipefail
TARGET_DIR="/path/to/repos"
GITEA_URL="https://gitea.example.com"
GITEA_ORG="your-org"
GITEA_TOKEN="your-token"
GITEA_REPO_PREFIX="ssh://git@gitea.example.com:2222"
ORIGIN_REMOTE="origin"
cd "$TARGET_DIR" || { echo "错误: 无法进入目录 $TARGET_DIR" exit 1 }
echo "工作目录: $TARGET_DIR" echo "Gitea 组织: $GITEA_ORG" echo "拉取远程: $ORIGIN_REMOTE" echo "=============================="
for dir in */; do [ -d "$dir" ] || continue
REPO_NAME=$(basename "$dir") echo "处理仓库: $REPO_NAME"
if [ ! -d "$dir/.git" ]; then echo " 跳过: 不是 Git 仓库" continue fi
pushd "$dir" > /dev/null || { echo " 错误: 无法进入 $dir" continue }
echo " 清理本地更改..." git reset --hard HEAD 2>/dev/null || true git clean -fdx 2>/dev/null || true
if git remote get-url "$ORIGIN_REMOTE" >/dev/null 2>&1; then echo " 正在从 $ORIGIN_REMOTE 拉取全量数据..." if ! git fetch "$ORIGIN_REMOTE" --prune --tags --force; then echo " 警告: 拉取失败,将只推送本地已有内容" fi else echo " 警告: 未找到远程 '$ORIGIN_REMOTE',跳过拉取" fi
echo " 在 Gitea 组织 $GITEA_ORG 创建/检查仓库 $REPO_NAME ..." CREATE_RESPONSE=$(curl -s -w "%{http_code}" -o /dev/null \ -X POST \ -H "Authorization: token $GITEA_TOKEN" \ -H "Content-Type: application/json" \ -d "{\"name\":\"$REPO_NAME\",\"private\":true}" \ "${GITEA_URL}/api/v1/orgs/${GITEA_ORG}/repos")
if [ "$CREATE_RESPONSE" = "201" ]; then echo " 仓库创建成功 (私有)" elif [ "$CREATE_RESPONSE" = "409" ]; then echo " 仓库已存在,将直接推送" else echo " 警告: 创建仓库失败,HTTP 状态码 $CREATE_RESPONSE,将继续尝试推送" fi
NEW_REMOTE_URL="${GITEA_REPO_PREFIX}/${GITEA_ORG}/${REPO_NAME}.git"
echo " 添加临时远程 'gitea' ..." git remote remove gitea 2>/dev/null || true git remote add gitea "$NEW_REMOTE_URL"
echo " 全量推送至新仓库..." if git push --mirror gitea; then echo " 推送成功" else echo " 错误: 推送失败,请检查权限或仓库状态" fi
git remote remove gitea echo " 临时远程 'gitea' 已移除"
popd > /dev/null echo "" done
echo "全部处理完成。"
|
使用方式
先把脚本保存成一个文件,比如 migrate.sh,然后给执行权限:
执行:
如果你的 Gitea 使用的是 SSH 推送,记得提前把本机公钥加到 Gitea 账号里;否则脚本能创建仓库,但推送会失败。