【工具使用】【Shell指令碼】【gitlab】下拉所有的倉庫程式碼並指定分支推送給客戶倉庫

酷酷-發表於2024-09-15

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 指令碼不經常寫就容易忘,有的陣列包含、字串處理什麼的都不會寫了= =,但是有邏輯的話,先幹什麼後幹什麼最終都可以實現,後續空了看看能不能再最佳化下,加油。

相關文章