与 Git 一起工作的地方(分支或树干)

Where work with Git (Branches or Trunks)

我使用 SVN 并且有 3 个 environments

实际上,所有团队都与 trunk 一起工作。

我们想迁移到 Git。 我们应该在开发环境的什么地方工作?

我们应该使用分支,当我们将代码上传到生产环境时,将该分支重新集成到 master(主干)?

Git 和 SVN "think" 在提交和分支方面有很大不同。具体来说,Git没有后备箱

在其他版本控制系统中,分支和 branch-names 是非常可靠的(相应地 heavy-weight)项,并且在某些情况下是完全不可分割的。例如,在 Mercurial 中,一旦在某个特定分支上进行了提交,该提交就 on that 分支,并且仅 那个分支,永远。 (在 SVN 中,分支非常 heavy-weight,但与 Mercurial 和 Git 有很大的不同,也没有可比性。我喜欢使用 Mercurial 作为比较器,因为 Git 和 Mercurial 都是 分布式,而SVN是集中式的。分布式与集中式也从根本上改变了人们使用版本控制的方式。Git允许您指定一个中央同步存储库,但它是可选的而不是强制性的。)

相比之下,在 Git 中,一个分支 name 是一个很小的、轻量级的东西,几乎不重要。它只是一个 人类可读的 提交名称,还有一个特殊的 属性。 Git 有两个方便的 human-readable 提交名称:分支名称和标记名称。它们之间最大的区别是分支名称应该移动——如此之多以至于Git移动它们自动——和标签名称还不够 Git 防止您不小心移动它们。

请注意 Git 中分支 name 分支之间的仔细区别,呃,something-or-other。 Git 并没有完全区分这一点。至少有两个不同的东西,都叫做"a branch"。有关此的更多信息,请参阅 What exactly do we mean by "branch"? 我将尝试通过说实际历史(构成 branch-as-a-thing-other-than-the-name 的提交集)由提交本身形成来总结这一点。提交一旦做出,就是永久性的1 并且不会改变。没有人——不是你,也不是 Git——可以更改提交,因为它的哈希 ID——它的 "true name",完全不可读——是其内容的加密哈希。即使更改这些内容的一点点,哈希 ID 也会更改,因此您有一个新的和不同的提交。

每个提交都包含其 parent(直接祖先)提交的 ID 作为其数据的一部分,或多个 parent 的多个 ID如果提交是 合并提交 ,则提交。正是这些 ID 链构成了 branch-as-something-other-than-the-name——在 Git 中,这意味着任何给定的提交都可能同时在 多个 分支上。在某些情况下,提交可能根本 no 个分支!

当您进行新提交时,Git 通过将提交写入存储库数据库并将其 parent 设置为当前提交,将新提交添加到当前分支。因此,总有 2 个当前提交,称为 HEAD。一旦新提交被安全地永久保存,Git 就会将新提交的 ID 写入分支名称。 HEAD 实际上是作为文件实现的,但该文件通常只包含当前分支的 name。 branch-to-commit-ID 映射提供了当前提交的哈希 ID。

可以随时添加和删除分支名称,但如脚注 1 中所述,可以删除分支名称——如果这些提交没有 other 名称可供查找他们——放弃对 Grim Reaper Collector 的承诺。

由于所有这些,Git 应该以一种非常不同的方式使用。您可以而且应该立即左右创建新的分支。当你完成任何需要分支的东西时,合并它,重新设置它的基数,rebase-and-squash它,或者扔掉它,无论你想要什么:所有这些都非常快。当你完成后,无论提交你有历史,你查看历史通过开始Git 带有一些分支名称或其他 starting-points(例如,标签,甚至是原始提交哈希 ID)。它向您显示那些特定的提交,然后是它们的 parents,以及它们的 parents' parents,等等,一直回到第一个(parent更少,或者 root) commit.


1永久,也就是说,除了 "abandoned" 提交(和其他 Git objects)。这些最终被 垃圾收集 使用 git gc。分支 names 有一个额外的目的:他们 protect 从这样的集合中提交。但是,any 名称—分支名称、标记名称、git stash 命令中的 stashgit notes 中的任何 notes 名称, 等等——将保护提交。该提交然后保护其 parent 提交,返回所有提交历史记录。

2这一规则有一个例外。必须有,来处理一个空的存储库,它根本没有提交。该异常也用于 so-called orphanunborn 分支一些 Git 使用第一个术语,一些使用第二个),但大多数人只会在新的空存储库中看到异常。