我在服务器上有一个裸git存储库,用作中央存储库。我已经安装了一个post-receive挂钩,以便在将提交推送到此存储库时,使用以下命令将提交的更改部署到同一服务器上的工作目录中:
git --git-dir=path-to-repository --work-tree=path-to-working-directory checkout -f
我意识到通过在post-receive挂钩中设置GIT_DIR
和GIT_WORK_TREE
环境变量,我也可以从命令行发出任意Git命令。我不是建议修改文件并从这个工作目录提交更改是一个好的开发实践,特别是如果这是我的生产环境,但是我从Git的角度做了什么非法的?
答案 0 :(得分:0)
...但是从Git的角度来看,我做了什么违法行为吗?
没有。然而,重要的是要认识到这个有点奇怪状态的一些事情。
Git只有一个存储库,--git-dir
告诉它在哪里找到一个存储库。
Git只有一个工作树, 1 ,--work-tree
告诉它在哪里找到一个工作树(并覆盖core.bare
设置)。
Git只有一个HEAD
(但请参阅脚注1),--git-dir
告诉它在哪里找到一个HEAD文件。
Git只有一个索引, 2 和... --git-dir
告诉它在哪里找到一个索引,如果没有被环境变量设置覆盖。
这些最后一点让人们感到高兴,主要是在使用post-receive
脚本部署某些特定分支时。
如果只将一个分支部署到一个工作树,则一个索引不是问题。如果您开始将两个或多个分支部署到两个工作树,则一个索引就成了问题。
同样,单个HEAD文件通常不是问题,特别是如果在以常规方式创建裸存储库时仅部署分支master
,并将master
作为其当前分支。 (裸存储库仍然有一个当前分支,它是HEAD
文件中的分支。)当人们克隆裸存储库时,他们的克隆默认检查裸存储库中当前的哪个分支 - 所以如果你开始部署了几个不同的分支机构,人们会对从克隆QA
或test
或develop
或其他任何内容开始的克隆感到惊讶。
(master
只需要让人们知道他们的默认克隆分支可能会让他们感到惊讶,他们应该查看开发分支,看看他们想要什么。它是导致真正麻烦的单个索引文件,请参阅脚注1。)
1 如果您使用Git 2.5及更高版本中提供的HEAD
,则不再适用。额外的工作树当然提供了自己的工作树,但也提供了自己独立的git worktree add
,以及他们自己的索引。
您可以使用环境变量HEAD
提供自己的索引,该变量始终覆盖Git的正常计算。这也提供了一种进行多个分支部署的方法:让一个分支使用默认索引,并为其余分支提供自己的索引文件(每个分支一个)。
对GIT_INDEX_FILE
使用多个工作树和新的updateInstead
模式可能是自动部署的更好方法,但我实际上没有对此进行过测试。
2 最新版本的Git引入了一个"拆分索引",其中非常大的索引文件是" split"进入不会发生太大变化的部分,以及那些为了使Git变得更快的部分。索引拆分略显神奇(虽然最终显然是确定性的和可预测的)并且知道如何处理备用索引文件,所以你真的不需要知道任何关于这个的东西,但是它会使得#34;索引文件"声称有点怀疑。在任何情况下,push.denyCurrentBranch
中添加的工作树仍然会获得自己的索引文件(或索引对),因为这是必要的。