我正在尝试在Windows上使用git post-receive hook。
我正在使用Git 1.7.9(Msysgit)并在本地拥有一个repo,并在远程服务器上拥有一个裸仓库。我可以获取,提交,推送等。我已经设置了一个post-receive挂钩,应该将文件签出到工作文件夹(部署过程的一部分),但它似乎不起作用。
这就是我的所作所为:
我更改了钩子,所以它除了回显消息之外什么都不做,我读过我应该在推送后在控制台中看到这个。但这并没有显示出来,所以我只能假设钩子没有被解雇。
我正在处理请求的服务器上使用git dot aspx推送HTTP并在本地通过gui进行pusing。在那次失败之后我尝试了Bonobo并且当通过gui或bash控制台推送时钩子不起作用。
我假设有人在某个地方工作,但经过两天的搜索,我发现所有的解决方案都没有帮助,或者有相同问题的人没有得到答复。
(我是一个git newbie btw)。
干杯。
更新
我开始认为它可能与权限有关 - 但是Unix权限,而不是NTFS。当@eis提到权限时我假设NTFS。但是经过更多的挖掘后,似乎Windows上的Git仍然会检查Unix文件的权限。
所以我怀疑问题是后接收文件不可执行,因为当我执行ls -o
时它是-rw-r - r--(我相信644)。如果我尝试通过bash和chmod 777 post-receive
进行更改,那么执行ls -o
权限是相同的。
奇怪的是,只要我编辑后接收(使用notepad ++),执行位就会被删除。 (我的测试脚本以.bat结尾但确实保留了它的执行位......)
BTW,我登录的用户是文件的所有者(根据ls -o
)但我无法设置权限。
现在开始变得非常困惑。我错过了一些非常明显的东西吗?
更新2
chmod 777 post-receive
和chmod a+x post-receive
都不起作用。我拿了一个新的,干净的post-receive文件,将其上传到服务器并检查权限并执行了。如果我在Windows中重命名文件(删除示例),则删除执行。如果我在使用mv
的bash中执行此操作,则保留执行。
但是,每当我编辑文件时(在Windows中或在使用vi的bash中),执行都会被删除。
所以,现在问题是为什么在编辑文件时它会删除执行位?
希望这是最后的障碍,并且导致它没有执行......
答案 0 :(得分:1)
你将不得不修补git来使这项工作。 builtin / receive-pack.c中的检查适用于access(path, X_OK)
。在msysgit中,这会转移到mingw_access,它会丢弃X_OK位,因为Windows上不支持它。
在Windows上,我们没有标志来指定文件是可执行的。系统经常对此进行一些仿真。例如,tcl将在PATHEXT环境变量中查找任何扩展,以确定文件是可执行的。我们不能这样做,因为钩子名称是硬编码的,没有任何扩展名。
相反,我建议更改访问测试,只检查文件是否存在,然后在路径上调用execv
。 mingw版本(在compat / mingw.c中)查找脚本文件,并将读取shbang行并启动适当的解释器(sh,perl等)。所以修改builtin/receive-pack.c:run_update_hook
应该让这对你有用。目前,钩子运行使用start_command
,我认为应该为你调用execv。
简而言之,更改访问测试,它可能会有效。
答案 1 :(得分:0)
在服务器上使用msysgit并通过文件共享挂钩现在可以正常工作。也许这是在mysysgit中修复的,因为答案是写的。我没有调查它。
我还注意到原来的问题是git dot aspx和Bonobo正在使用GitSharp.dll。这意味着应用程序没有外壳到git.exe,并且钩子不会以相同的方式处理。
例如,git dot aspx中使用的GitSharp.dll有自己的钩子后接收挂钩实现,可以在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的应用程序之间产生混淆。