简体   繁体   中英

Write GIT pre-commit hook in java?

I need to write a Git pre commit hook in Java, which would check if the code commited by the developer is formatted according to a specific eclipse code formatter before actually commiting it, otherwise reject it from commiting. Is it possible to write the pre commit hook in Java?

The idea is to call a script which in turns call your java program (checking the format).

You can see here an example written in python , which calls 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)

This other example calls directly ant , in order to execute an ant script (which in turns call a Java JUnit test suite)

#!/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

As of Java 11, you can now run un-compiled main class files using the java command.

$ java Hook.java

If you are using a Unix based operating system (MacOS or Linux for example), you can strip off the .java and add a shebang to the top line like so:

#!/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);
    }
} 

then you can simply execute it the same way you would with any other script file.

$ ./Hook

If you rename the file pre-commit , and then move it into your .git/hooks directory, you now have a working Java Git Hook.

Note: You may be able to get this to work on Windows using Cygwin or Git Bash or similar terminal emulators. However, shebangs do not handle spaces well. I tested that this works by moving a copy of java into a directory without spaces and it works fine.

Yes, you can write a git hook in java.

Attempted solution

I attempted Rudi's solution for my commit-msg hook:

commit-msg file

#!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);
    }
}

But I received this error message and had difficulty troubleshooting

$ 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

Solution that worked for me

Then I found a source that outlines another way.

https://dev.to/awwsmm/eliminate-unnecessary-builds-with-git-hooks-in-bash-java-and-scala-517n#writing-a-git-hook-in-java

The commit-msg hook looks like this

#!bin/sh
DIR=$(dirname "$0")
exec java $DIR/commit-msg.java "$@"

This saves the current directory (.git/hooks) of the git commit command to a variable to help build the path to the java file. Then the shell executes the java command with the path to the java file and an argument holding the path to the COMMIT_EDITMSG file.

Then you can move the Hook class defined above into its own java file (in this case commit-msg.java) and put it in the.git/hooks directory.

Now you can run git commit -m "Message" and the commit-msg hook will block the commit

You can write the hook in any language that can be understood by the shell, with the properly configured interpreter (bash, python, perl) etc.

But, why not write your java code formatter in java, and invoke it from the pre-commit hook.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM