欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

使用Git Hook技術(shù)定義和校驗(yàn)代碼提交模板方式

 更新時(shí)間:2023年11月15日 16:16:03   作者:職場(chǎng)007  
這篇文章主要介紹了使用Git Hook技術(shù)定義和校驗(yàn)代碼提交模板方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

1.背景

使用Git做項(xiàng)目的版本控制時(shí),在版本系統(tǒng)中會(huì)有很多的代碼的提交記錄,我們使用git log命令就會(huì)得到如下中的提交記錄:

當(dāng)我們的項(xiàng)目比較簡(jiǎn)單,規(guī)模較小、開(kāi)發(fā)人員也只有一兩個(gè)的時(shí)候,其實(shí)可以不用定義代碼的提交記錄模板,但是當(dāng)我們的項(xiàng)目開(kāi)始變得龐大,有很多的開(kāi)發(fā)者都在參與開(kāi)發(fā)的時(shí)候,我們會(huì)發(fā)現(xiàn)每個(gè)人提交的信息都是千奇百怪的,出現(xiàn)了一個(gè)問(wèn)題,要定位具體的提交時(shí)更是如大海撈針。特別痛苦。

所以Git提供了代碼提交記錄模板,和對(duì)提交記錄模板的驗(yàn)證,讓每個(gè)提交代碼的開(kāi)發(fā)者按照模板填寫(xiě)提交的信息,提交后再驗(yàn)證下開(kāi)發(fā)者是否按照模板的要求填寫(xiě)提交信息,如果沒(méi)有就不讓其執(zhí)行接下來(lái)的git push命令。

2.解決方案

2.1 技術(shù)可行性

2.1.1 如何實(shí)現(xiàn)

其實(shí)當(dāng)我們創(chuàng)建了一個(gè)Git的本地倉(cāng)庫(kù)后,項(xiàng)目的根目錄下看到一個(gè).git文件夾,在文件夾下的hooks目錄下有很多的.sample 為后綴的文件,

如下所示:

這些文件就是我們要改造的腳本,這個(gè)以.sample后綴結(jié)束的腳本文件是不會(huì)執(zhí)行的,如果需要執(zhí)行,我們需要去掉.sample后綴。

我們要實(shí)現(xiàn)的功能是定義Git提交模板和校驗(yàn)?zāi)0宓恼_性。

所以我們可以參考prepare-commit-msg.sample(提交模板)和commit-msg.sample(驗(yàn)證模板)完成我們的功能,修改完這個(gè)模板后我們就可以使用模板了,當(dāng)我們需要使用命令git commit 提交代碼時(shí),在出現(xiàn)的提交信息編輯器中會(huì)出現(xiàn)我們?cè)?code>prepare-commit-msg腳本中定義好的模板,我們填寫(xiě)完模板后保存模板,這時(shí)會(huì)使用commit-msg腳本對(duì)模板做校驗(yàn)。這樣的話(huà)我們的本地提交代碼就能使用我們定義好的模板了。

2.1.2 如何同步配置到項(xiàng)目中其他開(kāi)發(fā)者

現(xiàn)在還有一個(gè)問(wèn)題,就是這些配置都是在我們的本地,項(xiàng)目中的其他開(kāi)發(fā)者并沒(méi)有這個(gè)環(huán)境,我們?nèi)绻屗麄內(nèi)ヅ渲蔑@然不合適,因?yàn)橛械娜丝赡懿粫?huì)搭理你。所以我們需要做到讓開(kāi)發(fā)者無(wú)感知的就裝上了我們的環(huán)境,原理其實(shí)就是我們將模板提交到代碼倉(cāng)庫(kù)中,然后通過(guò)腳本將配置的模板拷貝到用戶(hù)的".git/hooks"目錄下,當(dāng)用戶(hù)觸發(fā)某個(gè)操作時(shí),就執(zhí)行腳本。本文我們以Android項(xiàng)目為例子,使用Gradle腳本,當(dāng)用戶(hù)執(zhí)行構(gòu)建操作的時(shí)候,我們執(zhí)行配置提交模板的腳本

