一行注释代码背后的故事
如果你打开腾讯地图,查看网页源码,可以看到一行注释:
<!--modified by nimomeng 添加统计额外参数opt,在此处设置其key为areaId,value为left-->
‘nomomeng’同学是一个前端工程师,985大学毕业的。他刚刚完成了一个不大不小的功能,为此他已经连续加班了半个月。他写下这行注释后就提交了代码,未来的工作就变得简单了,只要顺着脑子里的思路往下写就好,他甚至连未来可能要用到的参数都已经预留好了。不过,这是他在腾讯地图留下的最后一行代码,随即他遭到了腾讯地图开除。原因当然不是因为这行注释,而是他在提交代码的时候将本地工作分支覆盖了主分支,并将它推送到了远端。这在腾讯地图项目组引起了一场不大不小的轰动,他的上司为他出头也受到波及,最终没能留住他。他后来去了百度地图,并将他在腾讯地图所做的工作又依葫芦画瓢做了一遍。随后他去了携程,大概还是做地图。后来他娶了一位钢琴老师,在上海安了家,在我们那个小圈子里算是混的有头有脸的了。
我所认识的‘nimomeng’同学是一个动不动就爱删库的家伙,他在学习数据库主外键时候,把自己的数据表用主外键关系捆称了一团乱麻,以至于任何的单表操作都会‘嘣’的一声弹出主外键冲突警告。然后就删库,重新建表。我当然看不惯他这样搞。‘你这样搞不费劲吗?’,我终于忍不住了。‘没关系,这又搞不坏电脑,我还可以多练习一下sql命令’。随后他向我展示了一下他所掌握的课堂上没有讲的诸多命令,尤其他向我演示‘xact_abort’命令的时候,我彻底叹服。以后,随他怎么乱搞主外键关系,我都不再说什么。
那些都是非常遥远的记忆了。言归正传,Git当然并不复杂,也并非那么简单。问题在于你是否理解了git的基本原理,你是否对git的诸多命令背后的引发的副作用有清晰的认知。天堂和地狱,都在一念之间。如果你之间有用过svn,将有助于你更好地理解git。
git的基本原理
Svn很像一个BBS聊天室的应用,客户端对信息的收发都经过中心服务器的处理,由中心服务器集中处理所有消息,并群发给所有客户端。svn的版本管理全部交由中心服务器处理,客户端只做代码提交和下载。git被称为分布式版本控制,所谓分布式,即是所有git客户端都由自己独立的仓库。而所谓的远端,仅仅是相当于一个FTP文件服务器,顺便记录一下你的上传和下载操作。因此,git的核心是本地仓库。下面就让我们来了解一下本地仓库的一些基本操作。
本地仓库的基本操作。
和svn保存代码文件不同,git记录的是动作快照。所谓快照,可以理解为是一条日志记录,即记录你的每一步git动作。比如,你add一下,它会记录。你rm一下,它也会记录。当你需要恢复以前的代码状态时,就可以通过动作回放来达到目的,就像数据库可以通过日志恢复被删除的Data文件一样。是不是非常的简单呢?你还需要理解一下分支的概念,git的所有操作都基于分支的。本地版本库就是一个分支集合,本地版本库一旦创建,即会创建一个默认分支master。这个分支除了不能删除以外并没有任何特别之处。一个分支相当于一个日志文件,即在master分支下的任何操作都会记录到master日志中,在wsj分支下的任何操作都会记录到wsj日志中。因此,切换分支就相当于切换不同的工作环境,在物理上,就相当于切换到了不同的工作目录。理解这一点非常关键,这是git最具特色的地方。这里只做理论上的概述,你如果不能理解它,请务必查阅其他资料,在脑子里形成一个非常具象的概念模型。关于分支,有以下细节需要注意:
1.本地版本库一旦创建,就会创建一个本地Master分支,并将当前工作分支切换到Master下。
2.在当前工作分支创建另一个分支,并不是创建一个空分支,而是将当前工作分支的所有快照记录都复制给新的分支。
关于第二条,这里稍作一下解释。比如,你创建一个空目录,并用cmd命令进入该目录,在cmd中执行git init。这时候你就已经出于master分支下,你在目录中新建一个文件并通过add和commit将文件提交到master分支下。这时,你在git branch xxx创建一个分支。你通过git checkout切换新分支下,会发现新分支的工作目录并非是一个空目录,而是有刚刚在master分支下添加的那个文件。关于这一点,是很好理解的。如果不能理解,请在去查阅别的资料。那么,接下来,我们再去了解一下branch的基本结构。
branch的基本结构
branch在逻辑上相当于一个日志文件,用于记录本地的git动作。在物理上,一个branch包含以下部分:
1.工作目录 工作目录是指工程目录中除.git目录的所有文件资源。
2.暂存区 git add命令会将新增和修改内容写入暂存区。
3.版本库 git commit命令将暂存区的内容写入版本库。
由于在实际编码中,经常会新增和修改文件,因此,以下命令是用的最为频繁的。
1.git add //将修改下入暂存去
2.git status //查看当前工作目录中的文件状态
3.git commit // 将暂存区的内容提交到版本库中
将本地分支推送到远端
这一步非常的简单,我们可以通过git remote add 添加一个远端,并给远端设置一个别名。然后通过git push xxx 将当前分支分支推送到远端。这里有一个细节非常需要注意,正是这个细节所隐藏的坑让‘nomomeng’同学被腾讯地图开除。git并不限制用户只能推送本地master分支到远端,事实上,所有本地分支都能向远端推送。通常来说,我们都会将已经完成的功能合并到本地master分支中,最后由master分支向远程推送,因此我们的本地master一般都和远程仓库保持一致。但这并非git硬性规定的操作规则,而仅仅是一种大家都比较认可的代码提交策略。如果这一点不清楚,那么就极有可能犯错。千万记住,git push 的时候一定明白自己push的是哪个分支,这个分支又是做什么用的。
关于git,在敲下每一行git命令后,按回车之前请花两秒钟想想这个命令会引发什么样的副作用,保持这样的习惯,你就永远不会犯错误。好了,就到这里吧,希望能对你有所帮助。
git init //初始化本地仓库。
git clone //拷贝远程项目到本地
git diff //vim比较两个分支之间的差异
git commit //将暂件移除git,不做物理伤处
git mv //移动一个文件
git branch //列除当前所有分支,如果后面加参数则是创建一个新分支
git checkout //切换分支存区修改提交到版本库
git reset HEAD //撤销暂存区修改,由版本库内容替换暂存区内容
git rm //将文
git merge //将目标分支合并到当前分支