是整个工作副本"在一个分支"?

时间:2016-10-28 14:51:21

标签: git branch

这是一个非常基本的问题,但也许我不知道如何很好地表达我的查询以找到答案。

让我先来看一个SVN示例。 SVN没有"当前分支"作为工作副本的属性,所以我将给出带有修订的示例。考虑一个包含目标foobar的工作副本。在SVN中,可以update foo到早期版本,但将bar保留在HEAD

是否可以在类比git工作副本中检出dir foo中的一个分支而不更改bar中签出的分支?

如果没有,为什么不呢?

3 个答案:

答案 0 :(得分:2)

在git中,修订是提交。提交是整个仓库的快照。此快照记录了树结构的样子以及每个文件在git commit完成时保留的内容。如果foobar属于同一个仓库,则它们会绑定到同一个版本。签出修订后,foo会更新为此修订版快照中的内容,bar也是如此。这就是git-checkout在大多数情况下的工作原理。

Git-checkout还可以更新其部分文件或子目录。因此,如果foo和bar未嵌套,则可以签出修订版A的foo和版本B的bar。副作用是工作树变脏了。脏工作树意味着您可能会丢失未提交的更改,这些更改尚未被git跟踪。但是如果你确切地知道自己在做什么并且知道可能的损失,那么这种副作用就可以被忽略了。我们还可以将foobar初始化为两个单独的git repos。现在使用他们自己的修订版检出foobar是每个仓库中的完整结账,因此这两个回购都不会变脏。但我们现在必须维持两个回购。

如果foobar的子目录,我们可以将bar初始化为接管foo的仓库。签出bar后,foo也会更新,因为它现在是bar的一部分。但您仍然可以部分结帐foo并保持其他文件不变,或者检查其他文件并进行一些修订并保持foo不变。另一个选择是制作两个repos,foo作为bar的子模块。维护起来有点复杂。也可以不处理回购及其子回购。将它们作为两个独立的回购,但你必须在foo中忽略bar并始终记得将foo复制/克隆到bar内的正确位置,这可能是由git-submodule完成的。

我建议你阅读Pro Git章节Git Internals。它有助于理解git如何在内部工作,我可以保证你能够在脑中绘制包含分支,标签,HEAD等所有引用的提交图,并成为操作提交历史的大师。

答案 1 :(得分:1)

自Git 2.5以来,possible有多个工作副本。命令为git-worktree。例如,为了将现有分支foo签出到目录foo-working-copy,您可以这样做:

git worktree add ../foo-working-copy foo
cd ../foo-working-copy

答案 2 :(得分:1)

您可以将checkout个人文件或文件组添加到您想要的任何版本中。

然而,这留下了HEAD&索引未触及,因此这些文件显示为已修改(如您尚未add编辑或commit尚未进行的本地更改。没有办法告诉git一些(组)文件应该与其他文件不同。

如果您需要独立控制不同子目录的版本控制,请将它们作为单独的子模块存储库。

使用工作树只意味着您拥有repo的多个工作副本,可能显示不同的分支,但共享后端存储。在签出提交中,每个仍然是工作树的完整副本。