这个想法是调用一个脚本,然后再调用你的Java程序(检查格式)。
你可以在这里看到一个用Python编写的示例,该示例调用了Java。
try:
# call checkstyle and print output
print call(['java', '-jar', checkstyle, '-c', checkstyle_config, '-r', tempdir])
except subprocess.CalledProcessError, ex:
print ex.output # print checkstyle messages
exit(1)
finally:
# remove temporary directory
shutil.rmtree(tempdir)
这个另一个示例直接调用ant
,以执行一个ant脚本(该脚本又调用Java JUnit测试套件)。
#!/bin/sh
# Run the test suite.
# It will exit with 0 if it everything compiled and tested fine.
ant test
if [ $? -eq 0 ]; then
exit 0
else
echo "Building your project or running the tests failed."
echo "Aborting the commit. Run with --no-verify to ignore."
exit 1
fi
从Java 11开始,您现在可以使用java命令运行未编译的主类文件。
$ java Hook.java
如果您使用的是基于Unix的操作系统(例如MacOS或Linux),您可以去掉 .java
扩展名并在顶行添加shebang,如下所示:
#!/your/path/to/bin/java --source 11
public class Hook {
public static void main(String[] args) {
System.out.println("No committing please.");
System.exit(1);
}
}
那么你可以像处理其他脚本文件一样简单地执行它。
$ ./Hook
pre-commit
重命名,然后将其移动到您的 .git/hooks
目录中,您现在拥有一个可用的 Java Git Hook。
注意:您可以尝试使用 Cygwin 或 Git Bash 等终端模拟器在 Windows 上运行此操作。但是,shebangs 不会处理空格问题。我通过将 Java 的副本移动到没有空格的目录中进行了测试,测试结果表明可以正常工作。
是的,您可以使用Java编写git钩子。
我尝试了Rudi提供的解决方案来编写我的commit-msg钩子:
commit-msg文件
#!C:/Progra~1/Java/jdk-17.0.1/bin/java.exe --source 17
#Using Progra~1 to represent "Program Files" as escaping the space
#or surrounding the path in double quotes didn't work for me.
public class Hook {
public static void main(String[] args) {
System.out.println("No committing please.");
System.exit(1);
}
}
但是我收到了这个错误信息,并且在排查问题时遇到了困难。
$ git commit -m "Message"
Error: Could not find or load main class .git.hooks.commit-msg
Caused by: java.lang.ClassNotFoundException: /git/hooks/commit-msg
后来我找到了一份提供另一种方式的资源。
commit-msg 钩子看起来像这样
#!bin/sh
DIR=$(dirname "$0")
exec java $DIR/commit-msg.java "$@"
该命令将当前目录(.git/hooks)保存到一个变量中,以帮助构建到java文件的路径。然后shell使用java文件的路径和一个参数(包含COMMIT_EDITMSG文件的路径)执行java命令。
接下来,您可以将上面定义的Hook类移动到自己的java文件中(在本例中为commit-msg.java),并将其放置在.git/hooks目录中。
现在,您可以运行git commit -m "Message",commit-msg钩子将阻止提交。
exec
会阻止后续的命令(例如在提交更改之前需要执行 git add
命令)。 - Ahmed Ashour您可以使用任何能够被shell理解的语言编写钩子,例如已经配置好的解释器(bash、python、perl)等。
但是,为什么不用Java编写您的代码格式化程序,并从预提交钩子中调用它呢?