我试图得到一个git post-receive hook在Windows上工作。
我使用的是Git 1.7.9(Msysgit),并在本地有一个回购站,在远程服务器上有回收站。 我可以读取,提交,推送等。我已经build立了一个post-receive钩子,应该将文件检出到一个工作文件夹(部署过程的一部分),但似乎不起作用。
这就是我所做的:
我改变了钩子,所以它什么也不做,除了回应一个消息,我已经读过,我应该看到这个在推后我的控制台。 但是这并没有被显示出来,所以我只能假设这个钩子没有被解雇。
我正在处理请求的服务器上通过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)然后执行被删除。
所以,现在的问题是为什么当我编辑文件时,它删除了执行位?
希望这是最后的障碍,并没有执行的原因…
你将不得不修补混帐做这个工作。 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的应用程序。