使用Git协作开发,注意几点避免代码覆盖事故
由于Git库在客户端和服务器端都有仓库,涉及到仓库之间的同步,所以使用不当容易造成事故。Git提倡灵活使用分支进行开发协作,方法有多种:如Git官网上的书中提到,某些大的开源项目的做法是开发者各自建立自己的开发分支,然后合并到共享的开发分支上,合并时需要有管理员审核通过后才能合并到主分支上。
而实际开发过程中,我们发现很多事故就是出在merge时,因此简单的大家使用同一个develop分支,尽量少让初级人员进行合并。基于大家共享的开发分支,下图示说明代码覆盖事故产生的过程:
- Step1和Step2:Jack和Rose同时从服务器端更新了文件A和B;
- Step 3:Jack对B进行了修改,变成新版的B+
- Step4:Jack在本地仓库提交了修改后的B+
- Step5:Jack将本地仓库的修改Push到了远程仓库
Step6:Rose在本地修改了A,变成了新版本的A+
Step7:Rose 在本地仓库提交了修改后的A+
Step8:Rose准备将本地仓库的修改Push到远程仓库失败,因为Jack已经有了新的提交
Step9:Rose需要从Server端Pull最新的修改到本机来,git会在没有冲突的情况下自动merge修改,若存在冲突会要求Rose手动合并。
需要注意,Pull相当于先fetch在merge,这里很容易出错:比如Rose无意间也改动了B,merge解决冲突的时候覆盖了Jack的代码,在step10提交时事故就发生了。
Step10:Rose提交代码,若操作无误,正常流程结束。
此外,我们发现常常发生事故的场景是,开发者长时间不提交代码,提交代码时要进行大量的解决冲突的工作,初级开发者解决冲突不当就会覆盖别人的代码。
另一种常见的造成失误的情况就是,对IDE里的工具不熟悉、粗心大意导致失误,例如不小心选了强制覆盖远程代码的选型,造成代码覆盖事故。
根据对上述分析可知,使用同一个开发分支的协作开发者注意以下事项,就可减少错误:
首先要了解Git的基本原理和基本命令,知其然就知其所以然,就能减少失误。
及时提交代码、更新代码,避免因为长时间不更新代码而产生过多冲突文件,在解决冲突的过程中初级人员也是非常容易出错的。
开发人员一定要熟悉你所使用的git工具,无论是小乌龟还是IDE里集成的git工具,避免因为对工具不熟悉造成误操作。
本地修改前应该尽可能的避免本地库与远程之间有过多的差异,本地修改前执行一次git pull先把远程更新拉到本地;
- 推荐的操作步骤,提交前先把本地修改存入栈,然后从服务器端更新代码,这样可以避免过多的代码merge:
1、git stash
2、git pull
3、git pop
4、若有冲突解决冲突
- 1
- 2
- 3
- 4
- 当解决冲突时,若不是你修改过的文件就采用远程库里的版本,对于你自己修改过的文件也要查看日志找到提交人,跟他确认后再进行冲突解决,然后提交。
若事故已经发生了,如何解决问题
如果事故已经发生了,首先应该查看日志分析原因,找到出问题的节点撤销操作、回滚代码。关于事故的分析非常重要,今天来不及写了,先列一些参考资料和相关命令,回头慢慢补充
查看日志,分析原因
git log可以查看日志,选项的选项很多,详细可以查看官方文档和教程。
Windows下的Tortorisgit等图形化工具,提供了更友好的日志查看功能,本来想写写的,发现一篇博文讲的很详细,请参考:
http:\/\/blog.csdn.net\/tantexian\/article\/details\/42641457
#log --graph 结合使用时尤其有用,这个选项添加了一些ASCII字符串来形象地展示你的分支、合并历史 $ git log --pretty=format:"%h %s" --graph
- 1
- 2
- 3
- 4
回滚代码
撤销、回退相关命令,官方文档有详细的说明,请参考https:\/\/git-scm.com\/blog\/2010\/03\/02\/undoing-merges.html
这里先简单列一些:运行带有 --amend 选项的提交命令尝试重新提交:git commit --amend
取消暂存:git reset HEAD <file>...
丢弃工作区的修改:git checkout -- filename
Merge错了,需要回滚,若merge后还没有修改可以用reset,若已经修改了则需要用revert
#Git撤销merge,merge后还未进行任何操作,可以reset
$ git checkout [merge操作所在的分支]
$ git reset --hard [merge前的版本号]
#Git撤销merge,merge后已经进行了操作,需要revert
$ git revert -m 【要撤销的那条merge线的编号】 【merge前的版本号】