通过失败的预提交挂钩保留已提交的文件

Retain committed files through failed pre-commit hook

我有一个预提交挂钩,可以像这样运行一些 linting:

./gradlew app:ktlint --daemon

status=$?

if [ "$status" = 0 ]
then
    echo "${green}Linting found no problems.${reset}"
    exit 0
else
    echo 1>&2 "${red}Linting found issues.${reset}"
    echo "${yellow}Attempting to fix automatically...${reset}"
    ./gradlew app:ktlintFormat --daemon
    if [ $? = 0 ]
    then
        echo "${green}Fixed all issues automatically. Committing automagically...! :)${reset}"
        git add .
        git commit -m "Automatic commit of linted files" --no-verify
        exit 0
    else
        echo "${red}Could not fix all issues automatically, please review. :( ${reset}"
        exit 1
    fi  
fi

这里的问题是,如果 ktlint 任务失败,但自动格式设法解决了所有问题,我无法仅重新添加初始提交中包含的文件。

也许最好用一个例子来解释:

提前致谢!

在提交通过之前在代码库上预提交挂钩 运行。我建议在自动修复完成后删除 git add/commit 行,以便脚本以零(成功)状态退出。

您失去了向消息添加内容的能力,但预提交将完全按照它应该的方式运行。

与您的示例进行比较:

  • 3 个文件,A、B、C
  • 提交 A 和 B,但不提交 C
  • ktlint 由于格式化而导致提交失败
  • ktlintFormat 设法解决了问题
  • 提交继续,A 和 B。

✌️

解决方案是跟踪预先提交了哪些文件,然后在自动 lint 格式化发生后手动添加这些文件。

echo "${yellow}Running linting...${reset}"

#store the result of the commit in a variable and split into array items with newline
committedFiles=$(git diff --name-only --cached)
files=$(echo $committedFiles | tr ";" "\n")

[...]

#after ktlintFormat runs and succeeds
echo "${green}Fixed all issues automatically. Committing..! :)${reset}"

#replay items in the commits array and add only those files
for file in $files
do
    git add $file
done
git commit -m "Automatic commit of linted files" --no-verify
exit 0

[...]