• 未分類
  • 2

[Git-Hook] How prevent merge action !? pre-merge Hook!?

週末收到個需求,希望協助解決個 Git 流程上問題

問題是這樣

Integration分支是 master

且有個  Topic分支 Enhancement, 就如他的名稱,這分支會有許多人merge 功能進去 

這個 Enhancement 是暫時測試許多功能的分支

只將自己的功能 merge 到 master ,然後push 是標準流程

但是當有人操作錯誤將 Enhancement merge 到自己的分支再合併到 master

或直接 merge  master

push 後就大家飛上天啦 …… XD

好長的前言

釐清問題後

重點為 任何分支不能 merge 到 Enhancement

 

但是 hook 沒有 per-merge 的這種事件 Orz

原因為

You can not prevent people effectivly from locally merging or commiting on any branch. The only really effective way to prevent people from merging/commiting in a branch is a server side hook.

不能在本地端禁止使用者操作(Merge) 分支,只能server端限制

http://stackoverflow.com/questions/27565663/how-would-i-use-pre-merge-hook-in-git?noredirect=1#comment43557913_27565663

但是在server 端才檢查實在太費時間(中間可能使用者又經過很次修改)

所以轉個想法為在 Post-merge (merge 完成後)時做檢查
若合併了指定 分支名稱建立備份分支
由於合併有兩種 merge / rebase 所以當觸發其中一種時會進行檢查
並且發現有備份分支後禁止 commit 跟 push (必須先手動解決此問題)

 

在.git 目錄下 hooks 資料夾下分別建立以下檔案 (osx / win 可用)

 

post-merge

#!/bin/sh
#----------------------------------------------------------
# 檢查是否合併了 Enhancement,建立備份分支
#----------------------------------------------------------
# * Author: 羊小咩 Lamb-Mei
# * Update : 2014/12/20
# * Description: 當合併了 Enhancement ,顯示警告跟建立備份用分支
#

echo $GIT_REFLOG_ACTION | grep -q "merge Enhancement" >> /dev/null;

if [ $? == 0 ]; then
#已經合併了不想要的分支
echo "Error 合併包含 Enhancement !!"
echo "請立即使用 reset 或 revert 解決此錯誤 !!"
#複製原始的狀態
git branch AP_ISSUE_HEAD_bak HEAD^1
git branch AP_ISSUE_Master_bak master^1
else
echo "check OK 合併檢查無誤!!!"
fi

 

 

pre-rebase

#!/bin/sh
#
#----------------------------------------------------------
# 禁止使用 Enhancement,進行 rebase
#----------------------------------------------------------
# * Author: 羊小咩 Lamb-Mei
# * Update : 2014/12/20
# * Description: 不允許 rebase onto Enhancement
#

echo $1 | grep -q "Enhancement" >> /dev/null;

if [ $? == 0 ]; then
#已經合併了不想要的分支
echo "Error 不能使用 rebase onto Enhancement !!"
exit 1;

else
exit 0;
fi

 

pre-commit

#!/bin/sh
#----------------------------------------------------------
# 檢查是否包含 AP_ISSUE* 的分支,禁止 commit
#----------------------------------------------------------
# * Author: 羊小咩 Lamb-Mei
# * Update : 2014/12/20
# * Description: 含有 AP_ISSUE* 的分支 禁止 commit (為了提早發現問題)
#

git branch | grep "AP_ISSUE" >> /dev/null;

if [ $? == 0 ]; then
echo "您分支合併了 Enhancement ,請先解決此問題,能才進行後續動作!!"
exit 1 ;
else
exit 0 ;
fi

pre-push

#!/bin/sh
#
#----------------------------------------------------------
# 檢查是否包含 AP_ISSUE* 的分支,禁止 Push
#----------------------------------------------------------
# * Author: 羊小咩 Lamb-Mei
# * Update : 2014/12/20
# * Description: 含有 AP_ISSUE* 的分支 禁止 Push
#

git branch | grep "AP_ISSUE" >> /dev/null;

if [ $? == 0 ]; then
echo "您分支合併了 Enhancement ,請先解決此問題,能才進行後續動作!!"
exit 1 ;
else
exit 0 ;
fi

 

後記

使用上會有一個缺點

由於 merge 動作進行不會觸發任何hook ,除非merge 選項有新commit 狀態

所以進行merge 是已經成功了,所以才在使用建立備份的分支當紀錄點,跟判斷

但rebase 可以在進行之前就先阻擋掉

以上是目前想到最佳的的解決方式

 

 

參考資料

How To Use Git Hooks To Automate Development and Deployment Tasks
https://www.digitalocean.com/community/tutorials/how-to-use-git-hooks-to-automate-development-and-deployment-tasks

 

 

 

Comments

comments

您可能也會喜歡…

2 個回應

  1. callmenp表示:

    prepare-commit-msg 也行吧?

    #!/bin/sh
    case “$2,$3” in
    merge,)
    grep “‘test'” $1;
    if [ $? ];then
    echo ‘#######################################’;
    echo ‘### 不要将test分支merge到任何分支!!!’;
    echo ‘### 这次冲动merge被钩子及时制止了,’;
    echo ‘### 现在需要用git reset –hard ORIG_HEAD来恢复一下代码。’;
    echo ‘#######################################’;
    exit 1;
    fi;;
    *) ;;
    esac

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *

這個網站採用 Akismet 服務減少垃圾留言。進一步瞭解 Akismet 如何處理網站訪客的留言資料