【Git】代码提交

Git——以及所有一切的版本库——的核心目标,就是保证代码不会丢失。我所熟知的两个版本控制工具——SVN和Git——都是通过提交代码(commit)来实现这个目标的。

虽然我反对使用SVN来类比Git,但是,如果仅是为了强调它们的“不同”,而进行比较,我觉得还是有助于理解的。

SVN使用过程中,版本仓库是在云端的,程序员的个人电脑上,只是一个工作副本,或者叫代码暂存,如果写好的代码,没有被送到云端的版本库,就意味着有潜在丢失的风险。所以,SVN的提交(commit),其本质,就是将代码从本地电脑传送到云端服务器,这个过程,我们称之为“入库”。

既然版本库在云端,而且多人共用一个版本库,就有可能多人共同编辑一个文件,就可能冲突(conflict),所以,使用SVN,在进行提交的时候,遇到冲突、解决冲突,就变成了提交过程中的一个关键任务。

Git与SVN截然不同,其根本原因在于,版本仓库在程序员的个人电脑上。所以,Git的提交(commit),就是在自己的电脑上,把不在版本仓库里的代码,放进版本库里面而已。这个过程里,完全不需要网络连接。因为本地电脑上独占一个版本库,提交的过程,也根本不可能冲突。

使用Git,提交代码,就是“提交代码”本身,就是完成了保护代码不会丢失的目标。这个过程纯粹、单一,不存在潜在的冲突的可能性。所以,使用Git,提交代码,就是非常愉快的一件事情,大家应该很乐意去提交,随时提交,甚至写个脚本自动提交,无时无刻不在提交。

然而——果然还是有一个“转折”,这真是令人讨厌的部分啊——使用Git进行提交,我们还需要再多搞清楚一些概念,才可以做得有条不紊。这些概念不完全是Git的发明,但是为了使用它,这些概念被曝光了出来,以至于我们发现了它们的存在。

这个概念,就是文件的“状态”。因为整个过程中,我们在进行版本控制,所以,这些“状态”都是与版本控制有关系的。

已提交(committed),文件所有变化,都已经位于版本库里面了,安全了。(SVN中也有这个概念,不是新发明)

不追踪(untracked),文件在版本库影响的文件夹里面,但是没有被纳入到版本库的管理,“与版本库完全无关”。在我们给出明确的指令,用版本控制工具管理某个文件时候,任何文件对于版本库来说,都处于不追踪状态。因为一般我们以文件夹为单位,进行版本管理,所以,已经纳入版本管理的文件夹里面,如果出现了一个“不追踪”的文件,极可能是将要被追踪的文件,所以Git会明确识别出它们的存在。(SVN中也有这个概念,不是新发明)

已修改(moified),文件受到版本控制管理,已经被修改了,还没有提交,变更有潜在丢失风险。(SVN中也有这个概念,不是新发明)到目前为止,这三个状态,还在大多数人的“舒适区”内,没任何突破。现在,变化来了,就在这个“已修改”的状态里,在Git里,“已修改”会分裂为两个子状态,一个是“已修改,待提交(staged)”(执行commit命令的时候,默认情况下,只有这个状态的文件会被提交到版本库),另一个是“已修改,暂不提交(not staged)”。

我尝试揣摩一下,多出来的两个子状态的原因,我觉得可能设计者希望大家用得更方便,控制更精细,这种设计,给了程序员一个选择:部分提交自己的修改。SVN里,也可以做到部分提交,但是颗粒度只能达到一个文件的粒度,这个文件,要么全部提交,要么全部不提交。但在Git里,你可以做到,截止此时此刻,此文件需要提交,从下一秒开始,这同一个文件的变化,我还没想好,到底要不要提交。(SVN做不到)

另外,假如我一次修改了30个文件,只需要提交17个,透过这个子状态,也可以一并做到。我特意研究了下,发现SVN到是也可以做到这一点,但是不是用文件状态实现的,而是用了一个附加小工具,changelist,你通过将文件记录到一个可命名的list里面,实现提交特定的文件列表。

当然,像上述两个我分析的原因,并非所有人都需要的,大家就会觉得,这未免太麻烦了,比如总是穿着开裆裤的人,你非让人家把开裆裤脱掉再尿尿,就有些多余。其实,穿开裆裤的人,只要叉开腿或者蹲下,就可以尿了,没必要脱裤子。于是,Git的commit指令,有个叫-a的参数,意思是无视“已修改(modified)”状态的两个子状态,只要“已修改”,就一律都提交。这么处理很方便,好像穿了开裆裤一样。

至于用SVN时候,我们对这些“状态”,为什么没有那么强的感知呢?我想,SVN成功太早,太成熟,大多数程序员,哪怕像我这个年龄,开始接触SVN的时候,SVN的图形界面,早就一统江湖好多年,比如著名的ToitorseSVN,跟资源管理器高度结合,简直就是Windows环境下的标配,在图形界面里,这些状态被高度形象化了,浑然天成,好像不存在一样,那么理所当然,以至于很多人以为,这个“客户端的图形界面”,就是“客户端”本身,甚至觉得,就是SVN本身,谬矣,谬矣。