2.2 實(shí)現(xiàn)方案

2.2.1 提交模板的腳本示例

.git/hooks目錄下,復(fù)制prepare-commit-msg.sample文件,重命名為prepare-commit-msg(注意這里沒(méi)有“.sample后綴名”),我們定義一個(gè)模板:

  • 項(xiàng)目名稱(chēng): [MountTai] 部門(mén)名稱(chēng): [] 禪道BUGID: [無(wú)]
  • 原因分析: {}
  • 解決方案: {}

prepare-commit-msg:(腳本是用perl語(yǔ)言和shell語(yǔ)言搭配寫(xiě)的,比較簡(jiǎn)單就不細(xì)講了),邏輯就是在開(kāi)發(fā)者進(jìn)入編輯器之前,往編輯器寫(xiě)入我們的模板。

這樣編輯器打開(kāi)后顯示的就是我們寫(xiě)的模板啦。

#!/bin/sh
COMMIT_MSG_FILE=$1
COMMIT_SOURCE=$2
SHA1=$3
case "$2,$3" in
 merge,)
  /usr/bin/perl -i.bak -ne 's/^/# /, s/^# #/#/ if /^Conflicts/ .. /#/; print' "$1" ;;
 ,|template,)
  /usr/bin/perl -i.bak -pe 'print "項(xiàng)目名稱(chēng): [MountTai] 部門(mén)名稱(chēng): [] 禪道BUGID: [無(wú)]\n
  #部門(mén)名稱(chēng): Android開(kāi)發(fā)部 / 三維軟件部 \n\n原因分析: {}\n解決方案: {}\n" if /^#/ && $first++ == 0' "$1" ;;
 *) ;;
esac

這個(gè)文件編寫(xiě)好后,直接放到.git/hooks目錄下,然后我們執(zhí)行git commit 命令后就會(huì)出現(xiàn)下中的模板

[]

提交編輯界面:這里需要重點(diǎn)注意下,如上所示,在編輯器的最上面會(huì)有一個(gè)空格,這個(gè)空格需要我們手動(dòng)刪除,然后再填寫(xiě)我們的提交信息。

若是無(wú)法編輯,請(qǐng)將輸入法切換為英文,按下鍵盤(pán)的i鍵,進(jìn)入編輯模式,要保存的時(shí)候,切換輸入法到英文,然后按下esc鍵,可以按下 shift+zz 組合鍵直接保存,或者按下shift + : 進(jìn)入指令模式,再輸入wq,回車(chē)就行了,放棄則輸入q!

刪除空格后,第一行會(huì)顯示黃色,如下:

[]

2.2.2 校驗(yàn)?zāi)0迨纠?/strong>

復(fù)制.git/hooks下的commit-msg.sample文件,重命名為commit-msg,然后編寫(xiě)模板校驗(yàn)規(guī)則,使用正則表達(dá)式驗(yàn)證開(kāi)發(fā)者提交的代碼信息。

下面的邏輯就是獲取提交的信息后,使用正則表達(dá)式去匹配。

成功的話(huà)就可以繼續(xù)提交,否則的話(huà)提示用戶(hù)消息提交格式不合法,重新編輯提交

commit_msg=`cat $1`
msg_re="^(項(xiàng)目名稱(chēng)|部門(mén)名稱(chēng)|禪道BUGID|原因分析|解決方案)(\(.+\))?: .{1,100}"

if [[ ! $commit_msg =~ $msg_re ]]
then
   echo -e "不合法的 commit 消息提交格式,請(qǐng)使用正確的格式:\n
   詳情請(qǐng)查看 git commit 提交規(guī)范:https://t3hx1u77li.feishu.cn/docx/CJr7d7aHJofPcYxOA1NcISVBn0d"
   
   # 異常退出
   exit 1 
fi

提交成功會(huì)展示:

[]

失敗會(huì)顯示

[]

標(biāo)出的部分,就是提交規(guī)范文檔,讓開(kāi)發(fā)者可以在失敗的時(shí)候通過(guò)這個(gè)文檔查看提交規(guī)范。

