有一个需求,在gitlab上有一个仓库,其中保留有大量的分支和tag信息;现在该仓库准备废弃,迁移到另外的仓库中,但是所有历史记录也要保存在新的仓库中。
gitlab上如果直接fork会把仓库fork成为自己私有的,这不符合要求。
git本身支持一个本地仓库对应多个远程仓库,只要使用下面命令即可
git add name url
但是 git push 时,默认只能推送当前分支,当然也可以使用 -all 推送所有分支,不过这样的操作也只能推送本地已经创建出来的分支,而新拉取的仓库在刚开始时默认只有master一个分支,总不能手动一个个创建并关联远程吧。
其实这种根据远程分支创建所有本地分支的操作可以通过脚本创建,如果使用shell,可以这样操作:
第一步 创建所有分支
git branch -r | grep -v '\->' | while read remote; do git branch --track "${remote#origin/}" "$remote"; done
上面的命令可以分为三部分:
1 列出所有远程分支
git branch 默认是列出本地所有分支,-r 表示列出远程所有分支;
2 去除不需要的内容
git branch -r 列出的分支格式基本如下:
上面每一项都是一项远程分支;但有个问题,如果远程仓库不是裸版本仓库(本人猜测非裸版本应该有自己的主分支,但不保证这个猜测正确),则它的 HEAD 也会指向相应的分支,这条是需要被过滤掉的,即图片中 origin/HEAD 这一项,grep -v ‘->’ 正是做这个工作的,因此这里需要用 grep 过滤一下。
3 新建所有分支并关联远程分支
grep 后过滤出远程所有有效分支,用 branch --track 来创建分支,这里用了 while 循环,其中 --track 时使用了shell的子字符串截取方式:
${remote#origin/}
因为所有远程分支均是以 origin/ 开头,因此这里用将这一部分去掉。
以上三步操作后,所有分支均已创建好。
推送所有信息
git push 默认只会推送当前分支,如果想推送所有分支,包括tag,使用以下命令:
git push ${remote} '*:*'
git push ${remote} --all
git push --all ${remote}
上面 remote 是仓库映射的远程仓库名,通过.git/config 文件可以看到.
上面 push --all 表示把所有分支推送上去,即.git/refs/heads 下所有分支。第一行 ‘:’ 似乎是推送所有tag,需要进一步确认。