git post-receive钩子无法删除文件。

3

我目前正在尝试使用git,并尝试创建一个工作流程,以便在服务器上对裸远程repo进行推送时,可以基于不同的分支更新2个不同的站点。

post-receive hook如下:

#!/bin/sh
GIT_WORK_TREE=/www/development/ git checkout -f master
GIT_WORK_TREE=/www/production/ git checkout -f production

基于https://dev59.com/KG865IYBdhLWcg3wZNrT#3838804的代码,但做了一些修改。
不幸的是,在测试过程中,将新的测试文件提交到任何一个分支都会推送并成功更新Web根目录,但是删除相同的测试文件后,Web根目录仍然保留有已删除文件的副本。
有人知道如何使post-receive钩子强制执行删除吗?

这里的基本问题是,您正在从一个存储库部署到两个不同的工作树。一个存储库有一个索引,用于跟踪单个工作树中的内容。这意味着一个索引会仔细记录/www/development中的内容,然后尽可能轻松地使用该目录来触及相同的目录/www/production。现在,Git 知道了production中的内容,它会确保下次尽量少地触及development,以此类推。看到问题了吗?我们有两个工作树,因此需要两个索引文件 - torek
3个回答

2

您可能需要使用git-resetgit-clean

#!/bin/sh
GIT_WORK_TREE=/www/development/ git reset --hard master
GIT_WORK_TREE=/www/development/ git clean -fdx
GIT_WORK_TREE=/www/production/ git reset --hard production
GIT_WORK_TREE=/www/production/ git clean -fdx

它并没有完全起作用,不确定是由于权限或其他原因:(使用TortoiseGit)remote: error: packfile ./objects/pack/pack-<random string here>.pack 无法访问 remote: HEAD is now at <another random string> test但我通过一些修改成功让它工作了。 - xiankai

1
我认为工作树检出不会在工作目录中记录有关存储库的任何信息。因此,当更新已经检出的版本时,Git将无法确定应该应用哪个diff以及需要删除哪些文件。
最简单的解决方法是在检出之前删除文件夹中的所有文件。

谢谢您解释了幕后发生的事情,这很有道理。 - xiankai

0

最终我做了

#!/bin/sh
GIT_WORK_TREE=/www/development/ git checkout -f master
GIT_WORK_TREE=/www/development/ git clean -fdx
GIT_WORK_TREE=/www/production/ git checkout -f production
GIT_WORK_TREE=/www/production/ git clean -fdx

基于 @Koraktor 的回答。


这在大多数情况下可能有效,但不是正确的方法:在某些情况下,它仍可能无法检查出某些内容。您应该完全删除目标工作树(Git 然后会注意到其索引已过期并重新构建所有内容),或者针对每个部署目标使用两个不同的索引文件,类似于 git worktree addgit worktree 是 Git 2.5 及更高版本中的新功能,可能并不完全适合您在这里的需求;您可以设置一个 GIT_INDEX_FILE)。 - torek

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接