没有工作树的仓库上的Git操作?

时间:2018-10-11 07:02:40

标签: git

旧项目的构建工作流程应检出特定的git版本标记并编译该源。 我建议保持简单并像这样使用Git Cli:

git clone –b $versiontag –singlebranch $gitrepouri

之后代替git clone和git checkout标签。

要“节省时间”,一位同事想使用另一种方法=从另一台服务器上的现有Git存储库复制.git文件夹 进入构建工作目录,然后在该文件夹上进行操作。

起初,她在复制后尝试使用git checkout $versiontag
输出具有多个条目,例如:

$ git checkout tags/sometag
D       Foobar/somefile
D       Foobar/someotherfile
[...]
Note: checking out 'tags/sometag'.

You are in 'detached HEAD' state.
[...]

,但是工作树的内容与正常的git clone和git checkout有所不同,尽管两者都位于 头部处于分离状态,并已签出该特定标签。
诸如Sonarqube之类的工具也存在问题,因为git blame不起作用
(缺少blame信息。)

此后,她在复制后尝试使用git sparse-checkout,乍一看似乎很有效
- 尽管与简单的Git Cli方法相比,它要复杂得多。

在没有整体工作树的情况下针对Git存储库使用Git命令有什么弊端?

1 个答案:

答案 0 :(得分:2)

Git有一个内部设置来告知 tell ,它使用的是没有工作树的克隆。具体来说,对于这样的存储库,core.bare应该设置为true

手动复制存储库,而不是使用git clone来复制它,而是复制其配置文件(.git/config.git/info/文件)。这包括core.bare设置,Git自行创建了几个设置来描述运行Git的机器和文件系统的行为。如果这些设置不能反映实际的计算机和实际的文件系统,则可能以各种方式出错。一些info文件可能会将Git指向其他 not 复制的目录;如果是这样,您还需要知道该怎么做。因此,除非您知道您对这些其他变量和info文件的处理方式,否则请勿使用cp -r(或tar或类似名称)来复制.git目录直接。

复制原始.git存储库也会复制该存储库的索引。索引描述了工作树,因此,如果新位置没有工作树,则复制的索引会自动不正确。 (注意:所有存储库,包括裸存储库,都有一个索引。最初裸存储库的索引通常为空,但请参见下文。)

也就是说,您可以在裸仓库上执行一些 Git操作。具体来说,您可以执行任何不需要工作树的操作。这意味着,如果您知道有关特殊控制变量的操作,则可以 .git存储库复制到其他位置,然后使用它。因为您将避免使用工作树的操作(例如,这意味着避免使用git checkout),所以折断索引不是问题,尽管如果您要变得如此聪明,那也许太聪明了一半,您还可以知道什么时候可以安全地删除损坏的索引。

您还可以使用git --work-tree=<path> ...GIT_WORK_TREE=<path> git ...为裸仓库提供临时工作树。如果这样做,它将覆盖core.bare设置,并且裸存储库的索引用于跟踪给定的<path>。请注意,如果更改路径,则会使索引无效;否则,索引将无效。在这种情况下,您必须使用其他索引(通过将GIT_INDEX_FILE设置为备用索引)或删除现有索引。

因此,考虑到以上所有注意事项,您可以 .git目录转换为正确的裸Git存储库,或者使用cptar将包含(或排除其)当前工作树的.git目录移植到具有新工作树的新位置。但是总的来说,您不应该,因为如果这样做,您必须对Git的未来版本做出很多假设。 Git承诺git clonegit bundle之类的东西将继续按照现在的方式工作; Git不保证在复制的.git目录上进行的偷偷摸摸的手术将继续以这种方式进行。