solstice333 solstice333 - 2 months ago 17
Git Question

Git server-side hooks sometimes do not execute on the server side?

I understand that the script is ran on the remote repo, but which context does the script execute in? Does it use the resources of the client machine or the resources of the server machine? Or does it change depending on how the client repo communicates with the remote repo. I can't seem to find this information officially documented anywhere.

Edit:

I should've probably formulated my question differently. Anyway, I just ran into this:

http://superuser.com/questions/974337/when-i-run-a-git-hook-in-a-repo-on-a-network-share-which-binaries-are-used

which mentions that "If it’s a regular (SMB/CIFS) network share, it’s executed on the client." When doing

git remote -v
from within the local repo it shows the local protocol (file://) mapped to origin, and pushing to the remote on the network share ends up using the Perl on my client, instead of the Perl on the server, verified with
perl --version
. So what I really wanted to ask is given this information, how can this be if they're "server-side" hooks? Shouldn't they ALWAYS run on the server regardless? This is on Windows btw.

Answer

I now understand where this particular bit of confusion comes from. Obviously "server side" hooks run on the server—but if you run git push to a remote whose URL is file://... (or just a path like /some/path/to/repo), and in the various server-side hooks, have the server print its host name, or software version, or whatever, you will find that those are your own machine's software version, etc.

The trick here is that when you are dealing with a local path, your Git acts as both client and server, talking to itself. This is true even if your local file system is network-based, as long as Git itself sees it as local. Hence for NFS, or CIFS/Samba, or (if you use such things) an Andrew File System mount or a Plan9 mount or FUSE or whatever, as long as Git thinks it's just a regular old file on your own machine, Git does all the server work itself, so these are still local.

(In fact, if you run ps on a Unix/Linux system, you'll see that your client has forked a git receive-pack process:

remote:   PID  PPID TT  STAT      TIME COMMAND
[snip]
remote: 28494 27867  4  S+     0:00.06 git push me testbr
remote: 28495 28494  4  S+     0:00.07 git-receive-pack /home/torek/tmp/t
remote: 28499 28495  4  S+     0:00.01 /bin/sh hooks/pre-receive
remote: 28500 28499  4  R+     0:00.00 ps -O ppid

so in effect, process 28494 is the "client" here, while process 28495 is the "server". Both are, of course, on one single host / VM / whatever. I set up remote me to point to file:///home/torek/tmp/t here.)