Git 分支



什么是分支

分支只是指向历史记录中特定提交的指针。它代表项目中独立的开发线。

在 VCS 中,分支是一个常见的功能,允许开发人员在不影响主开发的情况下处理不同的代码行。

传统的 VCS 工具在创建分支时可能会很慢,尤其是在大型项目中。这种速度下降是由于为每个新分支复制整个代码库造成的。

Git 在 VCS 中凭借其轻量级分支模型而脱颖而出,允许非常快速地创建和切换分支。

  • 这种效率来自 Git 与许多其他 VCS 工具不同,它不会为每个分支复制整个代码库。

  • 这使得可以频繁地进行分支和合并,甚至可能每天进行多次。

  • 通过掌握 Git 的分支,开发人员可以显著提高其工作流程和生产力。

Git 与其他 VCS

Git 与其他 VCS 在保存数据的方式上有所不同。与一系列修改相比,它利用了多个快照。

  • 在 Git 中,每次提交都会拍摄代码在那一特定时刻的状态的快照。

  • 此快照以提交对象的形式保存,其中包含有关作者、消息和与其引用的父提交的详细信息。

  • 常规提交有一个父提交,合并(合并分支)有多个父提交,而第一次提交则没有父提交。

暂存和提交

Git 会跟踪为特定提交暂存的文件。

  • 命令 git add 用于标记应包含在提交中的文件。

  • Git 为每个暂存的文件生成一个独特的校验和(SHA-1 哈希值),准确地反映了该特定时刻的内容。

  • 存储库将这些校验和存储为 blob

创建快照

Git 会跟踪每次提交时整个项目的状态。

  • 当我们使用 git commit 命令时,Git 会生成整个项目目录结构的快照。

  • 包含的文件(blob)及其相应的校验和以映射格式列出,称为 tree 对象,这就是保存此快照的方式。

提交对象

Git 通过创建提交对象来表示提交。

  • 元数据(如作者详细信息、提交消息、时间戳,最重要的是指向根树对象的指针)存储在此对象中。

  • 使用此指针,Git 可以重建该特定提交时的精确项目状态。

提交链

  • 我们进行的每次提交都会添加对(指向)之前提交的引用。

  • 通过这样做,创建了一个提交的时间顺序链,连接提交并让我们访问项目的历史记录。

使用分支

  • 对于提交链,Git 使用 分支作为可移动的轻量级指针。

  • 这些是指示某些提交历史点书签。

  • 默认情况下,Git 会创建一个名为 master 的主分支,该分支最初指向我们最新的提交。

git branch3

主分支的更新

  • 当我们进行更改和提交时,master 分支指针会自动刷新以指向最新的提交。

  • 这保证了项目的最新快照始终反映在 master 分支中。

创建新分支

在 Git 中,新创建的分支会创建一个新的指针来监控备用开发路径。

考虑一个名为 master 的分支项目,该分支指向项目历史记录中的特定提交。

使用以下命令创建分支

 $ git branch feature-xyz
 

此命令创建一个名为 feature-xyz 的分支,该分支指向与 master 分支相同的提交。

分支充当书签或标签。feature-xyz 分支和 master 将指向相同的提交。

git branchA

跟踪当前分支

Git 使用一个名为 HEAD 的特殊指针来跟踪当前活动的分支。

创建新分支时,HEAD 仍然指向 master 分支,表示当前工作分支保持 master,直到明确切换。

git branchB

带有 --decorate 选项的 git log 命令显示分支指针在提交历史记录中的指向位置。

$ git log --decorate

输出如下所示

f55bc (HEAD -> master, feature-xyz) Add support for new file formats
54bd2 Fix crash issue under heavy load conditions
88ba6 Initial setup and configuration

git log --decorate 中的 --decorate 选项提供了 HEAD 和分支指针的可视化表示。

切换分支

要更改活动分支并将 HEAD 更新为指向 feature-xyz 分支,请使用

$ git checkout feature-xyz

此命令更新 HEAD 以引用 feature-xyz,因此任何将来的更改和提交都将记录在 feature-xyz 上,而 master 保持不变。

git branchC

在分支切换后,每个分支的状态可能会发生分歧。

执行这些命令后,将在当前活动分支 feature-xyz 上创建一个新的提交。

例如

$ vim update_script.py
$ git commit -a -m 'Enhance script functionality'

master 分支仍然位于切换到 feature-xyz 之前指向的提交处,但 feature-xyz 分支已前进以包含此时的新提交。

git branchD

切换回 master

使用以下命令切换回 master 分支。

$ git checkout master

这会更新 HEAD 以指向 master 分支,从而使 master 再次成为活动分支。

git branchE

它会更新工作目录中的文件以匹配 master 指向的提交的状态。

这会导致工作分歧,因为在 feature-xyz 上进行的更改不会反映在 master 上,反之亦然。

让我们进行一些其他更改,然后提交

$ vim notes.txt
$ git commit -a -m 'Add notes for upcoming features'

通过执行上述命令,将在当前活动分支 master 上创建一个新的提交。

master 分支现在包含不同的更改,例如即将推出的功能的说明。

git branchF

git log --oneline --decorate --graph --all 命令提供了提交和分支的清晰可视化历史记录,还说明了它们之间的关系和分歧。

$ git log --oneline --decorate --graph --all
* 9d0f1 (HEAD -> master) Add notes for upcoming features
| * 6a1b2 (feature-xyz) Enhance script functionality
|/
* f55bc Add support for new file formats
* 54bd2 Fix crash issue under heavy load conditions
* 88ba6 Initial setup and configuration

总结

  • Git 分支的创建和删除几乎是即时的,因为它们只是包含提交的 40 个字符 SHA-1 校验和的文件。

  • 这允许高效地管理分支。

  • Git 的方法省去了为新分支复制整个目录的耗时步骤,而旧的版本控制系统需要此步骤。

  • Git 还通过自动识别合并基数和记录提交父级来简化合并过程。

  • 这种效率和自动化促进了频繁的分支和灵活的开发工作流程。

广告