1. 程式人生 > 實用技巧 >【熟能生巧】每日一鍵更新所有Git專案

【熟能生巧】每日一鍵更新所有Git專案

問題

我司的專案都是模組化的,一個大專案下面有很多小專案。某一個開發階段,開發人員可能要同時修改5-6個專案。

所以,每天早上到辦公室的第一件事,我會開啟SourceTree(一個管理Git程式碼的軟體,提供圖形化介面),把每個正在開發的專案更新一下(點一下Pull那個按鈕)。
如果有還沒來得及 commit 的程式碼,還要先做備份(這就比較複雜了,需要使用 stash 功能)。

這個過程,一般要花5-10分鐘,甚至更久,如果 Git 或者 SourceTree 很慢的話。這一件十分瑣碎的工作,需要優化。

解決思路

思路很簡單,Git更新專案用到的核心命令是git fetch / git pull

。所以,可以結合Shell指令碼將這個過程自動化。

最終實現一鍵更新所有專案。

專案設定

開發使用的是Windows系統,專案路徑如下:

C:/codebase/Project_A
C:/codebase/Project_B
C:/codebase/Project_C

存放指令碼路徑如下:

C:/scripts/git_update.sh

程式碼

第一部分:讀取引數

接受的引數為:專案名 和 branch名

#
# PART 1 - Prep
#
helpFunction()
{
   echo ""
   echo "Usage: $0 -p param_project -b param_branch" 
   echo -e "\t-p, param_project"
   echo -e "\t-b, param_branch"
   exit 1 # Exit script after printing help
}

while getopts "p:b:" opt
do
   case "$opt" in
      p ) param_project="$OPTARG" ;;
      b ) param_branch="$OPTARG" ;;
      ? ) echo "parameter not right"; helpFunction ;; # Print helpFunction in case parameter is non-existent
   esac
done

## Print helpFunction in case parameters are empty
if [ -z "$param_project" ] || [ -z "$param_branch" ]
then
   echo "Some or all of the parameters are empty";
   helpFunction
fi

# Begin script in case all parameters are correct
echo "[INPUT] param_project: $param_project"
echo "[INPUT] param_branch: $param_branch"

第二部分:處理

處理邏輯是這樣的:先將任何change備份到一個檔案,然後discard;然後pull;最後再將change重新apply回去。

#
# PART 2 - Process
#

# Parse input
DIR_PATH=/c/codebase/
branch=$param_branch
timestamp=`date "+%Y_%m_%d_%H_%M_%S"`

# git backup changes
gitBackupFunction()
{
	cd $DIR_PATH/$project
	echo "[INFO] current dir is: $PWD"; 

	echo "[GIT] checkout $branch" 
	git checkout $branch
	
	echo "[GIT] save changes to diff_${branch}_${timestamp}" 
	git diff > diff_${branch}_${timestamp}
	
	echo "[GIT] reset branch" 
	git reset --hard
}

# git pull
gitUpdateFunciton()
{
	echo "[GIT] fetch $branch"
	git -c diff.mnemonicprefix=false -c core.quotepath=false fetch origin

	echo "[GIT] pull $branch"
	git -c diff.mnemonicprefix=false -c core.quotepath=false pull --rebase origin $branch
}

# git reapply changes
gitReapplyFunction()
{
	echo "[GIT] reapply changes from diff_${branch}_${timestamp}" 
	git apply diff_${branch}_${timestamp}
	
	echo "[GIT] remove temp changes" 
	rm diff_${branch}_${timestamp}
}

# Loop each project
for project in $param_project
do
	echo -e "\n##### START TO PROCESS $project #####"
	gitBackupFunction
	gitUpdateFunciton
	gitReapplyFunction
	echo -e "##### FINISH TO PROCESS $project #####\n"
done

有一點需要說明的是,程式碼備份+還原,這裡使用了git diff,而沒有使用git stash。原因有二:

  • git diff執行起來更快,git stash經常會卡住一會。
  • git stash刪除起來比較麻煩,它需要指定 stash 佇列中的元素位置,而不是名稱。
git stash push -m stash_name_with_timestamp
git stash apply stash^{/stash_name_with_timestamp}
# note: can't delete with stash name, have to go with sequence number using git stash drop...

執行

在Windows任意目錄下,開啟Git Bash,輸入如下命令:

/c/scripts/git_update.sh -p "Project_A Project_B Project_C" -b dev_branch_20201010

這句話的意思是,更新Project A,B,C這三個專案的dev_branch_20201010分支。

定時執行

在Windows下面可以設定定時執行任務。這裡就不贅述了。

實際工作中,因為沒有計算機的管理員許可權,所以我選擇了另一種半自動的方法:將所有需要每天執行的指令碼命令都放到一個檔案。然後早上到了公司就執行一下這個檔案,然後再去接水/泡咖啡啦。