Git 基础理论之一
本文具有一定理论性,不是写给初学者的,对读者有一定git经验预设,并且可能对已入门者认识git有一定的提高。
本文以仓库托管商backlog.com提供的教程 (一篇不错Git入门教程,带有理论逻辑概念,不像官方或其它偏实现技术细节的)为纲,加入自己的理解,扩展写成。
另,此托管商提供了100M免费空间可用于个人项目。
Git 意义
- 跟踪代码变更历史
- 团队开发协作
- 查看谁进行了哪些更改
- 辅助产品的构建和渐进发布
Git 组成
这里的「组成」不是指Git软件内部技术组成,而是指Git作为一种工具,解决的任务的组成:有哪些主要的概念和对象组成。Git 任务有三个主要组件:
- 版本仓库
- 工作目录/文件树
- 暂存区/索引区
仓库与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不能翻译成「版本」,翻译成「提交」又比较粗糙。
一次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。
「分支合并」只是用一种特殊的方式来「制作新commit」——用另一个分支的commit,而不是工作目录(暂存区)上的数据。事实上,「制作commit」是整个VCS任务的中心,分支/合并分支是通过「协作的方式」来制作新commit,相对于在一条分支独立的一个一个制作commit。别忘记远程分支的分布式协作,不过本地分支与远程分支合并的意义是一样的——协作制作,只是一个多人协作,一个是一人分时协作。
工作目录
工作目录(工作文件树)保存签出版本的文件,组成「commitr制作者」或「开发者」的工作数据。开发者工作不会使用git 命令。
暂存区或index
「暂存区」是保存下一次「commit提交」的临时数据区。这里才是gitor开始作业的地方(制作一次Commit的临时数据区),相对于工作目录的编码者。
索引将「工作目录」中的文件与版本仓库中的文件进行比较。在「工作目录」中进行文件变更时,索引在提交commit之前将该文件标记为已修改。只有在索引区的数据才会保存为下一个commit的组成数据。
基本的 Git 工作流程
- 开发者在工作目录中修改文件,这个在git之外;
- gitor 制作commit,「版本跟踪者」将变更的文件保存到暂存区(git add);
- gitor 制作 repo,「版本跟踪者」提交commit,将暂存区域较完整的Commit(不断工作积累多个commit片断)存储到 Git 仓库中。