最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

使用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)。這樣的話我們的本地提交代碼就能使用我們定義好的模板了。

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ò)腳本將配置的模板拷貝到用戶的".git/hooks"目錄下,當(dāng)用戶觸發(fā)某個(gè)操作時(shí),就執(zhí)行腳本。本文我們以Android項(xiàng)目為例子,使用Gradle腳本,當(dāng)用戶執(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)目名稱: [MountTai] 部門名稱: [] 禪道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)目名稱: [MountTai] 部門名稱: [] 禪道BUGID: [無(wú)]\n
  #部門名稱: 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)將輸入法切換為英文,按下鍵盤的i鍵,進(jìn)入編輯模式,要保存的時(shí)候,切換輸入法到英文,然后按下esc鍵,可以按下 shift+zz 組合鍵直接保存,或者按下shift + : 進(jìn)入指令模式,再輸入wq,回車就行了,放棄則輸入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á)式去匹配。

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

commit_msg=`cat $1`
msg_re="^(項(xià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)文章

  • 值得收藏的9個(gè)提高代碼運(yùn)行效率的小技巧(推薦)

    值得收藏的9個(gè)提高代碼運(yùn)行效率的小技巧(推薦)

    本文給大家分享9個(gè)提高代碼運(yùn)行效率的小技巧(推薦),本文通過(guò)示例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧
    2021-04-04
  • 寫(xiě)給正在讀計(jì)算機(jī)專業(yè)的同學(xué) 該如何學(xué)習(xí)

    寫(xiě)給正在讀計(jì)算機(jī)專業(yè)的同學(xué) 該如何學(xué)習(xí)

    現(xiàn)在IT新技術(shù)日新月異。就常用編程語(yǔ)言而言,有c/c++、匯編、java,c#、Python等;操作系統(tǒng)平臺(tái)有unix/linux,windows系列
    2009-11-11
  • Git推送代碼的7種高效方式

    Git推送代碼的7種高效方式

    在 Git 中,推送代碼(即將本地提交推送到遠(yuǎn)程倉(cāng)庫(kù))有多種方式,每種方式適用于不同的協(xié)作場(chǎng)景和需求,以下是幾種常見(jiàn)的推送代碼的方式、結(jié)合完整示例說(shuō)明,并以表格形式總結(jié)對(duì)比,需要的朋友可以參考下
    2025-08-08
  • git push常見(jiàn)問(wèn)題及解決方案

    git push常見(jiàn)問(wèn)題及解決方案

    本文主要介紹了git push常見(jiàn)問(wèn)題及解決方案,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2026-02-02
  • 如何解決git revert后再次merge代碼丟失問(wèn)題

    如何解決git revert后再次merge代碼丟失問(wèn)題

    這篇文章主要介紹了如何解決git revert后再次merge代碼丟失問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2025-04-04
  • POST與GET方法的區(qū)別簡(jiǎn)要分析

    POST與GET方法的區(qū)別簡(jiǎn)要分析

    原理介紹:理論上說(shuō),GET是從服務(wù)器上請(qǐng)求數(shù)據(jù),POST是發(fā)送數(shù)據(jù)到服務(wù)器。事實(shí)上,GET方法是把數(shù)據(jù)參數(shù)隊(duì)列(query string)加到一個(gè)URL上,值和表單是一一對(duì)應(yīng)的。
    2008-10-10
  • 深入剖析從輸入U(xiǎn)RL到頁(yè)面顯示過(guò)程原理

    深入剖析從輸入U(xiǎn)RL到頁(yè)面顯示過(guò)程原理

    這篇文章主要為大家深入剖析了從輸入U(xiǎn)RL到頁(yè)面顯示這中間發(fā)生的過(guò)程原理,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-04-04
  • VSCode開(kāi)發(fā)必備插件推薦(墻裂推薦!)

    VSCode開(kāi)發(fā)必備插件推薦(墻裂推薦!)

    vscode是微軟開(kāi)發(fā)的的一款代碼編輯器,就如官網(wǎng)上說(shuō)的一樣,vscode重新定義(redefined)了代碼編輯器,下面這篇文章主要給大家介紹了關(guān)于VSCode必備插件推薦的相關(guān)資料,需要的朋友可以參考下
    2022-11-11
  • UTF-8 GBK UTF8 GB2312 之間的區(qū)別和關(guān)系介紹

    UTF-8 GBK UTF8 GB2312 之間的區(qū)別和關(guān)系介紹

    UTF-8:Unicode TransformationFormat-8bit,允許含BOM,但通常不含BOM。是用以解決國(guó)際上字符的一種多字節(jié)編碼,它對(duì)英文使用8位(即一個(gè)字節(jié)),中文使用24為(三個(gè)字節(jié))來(lái)編碼
    2011-12-12
  • git rebase 成功之后撤銷的操作方法

    git rebase 成功之后撤銷的操作方法

    這篇文章主要介紹了git rebase 成功之后如何撤銷,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-07-07

最新評(píng)論

麻城市| 喀什市| 额敏县| 中阳县| 杨浦区| 高安市| 孟津县| 盐津县| 邯郸县| 武穴市| 梁山县| 桃园县| 陵水| 香港| 盐城市| 临朐县| 昌邑市| 福贡县| 宝兴县| 南岸区| 循化| 彩票| 日土县| 南澳县| 凤山市| 通化县| 马尔康县| 乌拉特后旗| 静海县| 井陉县| 秭归县| 长岭县| 安新县| 尉犁县| 冀州市| 波密县| 涞水县| 福州市| 资源县| 万安县| 曲靖市|