Git 基础理论之一

本文具有一定理论性,不是写给初学者的,对读者有一定git经验预设,并且可能对已入门者认识git有一定的提高。

本文以仓库托管商backlog.com提供的教程  (一篇不错Git入门教程,带有理论逻辑概念,不像官方或其它偏实现技术细节的)为纲,加入自己的理解,扩展写成。

另,此托管商提供了100M免费空间可用于个人项目。

Git 意义

  • 跟踪代码变更历史
  • 团队开发协作
  • 查看谁进行了哪些更改
  • 辅助产品的构建和渐进发布

Git 组成

这里的「组成」不是指Git软件内部技术组成,而是指Git作为一种工具,解决的任务的组成:有哪些主要的概念和对象组成。Git 任务有三个主要组件:

  • 版本仓库
  • 工作目录/文件树
  • 暂存区/索引区

git workflow 001

仓库与Commit

**repository,**或 repo,一般译作「仓库」,直观上是指存放跟踪项目文件变更记录的“容器”或数据库。变更以Commit(在某个时间点的项目文件的快照)对象独立保存,「仓库」对象是「仓库管理者」的作业数据,例如,你可以使用 git log 查看Commit 历史记录。

理解「仓库」需要在特定语境,如果和一个商品库存人员交流,「仓库」肯定别有所指,故将repository 翻译成「仓库」是有局限的。所以最好加一个修饰,例如版本仓库。厘清「repository」的形式很有必要,有助于认识如何正确处理它——创建、制作和使用它。

git是一种分布式VCS,故它的repository 具远程属性,另外,git 以分支和commit为对象管理版本历史,所以 repository是一种分布式版本仓库。在开发社区,直译仓库,大家知道指是版本仓库,而版本是指分支和Commit组合。

由此,认识 repository形式的第一个前提,是有关commit和分支的形式知识。

Commit 正名

commit是什么?怎么翻译?变更、版本、快照、提交 ?!有各种的理解角度。正确翻译一个符号,最好从它具体实现了什么。最常用的「提交」来自命令操作commit,直观但不准确,因为提交的动作,和提交的数据是不同。commit最初所指应该是 file change,而且是一系列的文件变更历史,用于记录一次“新版本”。而git 引了暂存区(index)的概念,commit前有一个stage的步骤(git add命令),存放在暂存区的所有文件变更就是下一次commit,就是commit符号所指。我以为林纳斯设计的暂存区具有特别好的价值,它不但有利对commit逻辑认识,也在实践中有利commit构建。

综述以上,我没有找到特别合适的中文来翻译commit符号实际所指,故直接不译。

Commit 形式

Commit第一个形式属性,就是它有一个以上的「基」;实际上,一次提交的Commit 只是版本片断或增量,完整的软件版本,是由Commit 及其演化分支上所有基础的历史Commit叠加的结果。所以Commit不能翻译成「版本」,翻译成「提交」又比较粗糙。

recording changes 001 Commits

一次Commit包括什么变更,多少变更,没有严格规定,这个常常取决于程序模块设计,和程序员个人偏好,不过应该有一定的最佳实践;

由于Commit的具体形态很随意,所以常常需要「修正Commit」,包括

  • 单独增删commmit内容:git commmit --amend
  • 调基:git rebase
  • git cherry pick
  • 合并多个commit:Git merge --squash

Commit的制作,请参考文档附录 A3.3 Appendix C: Git Commands - Basic Snapshotting

分支的形式

commit并不是散列的存储在版本仓库里的,多个commit被组织成具有方向性的分支,「分支」是一个以上具有历史关联的「Commit」的结集。分支表征了完整的软件版本。如果版本库保存多个版本,那么版本更多是指分支,而不是一个个独立的commit。

work in parallel 003 三条分支

「分支合并」只是用一种特殊的方式来「制作新commit」——用另一个分支的commit,而不是工作目录(暂存区)上的数据。事实上,「制作commit」是整个VCS任务的中心,分支/合并分支是通过「协作的方式」来制作新commit,相对于在一条分支独立的一个一个制作commit。别忘记远程分支的分布式协作,不过本地分支与远程分支合并的意义是一样的——协作制作,只是一个多人协作,一个是一人分时协作。

工作目录

工作目录(工作文件树)保存签出版本的文件,组成「commitr制作者」或「开发者」的工作数据。开发者工作不会使用git 命令。

暂存区或index

「暂存区」是保存下一次「commit提交」的临时数据区。这里才是gitor开始作业的地方(制作一次Commit的临时数据区),相对于工作目录的编码者。

索引将「工作目录」中的文件与版本仓库中的文件进行比较。在「工作目录」中进行文件变更时,索引在提交commit之前将该文件标记为已修改。只有在索引区的数据才会保存为下一个commit的组成数据。

基本的 Git 工作流程

  1. 开发者在工作目录中修改文件,这个在git之外;
  2. gitor 制作commit,「版本跟踪者」将变更的文件保存到暂存区(git add);
  3. gitor 制作 repo,「版本跟踪者」提交commit,将暂存区域较完整的Commit(不断工作积累多个commit片断)存储到 Git 仓库中。

trees

参考

裸男
Nakeman.cn 2023 Build by Gatsby and Tailwind, Deploy on Netlify.