Git Hooks on Windows using batch

Started by
7 comments, last by ApochPiQ 11 years, 3 months ago
I'm currently attempting to construct a simple automated build server so that I can move towards a form of continual delivery on one of my projects. This involves an automated building system.

I use Git and I found this topic on hooks that allows Git to execute scripts based on events. The issue is that I'm using Windows ('$(GIT_DIR)\cmd' is on my path and I execute everything in the command line native to Windows) and I want to write the scripts in batch (rather than learning Bash or whatever).

However, I can't get any of the scripts to work. Surely they're automatically executed in the environment Git is being run in? I've only tried experiments like:

ECHO hello, world!

But nothing ever appears in the console. I've tried naming the hook 'post-commit' and 'post-commit.bat' but nothing ever happens when I make a commit.

I'm working off the assumption that I can use batch. My justification is based on the Git book on the website:

All the examples are written as shell scripts, with some Perl thrown in, but any properly named executable scripts will work fine — you can write them in Ruby or Python or what have you.

What am I doing wrong?

EDIT: Git spits out "error: cannot spawn .git/hooks/post-commit: No such file or directory" when I commit.
Advertisement

Not that I really like bumping a topic...

From what I understand you're wanting to have batch files execute based on git events such as post commit and pre commit?

The .git folder will be created when you initialize a git project. In the folder you'll have a folder called hooks. You will then see several files ending in .sample.

If you rename any of these files to strip the .sample off the end (so, for post-commit.sample you'd end up with post-commit) then git will see that you want to hook that particular event. Inside the file itself you can have your batch file execute by simply providing the path of the batch file.

I have a batch file called test.bat in .git/hooks/ and within post-commit I replaced ": nothing" with ./git/hooks/test.bat

My test.bat file merely contains "echo hurrah". Now whenever I do a commit in that particular project I see hurrah echoed in the console.

From the looks of things it seems that you'd have to set up hooks for every git project you're working with. However, it might be possible to set it up so the .git/hooks folder always has your batch files set up whenever you initialize a new git project.

Why don't you do a pooling based approach (I think that the majority of the CI servers, like Jenkins, are implemented this way) ? By using a pooling based approach, you could set a silence time, and only trigger a build when there wasn't any commit activity N seconds since the last commit.

Another thing to consider is that those hooks are meant to very fast operations. I don't know the internals of git, but a time consuming operation running on the commit's hook could lock the repository for the time of its execution.

try Hudson. It runs git and other scripts. It even sends emails with build status and stuff. Been using it since sometime now, and only got good words about it.

From what I understand you're wanting to have batch files execute based on git events such as post commit and pre commit?
You're absolutely right. Technically it was on the receive of information from a push but its the same procedure in a very broad sense.

I have a batch file called test.bat in .git/hooks/ and within post-commit I replaced ": nothing" with ./git/hooks/test.bat
I'm implying from this that it's not possible to write batch statements directly into the hook file like I was originally trying to do?

By using a pooling based approach, you could set a silence time, and only trigger a build when there wasn't any commit activity N seconds since the last commit.
I was kinda against this because its a waste. Not go on and sound like I'm worried about how my server uses every single processor cycle but I was concerned with the issue of build with nothing new to build.

Another thing to consider is that those hooks are meant to very fast operations. I don't know the internals of git, but a time consuming operation running on the commit's hook could lock the repository for the time of its execution.
I had read about blocks. I'm not concerned with the result successfully building at this stage (I was simply planning to have the log from MSBuild be remotely readable).

Failing that I was thinking about figuring out a method of running the build externally form the batch and just returning quickly (like making use of START without the wait command).

try Hudson. It runs git and other scripts. It even sends emails with build status and stuff.
Hm. I didn't really want to use a larger, external application for building. Really the whole point of the project is to learn stuff through Wikipedia, the Internet, and stumbling blindly around. I'm completely happy to reinvent the wheel on a small scale for my own education (obviously I'm not planning to write an entire integration system like Jenkins or Hudson).

[quote name='BinaryPhysics' timestamp='1357255596' post='5017295']
I was kinda against this because its a waste. Not go on and sound like I'm worried about how my server uses every single processor cycle but I was concerned with the issue of build with nothing new to build.
[/quote]

You don't need to build if nothing has changed. You could store the lastest build's hash and before building a new version compare its hash with the stored one, if they´re the same, you just skip building.

Cool that you're taking time and learning how the internals of the tools that you're using works, those "reinventing the wheel small scale projects" teach us so much

Okay, I'm being to become slightly frustrated. What am I doing wrong?
I took the original advise that was given to me and simply added the batch to the end of sample-script. That work with the exception that any batch style commands presented in the batch file cause errors.
I decided to go back and write straight to the hook. Nothing happened at all.
More research and I discovered a concept called a 'shebang' which dictates the program that the script is meant to run in. So I now have:

#! C:\System32\cmd

CALL "C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\vcvarsall.bat" amd64
MSBuild Project.sln

Which does... Nothing at all. I can see that the console interpretor is opened because the copyright information appears every time I commit but nothing is generated from the solution file. Simply calling 'MSBuild Project.sln' myself correctly builds an executable with no errors.
There isn't a massive amount of information on the Internet about this. Have I missed something incredibly obvious?

Shebangs are a Unix-land concept; I don't think they have any real bearing on Windows.

I would suggest trying a simple command-line program as your hook instead of a batch file. For instance, just create a simple C/C++/C#/whatever program that pops up a message box, or writes to a file, or whatever have you. Make sure your hooks are being executed correctly.

If that works, it's probably a quirk of the batch execution process that's going on. If you want a script-like interface, try PowerShell instead - it's a far superior command-line scripting environment than Batch, and has a lot fewer weird corners and shadowy edge cases. Otherwise, if you can accomplish what you want with a simple wrapper program, it may be worth just doing that.

Wielder of the Sacred Wands
[Work - ArenaNet] [Epoch Language] [Scribblings]

This topic is closed to new replies.

Advertisement