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

我试图得到一个git post-receive hook在Windows上工作。

我使用的是Git 1.7.9(Msysgit),并在本地有一个回购站,在远程服务器上有回收站。 我可以读取,提交,推送等。我已经build立了一个post-receive钩子,应该将文件检出到一个工作文件夹(部署过程的一部分),但似乎不起作用。

这就是我所做的:

  1. 更改文件,阶段并提交
  2. 推送到远程服务器 – 成功
  3. 期待看到回声 – 看不到回声
  4. 检查服务器上的工作文件夹 – 最新的文件不存在
  5. login到服务器并手动运行挂钩脚本 – 将最新的文件签出到工作文件夹中。

我改变了钩子,所以它什么也不做,除了回应一个消息,我已经读过,我应该看到这个在推后我的控制台。 但是这并没有被显示出来,所以我只能假设这个钩子没有被解雇。

我正在处理请求的服务器上通过git dot aspx推送HTTP,并通过gui在本地进行注入。 之后,我试图倭黑猩猩和钩通过gui或bash控制台推动不起作用。

我假设有人有这个工作的地方,但经过两天寻找所有我find的解决scheme,没有帮助或人们有同样的问题,没有得到答复。

(我是一个混帐新手btw)。

干杯。

更新

我开始认为这可能与权限有关 – 但是Unix权限,而不是NTFS。 当@eis提到了我曾经承认的NTFS权限。 但更多的挖掘后,似乎Windows上的Git仍然检查Unix文件烫发。

所以我怀疑问题是post-receive文件是不可执行的,因为当我做一个ls -o它是-rw-r-r–(我相信)。 如果我尝试通过bash和chmod 777 post-receive更改这个,那么执行ls -o的权限是一样的。

奇怪的是,只要我编辑post-receive(用记事本++)执行位被删除。 (我的testing脚本以.bat结尾,虽然保留其执行位…)

顺便说一句,我login的用户是文件的所有者(根据ls -o ),但我不能设置权限。

现在开始变得非常困惑。 我错过了一些非常明显的东西吗

更新2

chmod 777 post-receive既不chmod 777 post-receive也不chmod 777 post-receive chmod a+x post-receive工作。 我拿了一个新的干净的post-receive文件,把它上传到服务器,并检查了权限并执行了。 如果我在Windows中重命名文件(删除示例),则执行将被删除。 如果我用mv执行bash,则保留它。 但是,无论何时我编辑文件(在Windows中或在与bash bash)然后执行被删除。

所以,现在的问题是为什么当我编辑文件时,它删除了执行位?

希望这是最后的障碍,并没有执行的原因…

Solutions Collecting From Web of "Git – 后接收钩不能在远程的Windows服务器上工作"

你将不得不修补混帐做这个工作。 builtin / receive-pack.c中的检查用于access(path, 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应该让你的工作。 目前hook运行使用start_command ,我认为应该调用execv给你。

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

当在服务器上使用msysgit,并通过文件共享挂钩工作,现在没有问题。 自从答案写完以后,也许这个问题已经在mysysgit中解决了。 我没有看到它。

我也注意到,原来的问题说git dot aspx和Bonobo正在使用哪个使用GitSharp.dll。 这将意味着应用程序不会对git.exe进行脱壳,并且钩子将不会以相同的方式处理。

例如,git dot aspx中使用的GitSharp.dll具有自己的钩子post-receive hook实现,可以在C#中执行:

 public void Receive(Stream inputStream, Stream outputStream) { using (var repository = GetRepository()) { var pack = new ReceivePack(repository); pack.setBiDirectionalPipe(false); //setup post receive hook here pack.setPostReceiveHook(new PostRecieveHook()); pack.receive(inputStream, outputStream, outputStream); } } public class PostRecieveHook : IPostReceiveHook { public void OnPostReceive(ReceivePack rp, ICollection<ReceiveCommand> commands) { //Do PostRecieve Hook Work Here } } 

我希望能够帮助其他人混淆Git实现的库和调用实际的git.exe的应用程序。