且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

Git - 后接收挂钩不能在远程Windows服务器上工作

更新时间:2022-11-23 12:40:42

你将不得不修补git来完成这项工作。 builtin / receive-pack.c中的检查用于访问(路径,X_OK)。在msysgit中,这转向了mingw_access,它抛弃了X_OK,因为它在Windows上是不受支持的。



在windows上,我们没有标志来指定文件是可执行文件。系统经常对此进行一些模拟。例如,tcl将在PATHEXT环境变量中查找任何扩展来决定文件是否可执行。我们不能这样做,因为钩子名称是硬编码的,没有任何扩展名。



相反,我建议更改访问测试以检查文件是否存在,然后调用 execv 在路径上。这个(在compat / mingw.c中)的mingw版本查找脚本文件,并将读取shbang行并启动一个合适的解释器(sh,perl等)。因此,修改 builtin / receive-pack.c:run_update_hook 应该让你为你工作。目前钩子运行使用 start_command ,我认为应该调用execv给你。



总之,访问测试,它可能会工作。


I'm trying to get a git post-receive hook working on Windows.

I'm using Git 1.7.9 (Msysgit) and have a repo locally and a bare repo on a remote server. I can fetch, commit, push etc. I've set up a post-receive hook that should checkout the files into a working folder (part of the deployment process) but it doesn't seem to work.

Here's what I do:

  1. Change a file, stage and commit it
  2. Push to remote server - successfully
  3. Expect to see the echo - don't see the echo
  4. Check working folder on server - latest files are not there
  5. Log onto the server and run the hook script manually - latest files are checkout out into the working folder.

I changed the hook so it does nothing except echo a message and I've read that I should see this in my console after pushing. But this is not being displayed so I can only assume the hook is not being fired off.

I'm pushing over HTTP with git dot aspx on the server handling the request and pusing via the gui locally. After that failed I tried Bonobo and the hook doesn't work when pushing via the gui or a bash console.

I'm assuming someone has this working somewhere but after two days of searching all I have found are solutions that don't help or people with the same problem that has gone unanswered.

(I'm a git newbie btw).

Cheers.

Update

I'm starting to think it may be to do with permissions - but Unix permissions, rather than NTFS. When @eis mentioned permissions I had assumed NTFS. But after more digging it seems that Git on Windows still checks for Unix file perms.

So I suspect the issue is that the post-receive file is not executable as when I do a ls -o it's -rw-r--r-- (644 I believe). If I try and change this through bash and chmod 777 post-receive then do ls -o the permissions are the same.

The strange this is that as soon as I edited post-receive (with notepad++) the execute bit gets removed. (my test script that ends in .bat does retain its execute bits though...)

BTW, the user I'm logged on as is the owner of the files (according to ls -o) and yet I can't set the permissions.

Starting to get really confused now. Am I missing something really obvious?

Update 2

Neither chmod 777 post-receive nor chmod a+x post-receive work. I took a new, clean post-receive file, uploaded it the to the server and checked the permissions and it had execute. If I rename the file (to remove sample) in Windows then execute is removed. If I do it in bash with mv execute is retained. But, whenever I edit the file (in Windows or in bash with vi) then execute gets removed.

So, the problem now is why does it remove the execute bits when I edit the file?

Hopefully this is the final hurdle and the cause of it not executing...

You are going to have to patch git to make this work. The checks in builtin/receive-pack.c are for access(path, X_OK). In msysgit this diverts to mingw_access which throws away the X_OK bit as it is simple not supported on Windows.

On windows, we have no flag to specify a file is executable. Systems often do some emulation of this. For instance, tcl will look for any extension in the PATHEXT environment variable to decide that a file is executable. We can't do that here as the hook names are hardcoded without any extensions.

Instead, I suggest changing the access test to just check the file exists and then call execv on the path. The mingw version of this (in compat/mingw.c) looks for script files and will read the shbang line and launch an appropriate interpreter (sh, perl etc). So modifying builtin/receive-pack.c:run_update_hook should let this work for you. Currently the hook running uses start_command and I think that should call down to execv for you.

In short, change the access test and it will probably work.