假定A、B两用户对Git项目做操作,遇到场景:B在提交了一次commit之后,A将项目clone了下来,并在此基础上进行操作,但B又继续进行操作更新(对不同文件进行修改)并再次提交了commit到服务端。
用户B将远端库上的项目代码clone到本地,准备在此基础上进行项目代码的修改:
git clone https://gitee.com/asdfv1929/test.git test
git config --add --local user.name tom
git config --add --local user.email [email protected]
B的本地端更新远程库,将新建的分支纳入到本地:
git remote update
Fetching gitee
From https://gitee.com/asdfv1929/test
* [new branch] add_commands -> gitee/add_commands
git branch -av
* master 73c6ad9 merge readme
temp 1395813 add readme
remotes/gitee/add_commands 73c6ad9 merge readme
remotes/gitee/master 73c6ad9 merge readme
remotes/gitee/temp 1395813 add readme
B进入到新分支中,修改其下的readme
文件内容,并最终推送到远端服务器上。
git checkout -b add_commands gitee/add_commands
Switched to a new branch 'add_commands'
branch 'add_commands' set up to track 'gitee/add_commands'.
~/Desktop/test (add_commands)
vi readme
~/Desktop/test (add_commands)
git add -u
~/Desktop/test (add_commands)
git status
On branch add_commands
Your branch is up to date with 'gitee/add_commands'.
Changes to be committed:
(use "git restore --staged ..." to unstage)
modified: readme
~/Desktop/test (add_commands)
git commit -m 'add commands in readme'
[add_commands a82933e] add commands in readme
1 file changed, 2 insertions(+)
~/Desktop/test (add_commands)
git push
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Delta compression using up to 6 threads
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 310 bytes | 103.00 KiB/s, done.
Total 3 (delta 1), reused 0 (delta 0), pack-reused 0
remote: Powered by GITEE.COM [GNK-6.4]
To https://gitee.com/asdfv1929/test.git
73c6ad9..a82933e add_commands -> add_commands
用户A看到了B的最新一次提交后,准备在此基础上修改add_commands
分支上的文件内容。
git branch -av
* master 73c6ad9 merge readme
remotes/origin/HEAD -> origin/master
remotes/origin/add_commands a82933e add commands in readme
remotes/origin/master 73c6ad9 merge readme
remotes/origin/temp 1395813 add readme
# 切换到分支上,若本地没有则自动创建,并与远程库中的同步分支进行关联
git checkout -b add_commands origin/add_commands
Switched to a new branch 'add_commands'
branch 'add_commands' set up to track 'origin/add_commands'.
用户A在分支中修改了另一个文件file1
的内容,并进行了commit。
vi file1
git commit -am 'edit file1'
warning: LF will be replaced by CRLF in file1.
The file will have its original line endings in your working directory
[add_commands 4fc78ae] edit file1
1 file changed, 1 insertion(+)
注意,此时A并未push到远端库上!
在用户A提交了commit但尚未push到远端服务器时,用户B又一次更新了,并且push到了远端上:
vi readme
~/Desktop/test (add_commands)
git commit -am "second edit of B"
[add_commands 88ea401] second edit of B
1 file changed, 1 insertion(+)
~/Desktop/test (add_commands)
git push
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Delta compression using up to 6 threads
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 289 bytes | 289.00 KiB/s, done.
Total 3 (delta 2), reused 0 (delta 0), pack-reused 0
remote: Powered by GITEE.COM [GNK-6.4]
To https://gitee.com/asdfv1929/test.git
a82933e..88ea401 add_commands -> add_commands
之后,A准备将本地代码push到远端库上时,就会报错,报错原因是远端包含了一些work但本地是没有的,其实就是用户B的最新提交和A本地的内容发生了冲突。
git push
To https://gitee.com/asdfv1929/test.git
! [rejected] add_commands -> add_commands (fetch first)
error: failed to push some refs to 'https://gitee.com/asdfv1929/test.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.
报错原因是B提交了最新一次内容,但A是在B的上一次提交内容基础上进行修改的,所以此时A只需要将远端分支上最新的内容拉取下来,并将其与本地内容进行合并,最后重新push到远端服务器上即可。
git fetch gitee
git merge gitee/add_commands # 此时A处在add_commands分支上
Merge made by the 'ort' strategy.
readme | 1 +
1 file changed, 1 insertion(+)
git push gitee
Enumerating objects: 9, done.
Counting objects: 100% (8/8), done.
Delta compression using up to 6 threads
Compressing objects: 100% (4/4), done.
Writing objects: 100% (5/5), 555 bytes | 555.00 KiB/s, done.
Total 5 (delta 1), reused 0 (delta 0), pack-reused 0
remote: Powered by GITEE.COM [GNK-6.4]
To https://gitee.com/asdfv1929/test.git
88ea401..5283e22 add_commands -> add_commands
远端库上,file1
文件和readme
文件的更新内容同时存在了。
不同人修改了同一文件的不同区域。例如,用户A、B都对readme
文件进行了修改,但修改的是文件中的不同区域部分。
用户B修改readme
文件中间区域内的内容,并进行了commit提交。
vi readme
asdfv@DESKTOP-JWJ MINGW64 ~/Desktop/test (add_commands)
$ git commit -am 'userB edit'
[add_commands 0a9d613] userB edit
1 file changed, 1 insertion(+), 1 deletion(-)
注意,此时B是未push到远端的状态!
用户A也在修改readme
文件的内容,但是在另一个区域部分,例如文件末尾;
commit完成后便push到服务端。
vi readme
/g/test (add_commands)
git commit -am 'userA edit'
[add_commands 7fcd9b5] userA edit
1 file changed, 2 insertions(+)
/g/test (add_commands)
git push gitee
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Delta compression using up to 6 threads
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 298 bytes | 298.00 KiB/s, done.
Total 3 (delta 2), reused 0 (delta 0), pack-reused 0
remote: Powered by GITEE.COM [GNK-6.4]
To https://gitee.com/asdfv1929/test.git
5283e22..7fcd9b5 add_commands -> add_commands
此时,用户B将其本地的commit去push推送到远端时,就会发生报错。
git push
To https://gitee.com/asdfv1929/test.git
! [rejected] add_commands -> add_commands (fetch first)
error: failed to push some refs to 'https://gitee.com/asdfv1929/test.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.
用户B只需再次将远端库代码拉取到本地,并进行合并,最后重新push到远端即可。
git fetch gitee
remote: Enumerating objects: 5, done.
remote: Counting objects: 100% (5/5), done.
remote: Compressing objects: 100% (3/3), done.
remote: Total 3 (delta 2), reused 0 (delta 0), pack-reused 0
Unpacking objects: 100% (3/3), 278 bytes | 8.00 KiB/s, done.
From https://gitee.com/asdfv1929/test
5283e22..7fcd9b5 add_commands -> gitee/add_commands
~/Desktop/test (add_commands)
git merge
Auto-merging readme
Merge made by the 'ort' strategy.
readme | 2 ++
1 file changed, 2 insertions(+)
git push
Enumerating objects: 10, done.
Counting objects: 100% (10/10), done.
Delta compression using up to 6 threads
Compressing objects: 100% (6/6), done.
Writing objects: 100% (6/6), 603 bytes | 603.00 KiB/s, done.
Total 6 (delta 4), reused 0 (delta 0), pack-reused 0
remote: Powered by GITEE.COM [GNK-6.4]
To https://gitee.com/asdfv1929/test.git
7fcd9b5..2260cf2 add_commands -> add_commands
可以看到,用户A、B两人对同一文件readme
的不同区域上的编辑内容都呈现出来了。
多个用户修改相同文件的相同区域。
例如,用户A和B都基于相同commit在做修改更新操作,且是对同一文件的相同区域做操作。
用户A修改readme
文件后,进行commit之后便立即push了(先B一步推送)。
vi readme
~/Desktop/test (add_commands)
git status
On branch add_commands
Your branch is up to date with 'gitee/add_commands'.
Changes not staged for commit:
(use "git add ..." to update what will be committed)
(use "git restore ..." to discard changes in working directory)
modified: readme
no changes added to commit (use "git add" and/or "git commit -a")
git commit -am 'userA edit readme'
[add_commands dd37a4d] userA edit same file same region
1 file changed, 2 insertions(+)
git push gitee
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Delta compression using up to 6 threads
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 304 bytes | 304.00 KiB/s, done.
Total 3 (delta 2), reused 0 (delta 0), pack-reused 0
remote: Powered by GITEE.COM [GNK-6.4]
To https://gitee.com/asdfv1929/test.git
2260cf2..dd37a4d add_commands -> add_commands
用户B此时也在修改readme
文件,且修改的区域与用户A相同,都是在文件的末尾。
vi readme
/g/test (add_commands)
git commit -am"userB edit readme"
[add_commands 6b86e17] userB edit readme
1 file changed, 1 insertion(+)
但此时用户B去push时,就会报错。
/g/test (add_commands)
git push gitee
To https://gitee.com/asdfv1929/test.git
! [rejected] add_commands -> add_commands (fetch first)
error: failed to push some refs to 'https://gitee.com/asdfv1929/test.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.
遇到报错,那么用户B就需要先将远端库最新版本拉取下来,这边使用pull
命令,但遇到告警:Automatic merge failed
。这是Git在自动进行合并时发生冲突了,因为两用户都在同一文件的相同区域进行了编辑,Git就无法判断出做什么操作:是都保留、只保留A内容或者只保留B内容。这就需要用户来进行干预选择。
/g/test (add_commands)
git pull gitee
remote: Enumerating objects: 5, done.
remote: Counting objects: 100% (5/5), done.
remote: Compressing objects: 100% (3/3), done.
remote: Total 3 (delta 2), reused 0 (delta 0), pack-reused 0
Unpacking objects: 100% (3/3), 268 bytes | 11.00 KiB/s, done.
From https://gitee.com/asdfv1929/test
a5658ce..4994050 add_commands -> gitee/add_commands
Auto-merging readme
CONFLICT (content): Merge conflict in readme
Automatic merge failed; fix conflicts and then commit the result.
此时去查看readme
文件的内容:
/g/test (add_commands|MERGING)
cat readme
this is a test of push
second edit
hahhahahahaha
hahahahahah
userB edit readme between haha-content
content of add_commands branch
second edit of user B
userA edit readme in the end.
<<<<<<< HEAD
userB edit readme!!!
=======
userA edit readme!!!
>>>>>>> 4994050c587d0f11b63c5e06d2dcc7a481e6c88b
其中,<<<<<<< HEAD
与"=======" 之间的内容表示为自己(用户B)的编辑内容,"======="和>>>>>>> 4994050c587d0f11b63c5e06d2dcc7a481e6c88b
之间的内容为另一用户(用户A)的内容。
这边选择都保留,只需要把上面readme
文件中的三处特殊标记删除并保存,最后提交commit和push即可。
vi readme
...
userB edit readme!!!
userA edit readme!!!
/g/test (add_commands|MERGING)
git status
On branch add_commands
Your branch and 'gitee/add_commands' have diverged,
and have 1 and 1 different commits each, respectively.
(use "git pull" to merge the remote branch into yours)
You have unmerged paths.
(fix conflicts and run "git commit")
(use "git merge --abort" to abort the merge)
Unmerged paths:
(use "git add ..." to mark resolution)
both modified: readme
no changes added to commit (use "git add" and/or "git commit -a")
/g/test (add_commands|MERGING)
git commit -am'resolve 2 users content'
[add_commands b6a3675] resolve 2 users content
/g/test (add_commands)
git push
Enumerating objects: 10, done.
Counting objects: 100% (10/10), done.
Delta compression using up to 6 threads
Compressing objects: 100% (6/6), done.
Writing objects: 100% (6/6), 548 bytes | 548.00 KiB/s, done.
Total 6 (delta 4), reused 0 (delta 0), pack-reused 0
remote: Powered by GITEE.COM [GNK-6.4]
To https://gitee.com/asdfv1929/test.git
4994050..b6a3675 add_commands -> add_commands
多人同时变更了文件名称及其内容。
用户A对文件file1
进行了重命名,并进行了commit,但尚未push。
git mv file1 file.txt
~/Desktop/test (add_commands)
git status
On branch add_commands
Your branch is up to date with 'gitee/add_commands'.
Changes to be committed:
(use "git restore --staged ..." to unstage)
renamed: file1 -> file.txt
~/Desktop/test (add_commands)
git commit -am'mv file1 file.txt'
[add_commands 1f27e65] mv file1 file.txt
1 file changed, 0 insertions(+), 0 deletions(-)
rename file1 => file.txt (100%)
用户B修改了同一文件file1
的内容,且进行了commit。
/g/test (add_commands)
$ vi file1
/g/test (add_commands)
git commit -am'userB add content in file1'
[add_commands 850703b] userB add content in file1
1 file changed, 2 insertions(+)
用户A先一步进行了push,此时远端库发生了更新。
~/Desktop/test (add_commands)
git push gitee
Enumerating objects: 3, done.
Counting objects: 100% (3/3), done.
Delta compression using up to 6 threads
Compressing objects: 100% (2/2), done.
Writing objects: 100% (2/2), 279 bytes | 279.00 KiB/s, done.
Total 2 (delta 0), reused 0 (delta 0), pack-reused 0
remote: Powered by GITEE.COM [GNK-6.4]
To https://gitee.com/asdfv1929/test.git
b6a3675..1f27e65 add_commands -> add_commands
后面,用户B再去push时就会报错。
/g/test (add_commands)
git push gitee
To https://gitee.com/asdfv1929/test.git
! [rejected] add_commands -> add_commands (fetch first)
error: failed to push some refs to 'https://gitee.com/asdfv1929/test.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.
此时就需要用户B重新将远端库上最新版本库pull拉取到本地,Git会自动将两处变动进行合并(A的重命名和B的添加内容),最后重新push即可。
/g/test (add_commands)
git pull gitee
remote: Enumerating objects: 3, done.
remote: Counting objects: 100% (3/3), done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 2 (delta 0), reused 0 (delta 0), pack-reused 0
Unpacking objects: 100% (2/2), 259 bytes | 18.00 KiB/s, done.
From https://gitee.com/asdfv1929/test
b6a3675..1f27e65 add_commands -> gitee/add_commands
Merge made by the 'ort' strategy.
file1 => file.txt | 0
1 file changed, 0 insertions(+), 0 deletions(-)
rename file1 => file.txt (100%)
/g/test (add_commands)
ls
file.txt file2 readme
/g/test (add_commands)
cat file.txt
user A edit file1
userB edit file1!!!
/g/test (add_commands)
git push
Enumerating objects: 8, done.
Counting objects: 100% (8/8), done.
Delta compression using up to 6 threads
Compressing objects: 100% (4/4), done.
Writing objects: 100% (5/5), 651 bytes | 651.00 KiB/s, done.
Total 5 (delta 0), reused 0 (delta 0), pack-reused 0
remote: Powered by GITEE.COM [GNK-6.4]
To https://gitee.com/asdfv1929/test.git
1f27e65..06e4177 add_commands -> add_commands
多个人把同一文件修改成不同的文件名称。
用户A对file.txt
文件进行了重命名,并提交了commit,但尚未push。
~/Desktop/test/test (add_commands)
ls
file.txt file2.txt fileB.html readme
~/Desktop/test/test (add_commands)
git mv file.txt fileA.txt
~/Desktop/test/test (add_commands)
git commit -am'userA mv file.txt fileA.txt'
[add_commands 3913944] userA mv file.txt fileA.txt
1 file changed, 0 insertions(+), 0 deletions(-)
rename file.txt => fileA.txt (100%)
用户B对同一文件file.txt
也修改了文件名,且命名不同,并最后push到了远端库上。
/g/test/test (add_commands)
git mv file.txt fileB.txt
/g/test/test (add_commands)
git commit -am'userB mv file.txt fileB.txt'
[add_commands bda28ab] userB mv file.txt fileB.txt
1 file changed, 0 insertions(+), 0 deletions(-)
rename file.txt => fileB.txt (100%)
/g/test/test (add_commands)
git push origin
Enumerating objects: 3, done.
Counting objects: 100% (3/3), done.
Delta compression using up to 6 threads
Compressing objects: 100% (2/2), done.
Writing objects: 100% (2/2), 233 bytes | 233.00 KiB/s, done.
Total 2 (delta 1), reused 0 (delta 0), pack-reused 0
remote: Powered by GITEE.COM [GNK-6.4]
To https://gitee.com/asdfv1929/test.git
7801623..bda28ab add_commands -> add_commands
此时用户A也去push时就会报错。
~/Desktop/test/test (add_commands)
git push origin
To https://gitee.com/asdfv1929/test.git
! [rejected] add_commands -> add_commands (fetch first)
error: failed to push some refs to 'https://gitee.com/asdfv1929/test.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.
用户Apush遇到报错,这是因为本地库与远端库发生了冲突。
那正常情况下,都是先将远端库拉取到本地,并与本地内容进行合并,但此处会遇到冲突告警。
git pull origin
remote: Enumerating objects: 3, done.
remote: Counting objects: 100% (3/3), done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 2 (delta 1), reused 0 (delta 0), pack-reused 0
Unpacking objects: 100% (2/2), 213 bytes | 26.00 KiB/s, done.
From https://gitee.com/asdfv1929/test
7801623..bda28ab add_commands -> origin/add_commands
CONFLICT (rename/rename): file.txt renamed to fileA.txt in HEAD and to fileB.txt in bda28ab39ac039e39d1243290ee35bd8624a5e64.
Automatic merge failed; fix conflicts and then commit the result.
Automatic merge failed
自动合并失败,这是因为Git无法判断该保留哪种重命名。
此时用户A和B需达成一致,并最终选择其一(人工干预)。
用户A这边查看一下git的状态,并选择最后的决定(选择哪个名字)。
~/Desktop/test/test (add_commands|MERGING)
git status
On branch add_commands
Your branch and 'origin/add_commands' have diverged,
and have 1 and 1 different commits each, respectively.
(use "git pull" to merge the remote branch into yours)
You have unmerged paths.
(fix conflicts and run "git commit")
(use "git merge --abort" to abort the merge)
Unmerged paths:
(use "git add/rm ..." as appropriate to mark resolution)
both deleted: file.txt
added by us: fileA.txt
added by them: fileB.txt
no changes added to commit (use "git add" and/or "git commit -a")
~/Desktop/test/test (add_commands|MERGING) # 留意MERGING,表示处于合并中
git rm file.txt
rm 'file.txt'
~/Desktop/test/test (add_commands|MERGING)
git add fileA.txt # 选择保留fileA.txt文件名,另外两种都删除
~/Desktop/test/test (add_commands|MERGING)
git rm fileB.txt
rm 'fileB.txt'
~/Desktop/test/test (add_commands|MERGING)
git status
On branch add_commands
Your branch and 'origin/add_commands' have diverged,
and have 1 and 1 different commits each, respectively.
(use "git pull" to merge the remote branch into yours)
All conflicts fixed but you are still merging.
(use "git commit" to conclude merge)
~/Desktop/test/test (add_commands|MERGING)
git commit -am'finally choose fileA.txt' # 提交commit,并最终push到远端
[add_commands de4c6e5] finally choose fileA.txt
~/Desktop/test/test (add_commands)
git push origin
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Delta compression using up to 6 threads
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 364 bytes | 364.00 KiB/s, done.
Total 3 (delta 2), reused 0 (delta 0), pack-reused 0
remote: Powered by GITEE.COM [GNK-6.4]
To https://gitee.com/asdfv1929/test.git
bda28ab..de4c6e5 add_commands -> add_commands
用户B这边重新拉取,更新下文件名。
/g/test/test (add_commands)
git pull
remote: Enumerating objects: 5, done.
remote: Counting objects: 100% (5/5), done.
remote: Compressing objects: 100% (3/3), done.
remote: Total 3 (delta 2), reused 0 (delta 0), pack-reused 0
Unpacking objects: 100% (3/3), 344 bytes | 43.00 KiB/s, done.
From https://gitee.com/asdfv1929/test
bda28ab..de4c6e5 add_commands -> origin/add_commands
Updating bda28ab..de4c6e5
Fast-forward
fileB.txt => fileA.txt | 0
1 file changed, 0 insertions(+), 0 deletions(-)
rename fileB.txt => fileA.txt (100%)
/g/test/test (add_commands)
ls
file2.txt fileA.txt fileB.html readme
本文主要讲多人在单个分支上操作时常遇到的一些情形。在进行git操作时,对遇到的问题要多熟悉,能做到问题的快速定位,以及后续的及时解决。