Git预提交钩子中Spring JavaFormat自动格式化修改未被提交的问题求助
大家好,我遇到了个Git预提交钩子的棘手问题,想请教下各位大佬:
我正在写一个Git预提交钩子脚本,想用Spring JavaFormat自动给代码做格式化,脚本内容是这样的:
#!/bin/sh ./mvnw spring-javaformat:apply
但现在出现了很奇怪的情况:当我提交未格式化的文件时,
- 控制台显示命令执行成功了
- 目标文件确实提交成功了,但完全没带上格式化的修改
- 格式化的改动确实应用到了本地文件里,但就是没被包含在这次提交中
我试了好几种方法都没解决,想问问这到底是为啥,有没有靠谱的解决办法?
对了,我在pom.xml里是这么配置Spring JavaFormat插件的:
<plugin> <groupId>io.spring.javaformat</groupId> <artifactId>spring-javaformat-maven-plugin</artifactId> <version>0.0.40</version> <executions> <execution> <phase>validate</phase> <inherited>true</inherited> <goals> <goal>apply</goal> </goals> </execution> </executions> </plugin>
我的系统环境是:
- Maven v3.9.5(用了Maven wrapper)
- Spring Boot v3.2
- Spring JavaFormat v0.0.40
问题原因分析
其实核心问题特别简单:Git预提交钩子运行时,是基于你已经暂存的文件快照来执行的。当你运行spring-javaformat:apply时,它修改的是本地工作区的文件,但这些新修改并没有被加入到Git的暂存区中,所以最终提交的还是你最初暂存的那个未格式化版本。
解决办法
你需要在钩子脚本里,把格式化后的文件重新加入到暂存区,这样提交的时候就能包含这些改动了。修改后的钩子脚本如下:
#!/bin/sh # 执行格式化命令 ./mvnw spring-javaformat:apply # 将被格式化修改的文件重新加入暂存区 git add .
不过这里有个小细节要注意:如果你只想提交当前原本暂存的文件(不想意外把其他未暂存的改动也提交),可以用git diff --name-only --cached获取之前暂存的文件列表,只把这些文件重新add进去,优化后的脚本可以这样写:
#!/bin/sh # 获取当前暂存的文件列表 STAGED_FILES=$(git diff --name-only --cached) # 执行格式化命令 ./mvnw spring-javaformat:apply # 只重新暂存之前的那些文件 echo "$STAGED_FILES" | xargs git add
额外提示
另外,你在pom.xml里把插件绑定到了validate阶段,这个配置本身没问题,但预提交钩子是直接调用了spring-javaformat:apply目标,所以这个绑定的阶段主要是在Maven构建时生效,和钩子脚本的执行不冲突。
如果还是有问题,可以检查下钩子脚本的权限是否正确(需要给脚本添加执行权限:chmod +x .git/hooks/pre-commit),确保Git能正常执行这个脚本。
备注:内容来源于stack exchange,提问作者Firas RG

