![11892f675534f8694cfa462b66dd1afa.png](https://i-blog.csdnimg.cn/blog_migrate/b1ac0acbe785c99b8a62463a151aaada.jpeg)
0 引言
Git于我最大的作用无非是2个:
- 版本控制。
- 远程协作。
版本控制:
版本控制顾名思义就是通过Git来控制文件(一般是指代码)的版本。
比如我2020.10.18写好了一份代码code1,我将其命名为版本20201018.
我2020.10.19将code1做了一些修改,添加了一些功能,得到code2,将其命名为版本20201019.
如果现在我发现我在2020.10.19添加的代码我不想要了,我想将代码回退到版本20201018(这是一个很平常的需求),这就需要我们做版本控制了。记录不同版本的代码,以备需要时可以回退。
自然而言想到的办法就是我每获得一个版本的代码,我就手动保存到一个文件中,手动实现版本控制。可是这也太麻烦了吧!!!
Git就是帮助我们高效率地做版本控制的工具。
远程协作:
这一点很明显了:一群人协同完成一个较大型的项目,需要一个以git为核心的平台来对代码、分支、协作者等各个方面来进行管理,我们熟知的GitHub以及国内的Coding等平台,就是在做这样的事情。
当然你也完全可以用Git自己搭一个类似的平台,来协同你和你的小伙伴一起写代码(不过大可不必)。
1 开始
今天我主要想说说使用Git远程协作时,最常出现的一个问题——冲突,及其快速解决方案。
我们使用的实验平台是GitHub
为了方便理解,我们假设一个场景:
小刘和小君决定共同开发一个名为“what-for-lunch”的项目,来仔细规划午餐吃什么
小刘和小君经过商量,规划了未来三天的午餐内容:
2020.10.19:
炸酱面、荷包蛋、玉米汁
2020.10.20:
酱香味麻辣香锅、2份米饭
2020.10.21:
广式香肠滑蛋饭、竹荪排骨汤
小刘commit并push了第一版本的plan到GitHub repo what-for-lunch: git commit -m "init plan"
小君也相应地将对应的plan pull到了本地。
此时使用git log命令查看可得:
commit
02618d43e2a554e4aa69ea1f0193739fed65b9dd为commit id,可以理解成是项目的版本号。
此时,小刘本地、小君本地、GitHub三者保存的项目版本是完全一致的。
因为commit id过长,图中直接以commit id前10位来代表项目版本号:
![e7b735fc3c8c85b9562d90db077ea57b.png](https://i-blog.csdnimg.cn/blog_migrate/58169b608a10013576d687ada08d8897.png)
2 冲突产生
小君是个嗜辣的四川人,不是很喜欢甜口的酱香味麻辣香锅,(她)转念一想,酱香味有什么好吃的,干脆换成麻辣味吧,这样才够爽。
于是她将plan修改成了
2020.10.19:
炸酱面、荷包蛋、玉米汁
2020.10.20:
麻辣味麻辣香锅、2份米饭
2020.10.21:
广式香肠滑蛋饭、竹荪排骨汤
紧接着,小君便直接commit, push到了GitHub上
此时小君这里git log可以看到自己刚刚commit的记录:
commit
因为他还push了,因此小君本地、GitHub保存的项目版本是一致的。即:
![b1f823f931920333add8174f69b54fdc.png](https://i-blog.csdnimg.cn/blog_migrate/4ccc35bcf0093d9d903831ec7bd80942.png)
好巧不巧的是,小刘觉得最近自己吃酱香味麻辣香锅太多了,想换换口味,想尝试一下新推出的咖喱味,于是他将“plan”修改:
2020.10.19:
炸酱面、荷包蛋、玉米汁
2020.10.20:
咖喱味麻辣香锅、2份米饭
2020.10.21:
广式香肠滑蛋饭、竹荪排骨汤
可是,当他兴冲冲地去commit,push之后却发现:
![cfc2742176e8ffbc91bbb0de9f515a39.png](https://i-blog.csdnimg.cn/blog_migrate/6d9d765623cc36077b955c2e1b76d268.png)
此时小刘用git log查看commit记录:
commit
这下小刘明白了,一定是小君单方面做了某些修改并已经push到了github,导致目前小刘本地版本与GitHub版本在某地方冲突了,即:
![c8b8a685b2b882400d6f50413e7e6388.png](https://i-blog.csdnimg.cn/blog_migrate/2f6b606fca65b97f0965d1bbdec9b393.png)
3 冲突解决
接下来该怎么解决冲突呢?
冲突肯定是需要在本地先解决好的,然后再push到GitHub。
小刘的大致思路如下:
- 直接将GitHub最新版本的项目(47952b8689)拉下来。--> git pull
- 这时肯定就会在本地产生冲突,手动解决好冲突。
- 将无冲突的版本push到GitHub. --> git push
补充说明:当遇到有本地冲突,无法git pull时,可以尝试git stash和git stash pop
git stash
git pull
git stash pop
git push
接下来隆重介绍一下git stash和git stash pop
git stash可以将当前的修改保存起来,并使得代码回退到之前的clean状态
git stash pop将之前保存的修改释放出来,与当前版本合并,可能会引发冲突,需要手动解决冲突
小刘git pull之后发现果然产生了冲突:
![5f93f086c768b101d540bf5f049217f1.png](https://i-blog.csdnimg.cn/blog_migrate/8c3a1e5f093fb61b80f71d17b919d4ac.png)
小刘打开冲突文件,找到了冲突:
![aad84d9f480455c71286a9d3a386f6cb.png](https://i-blog.csdnimg.cn/blog_migrate/1da54e2fcac90f89107af313d2d6702c.png)
上红框为小刘版本,下红框为小君版本
此时需要手动解决冲突,也就是删除一个,保留一个。
小刘想了想,男生应该保持绅士风度,于是决定放弃咖喱味,选择麻辣味!
于是,小刘修改成了:
2020.10.19:
炸酱面、荷包蛋、玉米汁
2020.10.20:
麻辣味麻辣香锅、2份米饭
2020.10.21:
广式香肠滑蛋饭、竹荪排骨汤
补充说明:使用VS Code这类工具手动解决冲突会更加方便:
将项目在VS Code中打开:
![8605ed11d4c162360371e5cf902eea8d.png](https://i-blog.csdnimg.cn/blog_migrate/b02b26e76f260db7e7e709a6d101d1c3.jpeg)
点击Accept Current Change,就是接受当前的“咖喱味麻辣香锅”
点击Accept Incoming Change,就是接受新来的“麻辣味麻辣香锅”
小刘毫不犹豫地点击了“Accept Incoming Change”
4 后记
冲突解决了,从此小刘和小君过上了幸福的生活。
本故事纯属虚构,人物也都是虚构。如有雷同,不胜荣幸。
最佳实践:
在每一次coding之前,要养成先pull的好习惯,以确保当前本地版本是与服务器一致的,是最新的,然后再在此基础上再去写代码。
这样做可以避免绝大多数的冲突。