为什么 Git 不将分支名称存储为提交的一部分?

发布于 2024-12-10 10:36:36 字数 863 浏览 0 评论 0原文

请注意:我并不是想重新争论 Mercurial 还是 Git 哪个更好,我只是有一个技术问题,作为 Mercurial 用户,我不明白。我也不确定 SO 是否是提出这样的问题的正确位置,但它与编程相关。

从用户的角度来看,关于 Git 和 Mercurial 这两个版本控制系统之间的差异已经有很多讨论(例如 Mercurial 和 Git 之间有什么区别?http://felipec.wordpress。 com/2011/01/16/mercurial-vs-git-its-all-in-the-branches/ ),主要区别在于分支的处理。我已经阅读了许多这些讨论,但我不断问自己这个问题:

为什么 Git 不将分支名称存储为提交的一部分?

我实在看不出有什么理由不这样做。这意味着数据不能因为没有指向它的引用(标签、分支等)而简单地消失。

我认为将分支存储在提交中对于 Mercurial 来说是一个很大的优势,因为这使得丢失数据变得更加困难。

支持 Git 分支模型的 Git 人群的主要观点是,您可以简单地删除分支,但这并不妨碍 Git 将分支名称存储为每次提交的一部分:如果一个分支的提交被删除,那么该分支的提交也会被删除。对该分支的引用。它也不会干扰“廉价分支”的论点:分支的管理成本不会更高。而且我认为不需要担心所需的额外存储:每次提交只需几个字节。

Please note: I'm not trying to restart the argument whether Mercurial or Git is better, I just have a technical question that I, as a Mercurial user, don't understand. I'm also not sure whether SO is the right place to ask such a question, but it is programming related.

There have been many discussions about how the two version control systems Git and Mercurial differ from each other from a user's point of view (e.g. What is the Difference Between Mercurial and Git? and http://felipec.wordpress.com/2011/01/16/mercurial-vs-git-its-all-in-the-branches/ ), and the major difference is the handling of branches. I have read through many of these discussions, but I keep asking myself this question:

Why does Git not store the branch name as part of the commit?

I don't really see a good reason for not doing that; it means that data can't just simply vanish because there is no reference (tag, branch, whatever) poiting to it.

I see storing the branch in the commit as a big plus for Mercurial, because that makes it more difficult to lose data.

The main point of the Git crowd in favor of Git's branching model, that you can simply delete branches, does not prevent Git from storing the name of the branch as part of each commit: If the commits of a branch are deleted, so are the references to that branch. It will also not interfere with the "cheap branching" argument: branches will not be more expensive to manage. And I don't think that the additional storage needed should be of concern: it's just a couple of bytes per commit.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

迷爱 2024-12-17 10:36:37

Mercurial 的基本操作模型非常简单,匿名分支形成有向无环图 (DAG),因此分支名称并不重要,您将更少地处理它们。命名分支主要用于组织目的(发布分支等),对此我认为全局命名空间更有意义,或者至少不那么令人反感。

Git 拥有比 Mercurial 更复杂、更受管理的分支模型,甚至您的本地更改也被视为单独的命名分支,面对如此多的命名分支,您必须引入命名空间来管理它们。出于同样的原因,Git 具有快进合并的概念,这不适用于 Mercurial,因为您一开始就不会创建单独的分支。

这两个概念都增加了额外的复杂性,同时阻止了有用的功能,例如将分支名称与提交一起存储。这是因为如果没有一些全局空间,你就无法存储命名空间分支,而 git 没有。

VonC 上面引用的命名空间参数的缺陷是,它假设如果你和我都创建一个名为“x”的分支,就会出现问题。不存在,就像您创建一个命名分支、合并它,然后创建另一个同名分支时没有问题一样。精心选择的名称描述了分支的功能,无论作者是谁,如果您需要更多区分,作者会与分支名称一起存储,所有这些都是永久性的。

我认为 Mercurial 项目将分支名称与提交一起存储是一个非常好的决定。就像提交消息和作者一样,工作的上下文(分支)是重要且有用的元信息。它使得在检查历史记录时更容易看到变更集的流程,因为您可以看到它们所在的上下文。在 Git 中,我的经验是,如果没有这些信息,历史记录很快就会变成一团难以理解的混乱行的头或尾。我认为拥有这个是值得以没有命名空间为代价的。

我认为你可以说哲学上的区别在于 Mercurial 将命名分支视为永久元数据,它提供了有关一行提交的一些额外信息,而对于 Git 来说,分支是 DAG 之上的开发人员的无版本管理系统。顺便说一句,Mercurial 也以“书签”的名义提供了这些功能(从 1.8 版本开始,这是一个核心功能),但它们实际上更像是一个跟踪工具,并且被视为标签而不是分支。

Mercurial’s basic model of operation is very simple, anonymous branches that form a directed acyclic graph (DAG), and as such branch names carry little importance and you will be dealing with them a lot less. Named branches are there mostly for organizational purposes (release branches, etc.), for which I would argue a global namespace makes more sense or at least is less objectionable.

Git has a more complicated and managed branching model than Mercurial, where even your local changes are treated like a separate named branch, and facing such a plethora of named branches you have to introduce namespaces to manage them. For the same reason Git has the concept of fast-forward merges, something that does not apply to Mercurial because you wouldn’t have created a separate branch in the first place.

Both these concepts add extra complexity, and at the same time block useful features like storing the branch name along with the commit. This is because you can not store namespaced branches without some global space, and git has none.

The flaw in the argument for namespaces that VonC referenced above is that it assumes there is a problem if you and I both create a branch called ‘x’. There isn’t, just like there is no problem when you create a named branch, merge it, and later create another one with the same name. A well-chosen name describes what the branch does no matter who the author is, and if you need to differentiate more the author is stored right along with the branch name, and all of this is permanent.

I think it was a very good decision of the Mercurial project to store the branch name along with the commit. Just like the commit message and the author, the context of the work (the branch) is important and useful meta-information. It makes it much easier to see the flow of the changesets when inspecting history, because you can see the context they were made in. In Git I have experienced that without this information, history quickly becomes a mess of jumbly lines that is hard to make heads or tails of. I think having this is well worth the trade-off of having no namespace.

I think you could say the philosophical difference is that Mercurial treats named branches as permanent meta-data that gives some extra information about a line of commits, whereas for Git branches are an un-versioned managing system for developers on top of the DAG. Mercurial also has these under the name ‘bookmarks’ by the way (as of version 1.8 a core feature), but they are really more of a tracking tool and treated like labels instead of branches.

彼岸花ソ最美的依靠 2024-12-17 10:36:36

关于 Git 和 Mercurial 分支的权威来源之一是 SO 问题:

Git 和 Mercurial - 比较和对比

在 Git 中,引用(分支、远程跟踪分支和标签)位于提交的 DAG 之外。

(这允许管理有关本地和远程分支的分支的不同命名空间)

您对具有书签分支(可以推/拉)的 Mercurial 有类似的概念。

请注意,在 Git 中,数据不会“消失”,因为没有引用:您仍然拥有 reflog 来检索那些未引用的提交。

为什么 Git 不将分支名称存储为提交的一部分?
我实在找不到不这样做的充分理由

这个想法是将什么已更改(提交)与原因分开,即与更改的上下文分开(分支机构的名称)。
因为您可以快进合并 一个分支,一个分支的提交可以随时成为另一个分支的一部分。

这就是为什么 Jakub Narębski 质疑 Mercurial“命名分支”的设计(分支名称嵌入变更集元数据中),特别是对于全局命名空间,不太适合分布式版本控制系统。

您创建一个分支来隔离开发工作(请参阅“您应该何时分支?"),但对于 DVCS,开发工作(提交集)应该在任何分支名称下发布。一旦发布到另一个 Git 存储库,您定义的本地上下文(分支名称)可能无效。

One of the definitive source about branches for Git and Mercurial is the SO question:

"Git and Mercurial - Compare and Contrast"

In Git references (branches, remote-tracking branches and tags) reside outside DAG of commits.

(That allows to manage different namespaces regarding branches, for local and remote branches)

You have a similar notion with Mercurial with bookmark branches (which can be pushed/pulled).

Note that in Git, the data won't "vanish" because there is no reference: you still have the reflog to retrieve those unreferenced commits.

Why does Git not store the branch name as part of the commit?
I don't really see a good reason for not doing that

The idea is to separate what has changed (the commits) from whym ie from the context of the change (the name of the branch).
Since you can fast-forward merge a branch, commits from one branch can be part of another at any time.

That is why Jakub Narębski questioned the design of Mercurial "named branches" (with branch names embedded in changeset metadata), especially with a global namespace, not very suited for a distributed version control system.

You create a branch to isolate a development effort (see "When should you branch?"), but with a DVCS, that development effort (the set of commits) should be published under any branch name. What local context (branch name) you have defined might not be valid once published to another Git repo.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文