Git赢得了最受欢迎的版本控制系统的比赛。但为什么这么受欢迎?至少在我看来,答案很清楚:分支机构!它们允许您在与其他人的团队合作时,保持不同版本的代码,而且在与其他人一起合作时,还可以在您开始工作的新功能时。
虽然其他版本控制系统还提供某种形式的分支,但Git的概念和实施只是令人惊叹。它使分支机构合作,如此快速,简单地使许多开发人员采用了日常工作的概念。
在这篇文章中,我想探索和解释什么,为什么和分支机构:
我们将从高级观点来看Git中分支机构的概念 - 与更好地理解它们是什么以及应如何使用它们,以便您和您的团队可以获得最大的利益。
简单地,代码库是文件集合。任何有意义的变化(例如,在开发新功能或修复问题时)将很可能涉及几个文件。
只是片刻,让我们假装版本控制,特别是其“分支机构”的概念。在这种情况下,在进行更改时,您必须非常小心 - 因为您无法轻易撤消它们,并且您将冒出突破当前工作版本的风险。但是有一种缓解这些风险的简单方法:您可以简单地复制整个项目文件夹!在此副本中,您可以在不担心打破某些内容的情况下进行任何更改。
git中的分支具有完全相同的效果和目的:它们为其代码提供了具有单独工作空间的开发人员。当然,它们比我们简单的“复制文件夹”策略更聪明。例如,它们不会浪费磁盘空间(简单的文件系统副本将是这样),并且在与同一项目中的其他开发人员合作时,它们更有能力。
如果你考虑没有它们的工作流程,分支的价值变得清楚:想象一下10或20个开发人员的团队都在同一个“文件夹”中,所以说话。所有这些都同时编辑相同的源代码文件。突然,他们的代码现在是你的代码。有些人可能正在实现全新的功能,这可能会在开始时引入错误。开发人员必须执行的每个实验,以便进行进度和每个过程中不可避免的错误都会影响其所有队友。少数人以这种方式工作的人足以让整个发展过程停止。
只有一个上下文都存在所有队友和所有功能必须分享,提交历史看起来如此如此:
作为(相当令人困惑)点缀红线显示,没有分支机构的工作会很快导致混乱:很难理解哪个提交属于哪种功能!在遥远的过去,如果尚未获得强大的分支模型,版本控制是 - 非常有用,因为没有主要的结构元素。
让我们想象与思想的分支相同的情景。每个实验,每个新功能,每个Bug修复都获取自己的分支,它自己的上下文与所有其他开发上下文完全分开。在这方面“单独”也意味着“安全”:如果在一个上下文中发生错误,则其他上下文都没有受到影响。换句话说,分支是一种方便的容器,使得在多个同步的上下文中能够安全(并且可以首先是可能的)。
功能和错误修复程序显然彼此分开,他们的提交及其代码也是如此:
在上面的示例中,“常见问题内容”和“新设计”和“新设计”的变化不会彼此相处。
要短篇小说:使用分支机构的主要好处是他们使软件开发安全。他们防止错误和问题从一个上下文泄漏到另一个上下文中,并帮助您更容易地撤消错误。
如上所述,分支不是git排他性。许多其他版本控制系统提供分支作为工具集的一部分。但是有几个优点将Git的分支模型分开:
简单性:在git中使用分支真的很容易。初学者有时会在创建一个新分支之前犹豫,如果特定情况证明创建一个新分支,请询问自己。这种犹豫是不必要的:在git中创建新的分支是如此简单,它没有任何缺点。只需占用磁盘空间“示例:在GIT中创建新分支不会复制文件,可能会创建大量重复文件;相反,Git的文件管理确保没有任何东西可以复制!
速度:在Git中,与分支机构一起使用的所有操作都非常快。虽然某些版本控制系统,例如,在创建新分支时创建文件的副本,但Git的内部管理不需要此。因此,在创建新分支或使用现有的分支时,没有等待时间。
合并:使用分支创建安全的单独上下文是一件事。但是将(或“合并”)分支返回到其他上下文是游戏的另一部分。在许多其他版本控制系统中,合并可以是一个复杂的业务:可能会要求您提供确切的修改或选择特定的变更集。另一方面,Git使它非常简单和用户友好。在大多数情况下,它只是没有任何用户干预的作品。
Git以思想的概念为基础。它既不是事后的外临良好,也不是“很好”的功能,而是从一开始就是核心要求之一。
一般思想保持不变:分支机构为任何时候为任何项目发生的许多不同的工作提供了安全,独立的背景。在实践中,这需要一些不同的形式。
每当您在项目中启动“新建”时,为此创建一个新的单独分支是有意义的。如果它只是一个实验或全面的新功能
具有单独的上下文具有额外的好处,即易于摆脱 - 如果您的实验不会产生任何东西,或者您的新功能无法解决。同样,只要考虑这样的情况,就没有分支机构:你的新实验犯罪将与其他功能甚至是代码的主线混合,使他们难以摆脱以后。
即使对于错误修复(如果它们需要多行代码),则新的单独分支通常会有意义。一个优点,再次,您正在生产的相对未经测试的新代码不会干扰他人的工作。但在这种情况下,更重要的优势是关于组织:通过在自己的分支中拥有错误,更容易集成它何时何地在哪里。也许您只想在某个时间点或某些其他上下文中集成修复程序 - 所有这些上下文都可以使用分支机构轻松实现。
前面的例子 - 实验/新功能和错误修复 - 属于所谓的短期分支。顾名思义,这些分支并不意味着永远活着。相反,它们是为某些明确的目的而创建的(例如实现一个新的功能思想),然后一旦被集成到长期运行的分支中,就可以删除。
与他们的短暂的同事不同,在完整的一生中,长期的分支通常留在项目中。这些分支没有与特定功能或主题相关联。相反,它们代表项目中的状态或阶段:
项目的主线或生产代码的典型“主要”分支机构
有时也是代表某些阶段或环境的“阶段”或“生产”等分支机构
随着短期和长期跑步的这种区分,也经常是一个黄金法则:永远不会直接提交长期的分支;代码只能通过刻意集成(通过合并或rebase)来降落这些分支机构。
当试图想象分支机构如何工作时,使用“文件夹”的概念很诱人。毕竟,创建一个新分支的感觉非常像复制项目的当前状态并将其粘贴到一个新的单独文件夹中。
但是Git背后的一部分天才是它不仅仅是“复制所有内容”,这将使事情缓慢并使用大量的磁盘空间。它比这更聪明!
如果分支不是文件系统的副本,它们是什么?要回答这个问题,重要的是要知道Git的提交在存储数据时非常安全,有效:
安全性:提交的内容和元数据通过SHA-1哈希算法进行,这使得在事实之后很难操纵数据。
效率:如果已先存储,则提交不再存储数据。这意味着在提交之间未更改的文件不占用不必要的磁盘空间。
请记住这一点,会有任何需要“发明”的东西?不,当然不!这就是为什么Git的分支是一个极其轻量级的概念 - 远非沉重的“文件系统副本”。
每次添加新提交时,此指针都会自动移动。非常实用!
让我们再次来看待这个事实,从另一个角度:Git中的提交由他们的SHA-1哈希识别,那些40个字符的长,密码串。这些犯罪散列是静态和不可变的。另一方面,分支是非常灵活的,始终更改为最新提交的提交散列随时您在该分支中创建新的提交。
但那些神秘的指针看起来像什么,他们住在哪里?要回答这一点,我们必须快速进入Git的内部工作:隐藏的“.git”目录,位于您项目的根目录中。在这里,您会发现名为“refs”的子目录和另一个名为“heads”的子文件夹:它在此处,每个分支由在该分支之后名为的文件表示。
当您创建一个新分支时,例如使用“git分支My-new-branch”这样的命令,您将在此处找到一个新的物理文件,名为“my-new-branch”。
如果您要在文本编辑器中查看此类文件的内容,您发现它只包含单一信息:它目前指向的提交的SHA-1哈希哈希!
上面的图像显示了这种“指针文件”的内容:命名为“main”的分支当前指向SHA-1 HASH“BF88EF73C”的提交。
但是,Git如何知道您的本地分支机构的哪些目前处于活动状态?什么是添加新的提交的分支,并在发生这种情况时移动指针?
git保留另一个名为“head”的特殊指针。头部的唯一目的是指出目前活跃的(或“检查出”)分支机构:
在本地.git存储库文件夹中,您将发现在适当命名为“head”的文件中保存的此信息。该文件的内容通常如下所示:
最后,让我们来看看切换当前活动的分支时会发生什么。使用Git Checkout其他分支或Git Switch其他分支的命令。
b)工作副本中的文件已交换,现在代表该分支机构中的最新提交的状态。
我希望这篇文章能够更好地了解分支机构 - Git-Birt的核心工具之一。
就像在许多其他领域一样,它只是当你深深地了解你可以真正收获的好处。在我看来,这尤其如此:在我看来:互动rebase,子模块等高级工具,或者回流有能力让你成为一个更好的软件开发人员 - 但你必须需要一点时间来正确学习和理解它们。
如果您想上升您的GIT游戏,我将“Git的急救箱”放在一起 - 是免费收集的短视频,解释了许多有用的工具,如Rhallog,Interactive Rebase和其他可以帮助您避免或修复错误的其他人。
标签:分支机构,git,源控制