Shell脚本批量迁移TFS至Bitbucket遇特殊字符及$符号报错求助
批量迁移TFS到Bitbucket的脚本错误修复方案
问题根源拆解
- $符号被Git Bash解析:TFS路径以
$/开头,但Git Bash会将$视为变量前缀,导致传递给git-tfs的路径丢失$,触发TFS repository can not be root and must start with "$/"错误。 - 路径格式冲突:Windows路径在Git Bash中使用双反斜杠
\\容易出现转义异常,需统一使用正斜杠/。 - cmd.exe调用转义错误:直接通过cmd.exe执行时,Bash对
$和引号的转义逻辑与cmd冲突,导致命令解析失败。 - Git命令无效执行:由于git-tfs克隆失败,后续Git命令因找不到
.git目录抛出报错。
修正后的完整脚本
bitbucket_base_url="https://bitbucket.org/fm_ebiz/" # 统一使用正斜杠路径,避免Git Bash转义问题 migration_directory="E:/Migration2" excel_file="C:/Scripts/Repos.csv" while IFS=',' read -r repo_path || [[ -n "$repo_path" ]]; do # 清除路径前后多余空格(处理CSV格式异常) repo_path=$(echo "$repo_path" | xargs) repo_name=$(basename "$(dirname "$repo_path")") repo_name=${repo_name,,} echo "Repo_name: $repo_name" bitbucket_remote="$bitbucket_base_url$repo_name.git" echo "Bitbucket_remote: $bitbucket_remote" mkdir -p "$migration_directory/$repo_name" # 核心修正:用printf '%q'转义路径,保留$符号不被Bash解析 git-tfs clone 'http://mytfs_url/tfs/ebi' "$(printf '%q' "$repo_path")" "$migration_directory/$repo_name" echo "Repo_Path: $repo_path" # 增加克隆成功检查,避免无效Git命令执行 if [[ -d "$migration_directory/$repo_name/.git" ]]; then cd "$migration_directory/$repo_name" pwd git remote add bitbucket "$bitbucket_remote" # git-tfs克隆后默认远程名为tfs,而非origin git pull tfs master if [[ "$repo_name" == "Release" ]]; then git push bitbucket master:"$repo_name" --set-upstream else git push bitbucket master:"$repo_name" git push bitbucket "$repo_name:$repo_name" --set-upstream fi cd "$migration_directory" rm -rf "$repo_name" else echo "Error: 克隆失败,跳过仓库 $repo_path" rm -rf "$migration_directory/$repo_name" fi done < "$excel_file"
关键修改说明
- 保留TFS路径的$符号:使用
printf '%q' "$repo_path"对路径进行转义,确保$/前缀完整传递给git-tfs,不会被Bash解析为变量。 - 统一路径格式:将Windows路径改为正斜杠
/,避免Git Bash中双反斜杠的转义冲突。 - 增加错误校验:判断
.git目录是否存在,仅在克隆成功后执行后续Git操作。 - 修正拉取源:git-tfs克隆后默认远程名为
tfs,因此将git pull origin master改为git pull tfs master。
备选方案:通过cmd.exe执行git-tfs
若Git Bash直接调用git-tfs仍有问题,可改用cmd.exe执行,需额外处理$符号转义:
# 将路径中的$转义为\$,避免cmd解析错误 escaped_repo_path=$(echo "$repo_path" | sed 's/\$/\\\$/g') # 用双引号包裹cmd命令,内部路径用\"转义 cmd.exe /C "git-tfs clone http://mytfs/tfs/ebi \"$escaped_repo_path\" \"$migration_directory/$repo_name\""
额外注意事项
- 检查
Repos.csv格式:确保每行仅包含一个TFS路径,无多余逗号、空格或换行符。 - 单仓库测试:先手动执行修正后的克隆命令验证单个仓库迁移成功,再批量运行脚本。
- 权限验证:提前确保Git Bash具备TFS读取权限和Bitbucket推送权限,可配置凭据管理器或SSH密钥避免重复输入密码。
内容的提问来源于stack exchange,提问作者user14041754
相关产品推荐
相关产品推荐

