【工具使用】【Shell脚本】【gitlab】下拉所有的仓库代码并指定分支推送给客户仓库
1 前言
这不是项目要结束了么,项目验收要交付源代码,客户在阿里云上买了个云效,需要把我们公司的代码同步上去。
首先云效支持各种导入,比如直接贴上你的 gitlab地址,再加个token 他就会自己同步,但我不能这么做,主要是因为我们公司有的别的项目代码也在一块,只是分支不一样,并且做事情要干精细点负责点。用了哪个分支就只推哪个分支。
那同步一个仓库的代码,大概需要这么几步:
(1)拉代码 git clone xxx地址
(2)切换分支
(3)添加新仓库地址 git remote add new-origin xxxx新仓库地址
(4)推送 git push new-origin 完事
看似简单其实中间还是遇到一些问题,比如:
(1)权限:拉代码要权限 推代码也要权限 这个我们通过 ssh 方式来方便些 先本地生成下 ssh 然后把 key 配置到拉代码仓库的 key里 也在推的新仓库地址里配置上这个 key 这样拉推的权限就解决了
(2)ssh 推送的时候会有个这个 Are you sure you want to continue connecting (yes/no/[fingerprint]? 可以执行这个 set GIT_SSH_COMMAND=ssh -o StrictHostKeyChecking=accept-new
(3)获取全部仓库,这个还是通过 gitlab 的接口去拉,需要 token,但是不知道是不是 gitlab 的问题还是我的问题 总是获取的不全 我是用的这个 api:/api/v4/projects?per_page=9999&simple=true 它是分页的所以加上 per_page 参数,因为输出的信息很多加上 simple=true
(4)过滤仓库,因为并不是所有的都推,所以要筛选过滤一下,这个维护一个数组 要么在数组里的才推 要么在数组里的不推 或者某个名称开头等 看你们选择
(5)分支筛选,分支命名各种不规范要筛选出一些特定的分支,没有特定分支的话,再推一个默认test分支
(6)打扫战场,推送完后续不用的话,配的 key 该删的就删 token不用的话也删掉等
大概能回忆的暂时是这些问题,基本都解决了,就剩 gitlab 获取所有的仓库感觉它返回的就是不全,是真不全,不知道是不是权限不够还是怎么的,明明我能看到的仓库,JSON数据里边就是没有,大家有知道的还望指点下。
另外参考:这是我之前拉仓库的时候写的另一个 【工具使用】【Shell脚本】【gitlab】下拉所有的仓库代码。
2 前置
前置的工作主要就是,ssh 的 key 的生成加配置即可。
生成命令:
ssh-keygen -t rsa -b 4096 -C "xxx"
windows 默认的生成位置 c:/用户/名称/.ssh:
然后把 id_rsa.pub 里的密钥复制到拉推仓库,比如 gitlab:
阿里云效的在这里:
另外拉全部仓库的时候,是调用 gitlab 的 HTTP 接口所以也需要一个 Token,在这个页面生成一个即可。
好,前置工作基本就这样。
3 脚本
脚本的话,我这里也就直接贴了,都有注释,大家可以试试,需要变化的可能就是前面的四个地址以及后边要推送分支根据你的情况进行更改:
#!/bin/bash # 要拉取仓库的HTTP地址 GIT_ADDR="https://xxxxxx" # 要拉区仓库的 TOKEN GIT_ACCESS_TOKEN="xxxxx" # 要拉取的仓库的 SSH 前缀 GIT_CLONE_ADDR="ssh://git@xxxxx:23" # 要推送的仓库 SSH 前缀 GIT_PUSH_ADDR="git@xxxxxxx" # 获取的json文件名称 JSON_FILE="data.json" # 获取所有的仓库 echo "download start" curl -H "PRIVATE-TOKEN:$GIT_ACCESS_TOKEN" -H "Content-Type: application/json" "$GIT_ADDR/api/v4/projects?per_page=9999" > $JSON_FILE # json解析 objs=$(cat $JSON_FILE | jq '.[].path_with_namespace') echo "handle start" for obj in $objs do # 去掉双引号 obj=`echo $obj | sed -e 's/"//g'` echo $obj # 分支计算标识 如果有指定分支 num++ 没有最后就是 0 等于0的话推默认分支 num=0 # 前缀筛选 判断是不是以某个字符串开头的 if [[ $obj == stock* ]]; then # 截取最后的仓库名称 比如 a/b/c 得出 c result="${obj##*/}" # 打印一下 echo $result # 拼接 clone 地址信息 obj=`echo $GIT_CLONE_ADDR/$obj` # 打印完整的地址信息 echo $obj # 拉取代码 git clone $obj # 进入代码目录 cd $result # 添加新的远程仓库 norigin=`echo $GIT_PUSH_ADDR/$result` echo $norigin git remote add new-origin $norigin # 按分支进行筛选推送 test=$(git branch -a | grep test) echo $test if [ ${#test} -gt 0 ]; then echo "我找到test了" ((num++)) git checkout test # 推送 git push new-origin fi master=$(git branch -a | grep master) echo $master if [ ${#master} -gt 0 ]; then echo "我找到master了" ((num++)) git checkout master # 推送 git push new-origin fi dev=$(git branch -a | grep dev) echo $dev if [ ${#dev} -gt 0 ]; then if [ ${#num} -eq 0 ]; then echo "我找到dev了" git checkout dev # 推送 git push new-origin fi fi # 退出当前仓库路径 cd .. # !!!可以先测试一个 可以的话把 break 去掉即可 break fi done echo "handle end"
最后总共 55个仓库代码的推送,代码就不能给大家看了哈:
shell 脚本不经常写就容易忘,有的数组包含、字符串处理什么的都不会写了= =,但是有逻辑的话,先干什么后干什么最终都可以实现,后续空了看看能不能再优化下,加油。