Git中的“免费分支”是什么意思?


27

Git中的“免费分支”是什么意思?

与其他版本控制系统相比,每当提到Git时,我都会听到很多。

我没有机会(?)与其他人打交道(SVN等),那么在其他人中分支“昂贵”的情况又如何呢?

Answers:


28

“分支在git中是免费的”的说法是事实的简化,因为它本身并不是“免费的”。在幕后,更正确的说法是说分支便宜得多,因为分支基本上是对commit的引用。我将“便宜”定义为开销越少越便宜。

让我们通过检查Git有哪些开销来探究Git为什么如此“便宜”的原因:

如何在git中实现分支?

git存储库.git主要由目录组成,这些目录的文件包含git使用的元数据。每当您在git中创建分支(例如)时git branch {name_of_branch},都会发生以下情况:

  • 在以下位置创建对本地分支的引用: .git/refs/heads/{name_of_branch}
  • 在以下位置为本地分支创建历史记录日志: .git/logs/refs/heads/{name_of_branch}

基本上就是这样,创建了几个文本文件。如果将引用作为文本文件打开,则内容将是分支指向的提交的ID-sha。请注意,分支不需要您进行任何提交,因为它们是另一种对象。分支和提交都是git中的“一等公民”,一种方式是将分支与提交的关系视为聚合而不是组合。如果删除分支,则提交仍将以“悬挂”的形式存在。如果您不小心删除了一个分支,则始终可以尝试使用git-lost-found或查找提交,git-fsck --lost-found并在sha-id上创建分支,然后发现该分支悬空了(只要git尚未进行任何垃圾收集)。

那么git如何跟踪您正在处理的分支?答案与.git/HEAD文件有关,如果您在master分支上,则看起来像这样。

ref: refs/heads/master

切换分支只需更改.git/HEAD文件中的引用,然后继续使用提交中定义的内容更改工作区的内容。

与其他版本控制系统相比,这又如何?

Subversion中,分支是存储库中的虚拟目录。因此,最简单的分支方法是使用单线远程进行svn copy {trunk-url} {branch-url} -m "Branched it!"。SVN将执行以下操作:

  • 将源目录(例如)复制trunk到目标目录,
  • 提交更改以完成复制操作。

您将需要在服务器上远程执行此操作,因为在本地进行复制是线性时间操作,其中文件被复制和符号链接。这是一个非常慢的操作,而在服务器上执行此操作是固定时间的操作。请注意,即使在服务器上执行分支,在git分支时,subversion仍需要提交,而git则不需要。这是使SVN略低于Git的一种开销。

SVN中用于切换分支的命令(即svn switch)确实是svn update伪装的。由于虚拟目录的概念,该命令在svn中比在git中更加灵活。可以切换工作空间中的子目录以镜像另一个存储库URL。最接近的事情是使用,git-submodule但是使用在语义上与分支完全不同。不幸的是,这也是一个设计决定,使得SVN中的切换比Git中的切换慢一些,因为它必须检查每个工作空间目录所镜像的远程URL。以我的经验,Git比SVN切换分支更快。

SVN的分支需要付出一定的代价,因为它会复制文件,并且始终需要公开发布。如上所述,在git中,分支只是“引用”,可以保留在本地存储库中,并可以自行决定发布。以我的经验,SVN仍然比ClearCase便宜得多,性能也更高。

SVN不分散只是一个遗憾。您可以将多个存储库镜像到某个源存储库,但无法同步不同的更改,因为SVN没有用于提交的唯一标识符(git具有基于提交内容的哈希标识符),因此无法同步多个SVN存储库。我之所以开始在SVN上而不是在SVN上使用git的原因是,在git中启动存储库非常容易且便宜。从软件配置管理的概念上讲,项目的每个不同副本(克隆,派生,工作区或其他内容)都是一个“分支”,并且鉴于此术语,在SVN中创建新副本并不像Git便宜,后者分支“内置”。

