使用Git Hooks(Pre-Commit)实现代码提交的时候自动格式化代码

钩子文件在项目目录下

git 的钩子放在 git 项目下的 .git/hooks 目录。

$ ls -l .git/hooks

如果我们所有项目都需要一个通用的钩子,那么我们需要在所有的项目中都放置钩子文件。挨个复制显然不是一个可行的方案。

模板目录

我们可用模板目录来解决这个问题。

在 git init 或者 git clone时,如果指定有模板目录,会使用拷贝模板目录下的文件到 .git/ 目录下。

$ git init --template "path-to-template-dir"

$ git clone --template "path-to-template-dir"

好了,那么解决方案就是:把统一的钩子文件放到模板目录,然后在 git init / git clone 时候指定模板目录?

不行,这样还是太麻烦了。

模板目录写入全局配置

模板目录固定在一个地方,我们可以把模板目录写入全局配置。

# 定义模板目录,模板目录下的钩子目录
$ template_dir=$HOME/.git-templates

$ tempalte_hooks_dir=$template_dir/hooks

# 拷贝全局钩子文件目录到模板目录下
$ mkdir -p $template_dir

$ cp -rf $root_dir/sample/git-template/hooks/ $template_dir/

# 修改模板目录下钩子目录权限
$ chmod -R a+x $tempalte_hooks_dir

# 设置全局模板目录
$ git config --global init.templatedir $template_dir

在 git init 或者 git clone 时,会自动拷贝钩子文件到项目的钩子目录。 已有项目,执行 git init 重新初始化项目即可。

代码提交时候,自动格式化的参考代码如下:

#!/bin/bash

# https://stackoverflow.com/questions/12881975/git-pre-commit-hook-failing-in-github-for-mac-works-on-command-line
export PATH=$PATH:/usr/local/bin:/usr/local/sbin

STYLE=$(git config --get hooks.clangformat.style)
if [ -n "${STYLE}" ] ; then
  STYLEARG="-style=${STYLE}"
else
  # try source root dir
  STYLE=$(git rev-parse --show-toplevel)/.clang-format
  if [ -n "${STYLE}" ] ; then
    STYLEARG="-style=file"
  else
    STYLEARG=""
  fi
fi

format_file() {
  file="${1}"
  clang-format -i ${STYLEARG} ${1}
  git add ${1}
}

case "${1}" in
  --about )
    echo "Runs clang-format on source files"
    ;;
  * )
    for file in `git diff-index --cached --name-only HEAD` ; do
      format_file "${file}"
    done
    ;;
esac

使用的时候,简单的拷贝到.git/hooks 目录下,并重新命名为pre-commit。然后执行:

# macOS Mojave (10.14.3)
$ brew install clang-format

$ chmod +x .git/hooks/pre-commit

这样,每次提交代码的时候,都会自动格式化代码了。

参考链接


发布者

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注