2.2.3 配置同步到項(xiàng)目的其他開(kāi)發(fā)者腳本示例

(1)本地配置好了后,我們就可以把prepare-commit-msg和commit-msg兩個(gè)腳本放到你的項(xiàng)目根目錄下

[]

(2)創(chuàng)建一個(gè)gradle腳本,做環(huán)境拷貝工作

[]

Git配置提交模板和校驗(yàn)?zāi)0宓膅radle腳本示例:

def useGitTemplate = false

project.afterEvaluate {
    if(useGitTemplate){
        preBuild.dependsOn('resetGitHookConfig')
    } else {
        println("exec tasks")
        preBuild.dependsOn('prepareCommitMsgConfig')
    }
}

task prepareCommitMsgConfig(type:Copy){
    from(getCommitMsgConfigFile().toString())
    into(getGitHookDir().toString())

    File file = new File(getGitHookDir())
    println("GitHookDir: " + getGitHookDir() + " ,permission: " + file.exists() +
            " ,readable: " + file.canRead() + " ,writable: " + file.canWrite())

    into(getGitHookDir().toString())
    from(getPrePareCommitMsgConfigFile().toString())
}

task resetGitHookConfig{
    doFirst {
        File commitMsgFile = getGitHookFile('commit-msg')
        if(commitMsgFile != null){
            commitMsgFile.delete()
        }

        File prepareCommitMsgFile = getGitHookFile('prepare-commit-msg')
        if(commitMsgFile != null){
            prepareCommitMsgFile.delete()
        }
    }
}

def getGitHookFile(fileName){
    def dirPath = getGitHookDir()
    println("getGitHookFile:dirPath: " + dirPath)
    if(dirPath != null && dirPath.length() > 0){
        def file = new File(dirPath, fileName)
        println("getGitHookFile: file path: " + file.absolutePath)
        if(file.exists()){
            return file
        }
    }
    return null
}

def getCommitMsgConfigFile(){
    File configFile = new File(project.rootDir,"git-hook/commit-msg")
    println("getCommitMsgConfigFile: configFile: " + configFile.absolutePath
    + " ,isExist: " + configFile.exists())
    if (configFile.exists()){
        return configFile.absolutePath
    }
    return null
}

def getPrePareCommitMsgConfigFile(){
    File configFile = new File(project.rootDir,"git-hook/prepare-commit-msg")
    println("getPrePareCommitMsgConfigFile: prepareConfigFile: " + configFile.absolutePath
    + " ,isExist: " + configFile.exists())
    if (configFile.exists()){
        return configFile.absolutePath
    }
    return null
}

def getGitHookDir() {
    File gitHookDir = new File(project.rootDir,".git/hooks")

    if (!gitHookDir.exists()) {
        println("Your project can't find .git directory in the ${project.rootDir.absolutePath}," +
                " please ensure it have been tracked by git VCS!")
        return null
    }

    return gitHookDir.absolutePath
}

腳本的意思就是當(dāng)我們運(yùn)行Android的構(gòu)建時(shí),就會(huì)執(zhí)行我們的這個(gè)腳本,把項(xiàng)目中的prepare-commit-msgcommit-msg腳本拷貝到開(kāi)發(fā)者的.git/hooks目錄下,然后開(kāi)發(fā)者就可以使用提交模板和驗(yàn)證功能了

提交代碼的時(shí)候若是使用形界面,可以把模板復(fù)制到界面中提交

[]

Git 模板改造完后,我們的提交記錄就會(huì)變得很規(guī)整了

[]

3.總結(jié)

Git Hook技術(shù)可以用來(lái)實(shí)現(xiàn)很多功能,比如在push操作之前想做一些其他操作,和Java的hook技術(shù)差不多,都是希望執(zhí)行某個(gè)操作之前或者之后先執(zhí)行我們定義的操作,使用這個(gè)技術(shù)可以做代碼的規(guī)范驗(yàn)證,提交模板的定義,模板的校驗(yàn)等功能,更多的功能后面用到的時(shí)候再做分享。

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

最新評(píng)論