作为另一个示例,在Mercurial中,分支开始与DVCS有点不同,并且创建/销毁命名分支需要单独的提交。水银开发商在开发后实现书签来模仿Git的同一分支模型虽然heads被称为tipsbranchesbookmarks不是在善变的术语。


哇。非常感谢您的“昂贵”说明。
laggingreflex

2
从您自己的来源:This command causes a near-instantaneous commit in the repository, creating a new directory in revision 341. The new directory is a copy of /calc/trunk.-在SVN中创建分支很简单,除非要显式地为每个文件创建一个副本。
Bobson

@Bobson我正在考虑重写分支上的位,因为我为此做了很多工作,但我的观点仍然,在Git中不需要提交就可以创建分支。以我的拙劣经验,我仍然觉得SVN中的切换分支要比Git中的慢,但是我无法指出任何具体原因。
Spoike

2
@Spoike-当然可以切换。而且绝对需要提交。我进行了修改以澄清我遇到的问题。如果您愿意,可以随时还原它。
Bobson


10

在Git中,分支只是引用对本地存储库的提交。创建它非常便宜,根本没有网络。不是很自由(您必须键入命令),但是该死的很近。

在SVN中,分支并不是特别昂贵-只是一个副本,这是非常便宜的提交。SVN确实有一个中央存储库模型,因此它是一种网络访问,但不是可怕的。

另一方面,在古老的CVS中,分支非常昂贵。基本上,CVS分支涉及添加标签,但是在CVS中,这意味着必须修改每个受影响的文件。每个文件都被重写以包括新标签。那太贵了。而且,如果您的存储库很大,它的运行速度也会非常慢。实际上,如果您在进行大型项目,它的运行速度很慢,以至于有些人倾向于避免建立分支机构。


4
使用Git,它甚至比提交还少-分支只是一个标签。SVN听起来和CVS一样昂贵,因为它们都复制了所有文件。
2013年

8
@Izkata:如果从用户角度来看-是的,从实现(和性能)角度来看,所有文件都已复制-否,仅添加了有关复制的记录。
maxim1000 2013年

@Izkata太多评论-查看我的答案。
gbjbaanb 2013年

6
@Izkata SVN创建指针和引用,它不会复制所有内容。
亚伦·麦克弗

2
Git分支不是提交,它只是对提交的引用,可以自由地将其移至其他提交。将Git仓库想像成一棵提交树,并将分支作为便笺,可以随意移动到该树上的不同提交中。
40XUserNotFound 2013年

5

SVN的分支与Git一样免费。只是一些管家数据表明分支从哪里开始,对存储的文件没有任何更改。SVN中的“复制”就像将符号链接添加到Unix目录。请注意,在您提交工作副本更改之前,SVN分支将不需要网络旅行(但是,如果您在某个时候不在本地进行提交,那么拥有SCM并没有多大意义)。

请注意,Git分支还将涉及一些内务处理-例如在内部添加该标签-提交时必须将其存储在某个位置。这根本没什么大不了的,这就是为什么它被称为“免费”的原因。


5

它是“免费的”(在这种情况下,“免费”实际上意味着快速,轻松并且不占用空间),因为在某些较旧的版本控制系统中,分支是那时代码的完整副本,因此分支占用了大量的代码。空间,最终很容易获得大量不同的完全完整版本的软件,然后进行管理。在其他情况下,它不是代码的完整副本,但仍需要为标签修改每个文件,因此速度慢且痛苦(“代价高昂”)。

git的分支本质上是指向提交的标签,因此可以避免上述问题。


1

“免费/便宜/昂贵”的另一个方面是与开发人员资源相关的成本多少,以应对分支机构的下游后果;即合并分支中的更改的过程。

在这里,与旧系统相比,合并Git和Mercurial等DVCS系统中的分支更容易……因为DVCS系统在跟踪图中版本历史方面做得更好。即先前合并发生的地方。这使合并更加准确,减少了不必要的冲突,并且...使所涉及的开发人员在主观上“更容易”或“不太害怕”进行合并。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.