第八节《冲突解决》
在真实的运行环境中,用户的协同并不会一帆风顺,只要有合并就可能会有冲突,前面我们看到只要把共享版本库中的最新提交直接拉回到本地,然后就可以推送了,然而事实并不是这样....
<1>用户user1向版本库推送时,因为user2强制推送已经改变了共享版本库的提交状态,导致user1推送失败
<2>用户user1执行拉回操作的第一阶段,将共享版本库master分支的最新提交获取到本地,并更新到本地版本库特定的引用refs/remotes/origin/master
<3>用户user1执行拉回操作的第二阶段,将本地分支master和共享版本库本地跟踪分支origin/master进行合并
<4>用户user1执行推送操作,将本地提交推送到共享版本库
实际上git pull是由两个步骤组成:一个是git fetch和git merge。
产生冲突的情况及解决办法:
1、两个用户修改了不同的文件
<1>用户user1修改team/user1.txt文件,提交并推送到共享服务器
[root@git project]# echo "hack by user1 at `date`" >> team/user1.txt
[root@git project]# git add -u
[root@git project]# git commit -m "update team/user1.txt"
[master 66cd761] update team/user1.txt
1 files changed, 1 insertions(+), 0 deletions(-)
[root@git project]# git push
Counting objects: 7, done.
Compressing objects: 100% (4/4), done.
Writing objects: 100% (4/4), 407 bytes, done.
Total 4 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (4/4), done.
To file:///path/to/repos/shared.git
fbae0b3..66cd761 master -> master
<2>用户user2修改team/user2.txt文件提交
[root@git project]# echo "hack by user2 at `date`" >> team/user2.txt
[root@git project]# git add -u
[root@git project]# git commit -m "update team/user2.txt"
[master aada835] update team/user2.txt
1 files changed, 1 insertions(+), 0 deletions(-)
<3>用户user2在推送时会遇到非快进式推送错误
[root@git project]# git push
To file:///path/to/repos/shared.git
! [rejected] master -> master (non-fast-forward)
error: failed to push some refs to 'file:///path/to/repos/shared.git'
To prevent you from losing history, non-fast-forward updates were rejected
Merge the remote changes before pushing again. See the 'Note about
fast-forwards' section of 'git push --help' for details.
<4>用户user2执行git fetch操作,获取到的提交更新到本地用于跟踪共享版本库master分支的本地引用origin/master中
[root@git project]# git fetch
remote: Counting objects: 7, done.
remote: Compressing objects: 100% (4/4), done.
remote: Total 4 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (4/4), done.
From file:///path/to/repos/shared
fbae0b3..66cd761 master -> origin/master
<5>用户user2执行合并操作,完成自动合并
[root@git project]# git merge origin/master
Merge made by recursive.
team/user1.txt | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
<6>用户user2推送合并后的本地版本库
[root@git project]# git push
Counting objects: 12, done.
Compressing objects: 100% (7/7), done.
Writing objects: 100% (7/7), 749 bytes, done.
Total 7 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (7/7), done.
To file:///path/to/repos/shared.git
66cd761..5a0af89 master -> master
<7>查看提交日志
[root@git project]# git log -3 --graph --stat
* commit 5a0af89a0b71f10358c5d7034d9ec9ff5bad4332
|\ Merge: aada835 66cd761
| | Author: user2 <user2@89mc.com>
| | Date: Tue Aug 29 16:03:48 2017 +0800
| |
| | Merge remote branch 'origin/master'
| |
| * commit 66cd7610ba57a5da5b75ee0234ebf5d4330c2cac
| | Author: user1 <user1@89mc.com>
| | Date: Tue Aug 29 15:59:27 2017 +0800
| |
| | update team/user1.txt
team/user1.txt | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
| |
* | commit aada835b917d93d9b31820ca413325fa23f84671
|/ Author: user2 <user2@89mc.com>
| Date: Tue Aug 29 16:01:00 2017 +0800
|
| update team/user2.txt
team/user2.txt | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
2、修改相同文件的不同区域
<1>用户user1修改README文件,在第一行插入User1 hacked
[root@git project]# cat README
User1 hacked.
Hello
<2>用户user1对修改进行本地提交并推送到共享版本库
[root@git project]# git add -u
[root@git project]# git commit -m "User1 hack at the beginning."
[master f0595a9] User1 hack at the beginning.
1 files changed, 1 insertions(+), 0 deletions(-)
[root@git project]# git push
Counting objects: 5, done.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 292 bytes, done.
Total 3 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (3/3), done.
To file:///path/to/repos/shared.git
5a0af89..f0595a9 master -> master
<3>用户user2修改自己工作区中的README文件,在最后插入User2 hacked.
[root@git project]# cat README
Hello
User2 hacked.
<4>用户user2对修改进行本地提交
[root@git project]# git add -u
[root@git project]# git commit -m "User2 hack at the end."
[master b255a59] User2 hack at the end.
1 files changed, 1 insertions(+), 0 deletions(-)
<5>用户user2执行git fetch操作,获取到的提交更新到本地
[root@git project]# git fetch
remote: Counting objects: 5, done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 3 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (3/3), done.
From file:///path/to/repos/shared
5a0af89..f0595a9 master -> origin/master
<6>用户user2执行合并操作,并推送
[root@git project]# git merge refs/remotes/origin/master
Auto-merging README
Merge made by recursive.
README | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
[root@git project]# git push
Counting objects: 10, done.
Compressing objects: 100% (4/4), done.
Writing objects: 100% (6/6), 592 bytes, done.
Total 6 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (6/6), done.
To file:///path/to/repos/shared.git
f0595a9..95fa871 master -> master
3、同时更改文件名和文件内容
<1>用户user1在自己的工作区将文件README进行重命名,本地提交并推送
[root@git project]# pwd
/path/to/user1/workspace/project
[root@git project]# mkdir doc
[root@git project]# git mv README doc/README.txt
[root@git project]# git commit -m "move document to doc/."
[master 62a8eee] move document to doc/.
1 files changed, 0 insertions(+), 0 deletions(-)
rename README => doc/README.txt (100%)
[root@git project]# git push
Counting objects: 4, done.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 299 bytes, done.
Total 3 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (3/3), done.
To file:///path/to/repos/shared.git
95fa871..62a8eee master -> master
<2>用户user2在自己的工作区中修改README文件,在文件最后抽入内容,执行本地提交
[root@git project]# pwd
/path/to/user2/workspace/project
[root@git project]# echo "User2 hacked again." >> README
[root@git project]# git add -u
[root@git project]# git commit -m "User2 hack README again."
[master 7a6872f] User2 hack README again.
1 files changed, 1 insertions(+), 0 deletions(-)
<3>用户user2执行git fetch操作,获取到的提交更新到本地
[root@git project]# git fetch
remote: Counting objects: 4, done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 3 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (3/3), done.
From file:///path/to/repos/shared
95fa871..62a8eee master -> origin/master
<4>用户user2执行合并操作,并推送
[root@git project]# git merge refs/remotes/origin/master
Merge made by recursive.
README => doc/README.txt | 0
1 files changed, 0 insertions(+), 0 deletions(-)
rename README => doc/README.txt (100%)
[root@git project]# git push
Counting objects: 10, done.
Compressing objects: 100% (5/5), done.
Writing objects: 100% (6/6), 623 bytes, done.
Total 6 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (6/6), done.
To file:///path/to/repos/shared.git
62a8eee..6809fc0 master -> master
4、更改文件的同一内容
<1>用户user1修改doc/README.txt文件第二行
[root@git project]# cat doc/README.txt
User1 hacked.
Hello,user1.
User2 hacked.
<2>user1对修改进行提交和推送
[root@git project]# git add -u
[root@git project]# git commit -m "say hello to user1."
[master 7234438] say hello to user1.
1 files changed, 1 insertions(+), 1 deletions(-)
[root@git project]# git push
Counting objects: 14, done.
Compressing objects: 100% (5/5), done.
Writing objects: 100% (8/8), 706 bytes, done.
Total 8 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (8/8), done.
To file:///path/to/repos/shared.git
6809fc0..e9e7941 master -> master
<3>用户user2也更改README.txt文件
[root@git project]# cat doc/README.txt
User1 hacked.
Hello,user2.
User2 hacked.
User2 hacked again.
<4>user2进行提交
[root@git project]# git add -u
[root@git project]# git commit -m "say hello to user2."
[master 16bb0a2] say hello to user2.
1 files changed, 1 insertions(+), 1 deletions(-)
<5>user2执行pull操作,遇到冲突
[root@git project]# git pull
remote: Counting objects: 14, done.
remote: Compressing objects: 100% (5/5), done.
remote: Total 8 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (8/8), done.
From file:///path/to/repos/shared
6809fc0..e9e7941 master -> origin/master
Auto-merging doc/README.txt
CONFLICT (content): Merge conflict in doc/README.txt
Automatic merge failed; fix conflicts and then commit the result.
<6>查看一下现在的文件
[root@git project]# cat doc/README.txt
User1 hacked.
<<<<<<< HEAD
Hello,user2. //<<<和===之间的内容是当前分支所更改的内容
=======
Hello,user1. //===和>>>之间的内容是所合并的版本更改的内容
>>>>>>> e9e7941f0e86186bd24b6e251ce3ee9deaf82931
User2 hacked.
User2 hacked again.
<7>手工编辑完成冲突解决
[root@git project]# vim doc/README.txt
User1 hacked.
Hello,user1 and user2.
User2 hacked.
User2 hacked again.
<8>执行提交和推送
[root@git project]# git add -u
[root@git project]# git commit -m "Merge completed: say hello to all users."
[master 5ca3509] Merge completed: say hello to all users.
[root@git project]# git push
Counting objects: 14, done.
Compressing objects: 100% (6/6), done.
Writing objects: 100% (8/8), 710 bytes, done.
Total 8 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (8/8), done.
To file:///path/to/repos/shared.git
e9e7941..5ca3509 master -> master