冲突:
merge
在做合并的时候,是有一定的自动合并能力的:如果一个分支改了 A 文件,另一个分支改了 B 文件,那么合并后就是既改 A 也改 B,这个动作会自动完成;如果两个分支都改了同一个文件,但一个改的是第 1 行,另一个改的是第 2 行,那么合并后就是第 1 行和第 2 行都改,也是自动完成。
但,如果两个分支修改了同一部分内容,merge
的自动算法就搞不定了。这种情况 Git 称之为:冲突(Conflict)。
在现实的团队开发中,是同时并行开发的,所以必然会出现当一人 push
代码时,中央仓库已经被其他同事先一步 push
了的情况。
示例:
前置条件,有两个本地仓库,目录分别是:test-marketing-testcase 和 test-marketing-testcase-another 最开始两个目录里的内容是一样的
- 切到 test-marketing-testcase-another 目录,假扮成你的同事做一个
commit
,然后push
到 GitHub
➜ test-marketing-testcase-another git:(master) touch 1.txt ➜ test-marketing-testcase-another git:(master) ✗ vi 1.txt ➜ test-marketing-testcase-another git:(master) ✗ git add . ➜ test-marketing-testcase-another git:(master) ✗ git commit -m "添加1.txt" [master bc77233] 添加1.txt 1 file changed, 3 insertions(+) create mode 100644 1.txt ➜ test-marketing-testcase-another git:(master) git push Counting objects: 3, done. Delta compression using up to 4 threads. Compressing objects: 100% (2/2), done. Writing objects: 100% (3/3), 277 bytes | 0 bytes/s, done. Total 3 (delta 1), reused 0 (delta 0) To git@git.souche-inc.com:testGroup/test-marketing-testcase.git d33cf17..bc77233 master -> master
2.切回 test-marketing-testcase 变回你自己,做一个不一样的 commit
。
➜ test-marketing-testcase-another git:(master) cd /Users/chichi/Documents/gittest/test-marketing-testcase ➜ test-marketing-testcase git:(master) touch 2.txt ➜ test-marketing-testcase git:(master) ✗ vi 2.txt ➜ test-marketing-testcase git:(master) ✗ git add . ➜ test-marketing-testcase git:(master) ✗ git commit -m "添加2.txt" [master 7481b5a] 添加2.txt 1 file changed, 1 insertion(+) create mode 100644 2.txt
这个时候,远端中央仓库已经有了别人 push
的 commit
,现在你如果 push
的话:
➜ test-marketing-testcase git:(master) git push To git@git.souche-inc.com:testGroup/test-marketing-testcase.git ! [rejected] master -> master (fetch first) error: failed to push some refs to 'git@git.souche-inc.com:testGroup/test-marketing-testcase.git' hint: Updates were rejected because the remote contains work that you do hint: not have locally. This is usually caused by another repository pushing hint: to the same ref. You may want to first integrate the remote changes hint: (e.g., 'git pull ...') before pushing again. hint: See the 'Note about fast-forwards' in 'git push --help' for details.
从上图中的提示语可以看出来,由于 GitHub 的远端仓库上含有本地仓库没有的内容,所以这次 push
被拒绝了。这种冲突的解决方式其实很简单:先用 pull
把远端仓库上的新内容取回到本地和本地合并,然后再把合并后的本地仓库向远端仓库推送。
git pull
这次的 git pull
操作并没有像之前的那样直接结束,而是进入了上图这样的一个输入提交信息的界面。这是因为当 pull
操作发现不仅远端仓库包含本地没有的 commit
s,而且本地仓库也包含远端没有的 commit
s 时,它就会把远端和本地的独有 commit
s 进行合并,自动生成一个新的 commit
,而上图的这个界面,就是这个自动生成的 commit
的提交信息界面。另外,和手动的 commit
不同,这种 commit
会自动填入一个默认的提交信息,简单说明了这条 commit
的来由。你可以直接退出界面来使用这个自动填写的提交信息,也可以修改它来填入自己提交信息。
在退出提交信息的界面后,这次 pull
就完成了:远端仓库被取到了本地,并和本地仓库进行了合并。在这个时候,就可以再 push
一次了。由于现在本地仓库已经包含了所有远端仓库的 commits,所以这次 push
不会再失败:
➜ test-marketing-testcase git:(master) git push Counting objects: 5, done. Delta compression using up to 4 threads. Compressing objects: 100% (4/4), done. Writing objects: 100% (5/5), 516 bytes | 0 bytes/s, done. Total 5 (delta 2), reused 0 (delta 0) To git@git.souche-inc.com:testGroup/test-marketing-testcase.git bc77233..b0ce5b6 master -> master
这样,就把 push
时本地仓库和远端仓库内容冲突的问题解决了。
原文参考:https://juejin.im/book/5a124b29f265da431d3c472e/section/5a124c1f6fb9a0450b65fd3e