Bash Shell自定義助手函數git-submodule-foreach:遍歷對每個git子模塊倉庫執(zhí)行自定義的函數或命令序列

概述:

在一個大型項目下,我們通常通過Git Submodule(子模塊)機制引入了其他代碼倉庫,很多時候我們需要對這些子模塊倉庫執(zhí)行一系列操作(包括推送和拉取更新、查看代碼變更,替換源文件字符串等等),雖然git原生有自帶的 submodule foreach命令可以遍歷對子模塊倉庫執(zhí)行命令,但自帶的這個功能只能執(zhí)行實際存在的命令(即執(zhí)行的命令必須是真實存在的可執(zhí)行文件),無法直接運行終端自定義的函數或命令別名(alias),有一種方法可以曲線救國,實現對子模塊倉庫調用shell函數的功能,具體方法如下:

git submodule foreach bash -l -c "myfunction"     # myfunction為用戶自定義在~/.bash_profile中的函數
git submodule foreach bash -l -c "ll"             # ll為ls的別名引用,實際不存在ll這個命令

但以上方法會fork出額外的子進程,造成額外的性能開銷,影響效率,故編寫此輔助函數git-submodule-foreach,將其注入到~/.bash_profile或~/.bashrc文件中即可隨時隨地輕松調用(原理:查看.gitmodules注冊了哪些子模塊,自動pushd到子模塊目錄,在當前會話環(huán)境下執(zhí)行自定義函數命令或alias后再退回原工作目錄[popd],不再額外fork bash子進程...);

git-submodule-foreach函數代碼:

git-submodule-foreach() {
    #自動搜索并進入子模塊目錄執(zhí)行自定義的函數或Alias別名,作用類似于Git原生命令 git submodule foreach ...;
    #(場景說明:因 git submodule foreach xxxx 僅支持調用真實存在的命令,無法調用函數或Alias,故寫此輔助函數);
    # eg:git-submodule-foreach gtoday
    #     git-submodule-foreach git-log-today
    #     git-submodule-foreach git-plog-today
    #     git-submodule-foreach git-lines-today
    #     git-submodule-foreach git-show-yesterday -s --pretty="%cN\<%cE\>\ %cd\ %s"
    #     git-submodule-foreach 'git-show-yesterday -s --pretty="%cN<%cE> %cd %s"'   #用單引號包含完整的命令行則可以省去轉義過程
    #     git-submodule-foreach 'git-log-yesterday|wc -l'    #支持子命令中使用管道符(需用單引號包裹命令行....)
    # Git使用的環(huán)境變量請參看:https://git-scm.com/book/zh/v2/Git-%E5%86%85%E9%83%A8%E5%8E%9F%E7%90%86-%E7%8E%AF%E5%A2%83%E5%8F%98%E9%87%8F
    #----------------------------------------------------
    ([[ "$*" == "-h" || "$*" == "--help" ]]) && {
            print_color 40 "git-submodule-foreach:\n\t自動從.gitmodules中讀取注冊的子模塊,并自動進入子模塊執(zhí)行自定義的(命令/函數/Alias指令)!"
            echo -e "Usage:"
            echo -e "\tgit-submodule-foreach"
            return
    }
    
    if [ ! -d "./.git" ];then
        print_color 40 "沒有發(fā)現版本庫目錄.git,請在GIT倉庫根目錄運行此命令!"
        return
    elif [ ! -e "./.gitmodules" ];then
        print_color 40 "當前倉庫不包含子模塊(請檢查是否存在.gitmodules文件),程序退出后續(xù)操作..."
        return
    fi

    local subModules=$(cat .gitmodules|dos2unix -q|awk -F '=' 'BEGIN{IGNORECARE=1}\
        /\[submodule .*\]/{\
                getline;if(match($0,/^[ \t]*path[ \t]*=/)){gsub(" ","",$2);print $2;}\
        }')
    
    local subModulesPath=($(echo "$subModules"|tr '\n' ' '))
    
    [ -z "$*" ] && set -- "pwd"  #沒有指定任何附加參數則打印當前工作目錄的絕對路徑(pwd)
        
    for subPath in ${subModulesPath[@]};
    do
        [ -d "$subPath" ] && {
                pushd "$subPath" &>/dev/null
                echo "$subPath:"
                #pwd
                eval "$@"  #<---常規(guī)模式傳遞參數注意特殊字符需要轉義(如重定向符號<、>等...);你可以用單引號包裹完整的命令行以避免轉義的麻煩
                local subRetCode=$?
                echo -e "——————————————————————————————————————————————————————————————————————————————————————————————"
                popd &>/dev/null
                [ $subRetCode -ne 0 ] && break  #子命令返回失敗值則退出函數,不再循環(huán)向后執(zhí)行...(測試命令:git-submodule-foreach git-show-yesterday -s --pretty="%cN<%cE> %cd %s" 或  git-submodule-foreach test 1 -eq 2)
                command :  #為了避免輸出錯誤到下一個語句塊
            } || {
                print_color 9 "子模塊路徑:$subPath 不存在,自動跳過!"
            }
    done
    [ $subRetCode -ne 0 ] && print_color 40 "警告:因子模塊調用的命令以非零狀態(tài)退出,未對所有模塊執(zhí)行命令!"
}

使用例子:

1、對子倉庫執(zhí)行簡單命令:

git-submodule-foreach git log --oneline -5

2、對子倉庫執(zhí)行自定義函數或alias別名:

git-submodule-foreach print_color $(date +'%F %T')
git-submodule-foreach ll

3、子倉庫執(zhí)行命令時使用管道符:

#注意用單引號包括完整的子命令,否則子命令中的特殊字符需要轉義
git-submodule-foreach 'git log --oneline -5|wc -l'
git-submodule-foreach 'git log --oneline -5|tee ./gitlog.log'

4、對子模塊倉庫一次執(zhí)行多條命令:

#同上,使用單引號包裹子命令,多條命令用分號或 && 連接即可
#
#  區(qū)別:使用分號時,無論上一條命令執(zhí)行成功與否,都執(zhí)行下一條命令
#        使用 && 時,只有上一條命令執(zhí)行成功才會執(zhí)行下一條命令
git-submodule-foreach 'pwd;git log --oneline -5|wc -l'
git-submodule-foreach 'll && echo 123'
git-submodule-foreach 'lla && echo 123'
?著作權歸作者所有,轉載或內容合作請聯系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容