git rebase 和 git merge 从远端拉取处理合并的情况

git rebase 处理合并

无冲突情况

先配置 git pull 命令默认为 git pull --rebase。

git config pull.rebase true

远程仓库是这样的: 

本地仓库是这样的:

通过对比可以看出:

c7c56a7 是他们共同的 commit-id,但在这个节点以后,远程仓库和本地都对 hello.txt 文件进行了截然不同的修改。而且本地在修改这个文件以后,还继续进行了其他的 commit(包括对文件 hello.txt 的 commit)。

如果没有配置 'git config pull.rebase true' 而直接 git pull 的话,则会使用 merge 来处理合并(自动合并或者手动合并),但是现在我们配置了。

拉取一下:

[root@master GitTest]# git pull
Successfully rebased and updated refs/heads/master.

虽然远程和本地都对文件进行了不同的修改,但是 rebase 合并的时候竟然没出现冲突,这是为什么呢?(因为对同一个文件的不同地方进行修改的,各自的上下文都没有发生变化,所以没有冲突)

有冲突情况

到目前为止,远端和本地仓库的版本结构如下(本地领先远端 3 个 commit):

扫描二维码关注公众号,回复: 13039123 查看本文章
commit c3797b4cddb2bd43e609cefe8921c24e85fdca95 (HEAD -> master)
Author: looking <[email protected]>
Date:   Tue Dec 22 09:55:31 2020 +0800

    delete first line of hello.txt

commit e36200f61e20551724bf87a2afac7d338322a212
Author: looking <[email protected]>
Date:   Tue Dec 22 09:54:39 2020 +0800

    add hello world in world.txt

commit 8cad71d41f4fb040ad9685a4a6aa039005c82cea
Author: looking <[email protected]>
Date:   Tue Dec 22 09:51:15 2020 +0800

    add nice in hello.txt

commit fb26af6981e369f1c5e29b8b8b21b1f93d3233da (origin/master)
Author: looking <[email protected]>
Date:   Tue Dec 22 09:49:23 2020 +0800

    delete nice in hello.txt

commit c7c36a796d7a6ea5bf3c429fba88c36a61661681
Author: looking <[email protected]>
Date:   Tue Dec 22 09:45:56 2020 +0800

    readme.txt

为了让远程仓库和本地仓库必然冲突,我在远程提交了一个 commit (清空了 hello.txt 的内容 -- 好像还不小心多加了一个空行,不过无伤大雅,目的达成就可以):

再次 git pull  一下(这次终于得偿所愿冲突了):

[root@master GitTest]# git pull
remote: Enumerating objects: 3, done.
remote: Counting objects: 100% (3/3), done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
Unpacking objects: 100% (3/3), 865 bytes | 216.00 KiB/s, done.
From github.com:2392863668/GitTest
   fb26af6..eced426  master     -> origin/master
Auto-merging hello.txt
CONFLICT (content): Merge conflict in hello.txt
error: could not apply 8cad71d... add nice in hello.txt
Resolve all conflicts manually, mark them as resolved with
"git add/rm <conflicted_files>", then run "git rebase --continue".
You can instead skip this commit: run "git rebase --skip".
To abort and get back to the state before "git rebase", run "git rebase --abort".
Could not apply 8cad71d... add nice in hello.txt

不过先不要慌,我们先用 git status 看一下当前到底是什么情况:

[root@master GitTest]# git status
interactive rebase in progress; onto eced426
Last command done (1 command done):
   pick 8cad71d add nice in hello.txt
Next commands to do (2 remaining commands):
   pick e36200f add hello world in world.txt
   pick c3797b4 delete first line of hello.txt
  (use "git rebase --edit-todo" to view and edit)
You are currently rebasing branch 'master' on 'eced426'.
  (fix conflicts and then run "git rebase --continue")
  (use "git rebase --skip" to skip this patch)
  (use "git rebase --abort" to check out the original branch)

Unmerged paths:
  (use "git restore --staged <file>..." to unstage)
  (use "git add <file>..." to mark resolution)
	both modified:   hello.txt

no changes added to commit (use "git add" and/or "git commit -a")

果不其然是  hello.txt 文件冲突了(毕竟远端都把这个文件清空了,要是不冲突那才真的奇了怪)。

既然如此,那就 vim hello.txt 看一下(顺便处理一下冲突)。

[root@master GitTest]# vim hello.txt
<<<<<<< HEAD

=======
hello world
nice
hello world
hello world. I am Looking
nice to meet you too
>>>>>>> 8cad71d... add nice in hello.txt

自己取舍之后进行修改(我保留的本地的版本)。

[root@master GitTest]# vim hello.txt
hello world
nice
hello world
hello world. I am Looking
nice to meet you too

修改之后,当然要 git add hello.txt 一下:

[root@master GitTest]# git add hello.txt

现在 git status 告诉我们所有冲突都修复了之后该怎么做(甚至还告诉你了当前冲突节点的后续几个 commit 的 commit-id 和 title ):

[root@master GitTest]# git status
interactive rebase in progress; onto eced426
Last command done (1 command done):
   pick 8cad71d add nice in hello.txt
Next commands to do (2 remaining commands):
   pick e36200f add hello world in world.txt
   pick c3797b4 delete first line of hello.txt
  (use "git rebase --edit-todo" to view and edit)
You are currently rebasing branch 'master' on 'eced426'.
  (all conflicts fixed: run "git rebase --continue")

Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
	modified:   hello.txt

既然如此,我们就照着做一下:

[root@master GitTest]# git rebase --continue
[detached HEAD b6fdaf6] add nice in hello.txt
 1 file changed, 5 insertions(+), 1 deletion(-)
Successfully rebased and updated refs/heads/master.

如此,便大功告成(冲突节点以后的 commit 部分仍然得以保留 --- 这可正是我想要的,我可不想每次处理完冲突就把冲突后边的 commit 重新自己写一遍):

commit 5f7be5dbb1ebe2d662efd03b7d177c2da860e0a9 (HEAD -> master)
Author: looking <[email protected]>
Date:   Tue Dec 22 09:55:31 2020 +0800

    delete first line of hello.txt

commit 63bb8efabbcc3759a2bd2e53d195afdaee950d62
Author: looking <[email protected]>
Date:   Tue Dec 22 09:54:39 2020 +0800

    add hello world in world.txt

commit b6fdaf6d53a6e298ad8ab73f903e051ecd4c81e6
Author: looking <[email protected]>
Date:   Tue Dec 22 09:51:15 2020 +0800

    add nice in hello.txt

commit eced426098acd286cb45cb7191f83ddee9cc228c (origin/master)
Author: Looking <[email protected]>
Date:   Tue Dec 22 10:25:57 2020 +0800

    clear hello.txt

既然处理完了冲突,当然要 push 到远端一下啦:

[root@master GitTest]# git push
Enumerating objects: 12, done.
Counting objects: 100% (12/12), done.
Delta compression using up to 4 threads
Compressing objects: 100% (9/9), done.
Writing objects: 100% (9/9), 891 bytes | 297.00 KiB/s, done.
Total 9 (delta 3), reused 0 (delta 0), pack-reused 0
remote: Resolving deltas: 100% (3/3), completed with 1 local object.
To github.com:2392863668/GitTest.git
   eced426..5f7be5d  master -> master

和 merge 不一样的是,rebase 处理冲突不会产生菱形框哟(可以看到,git tree 都是线性的 --- 这也是 git rebase 很受欢迎的原因之一):

git merge 处理合并

无冲突情况

先禁用 git pull 的自动 rebase:

[root@master GitTest]# git config pull.rebase false

在上面代码的基础上,将本地版本回退一个 commit:

[root@master GitTest]# git reset HEAD~
Unstaged changes after reset:
M	hello.txt

重新修改回退版本变动的文件:

[root@master GitTest]# git diff
diff --git a/hello.txt b/hello.txt
index f4f41f3..83585f1 100644
--- a/hello.txt
+++ b/hello.txt
@@ -1,4 +1,3 @@
-hello world
 nice
 hello world
[root@master GitTest]# vim hello.txt 
[root@master GitTest]# git diff
diff --git a/hello.txt b/hello.txt
index f4f41f3..95696e0 100644
--- a/hello.txt
+++ b/hello.txt
@@ -1,5 +1,5 @@
-hello world
 nice
 hello world
 hello world. I am Looking
 nice to meet you too
+hello world

在本地再次提交 commit :

[root@master GitTest]# git add hello.txt 
[root@master GitTest]# git commit -m "delete first line and add after last line for hello.txt"
[master 085adcf] delete first line and add after last line for hello.txt
 1 file changed, 1 insertion(+), 1 deletion(-)

从远端拉取一下: 

[root@master GitTest]# git pull
Auto-merging hello.txt
Merge made by the 'recursive' strategy.

虽然也是对同一个文件进行的修改,但是改动地方不同,所以可以自动合并了。

[root@master GitTest]# git log
commit b2a17f4ece64a2adff17adfb0f9cfbfef24a0db7 (HEAD -> master)
Merge: 085adcf 5f7be5d
Author: looking <[email protected]>
Date:   Wed Dec 23 14:50:06 2020 +0800

    Merge branch 'master' of github.com:2392863668/GitTest into master

commit 085adcf8ee93c38b43f394f5aa8054e5478b148e
Author: looking <[email protected]>
Date:   Wed Dec 23 14:49:34 2020 +0800

    delete first line and add after last line for hello.txt

commit 5f7be5dbb1ebe2d662efd03b7d177c2da860e0a9 (origin/master)
Author: looking <[email protected]>
Date:   Tue Dec 22 09:55:31 2020 +0800

    delete first line of hello.txt

和 rebase 不一样的地方在于这儿合并的时候会多出一个 commit 而且会有明显的菱形框合并记录。 

[root@master GitTest]# git log --oneline --decorate --color --graph 
*   b2a17f4 (HEAD -> master) Merge branch 'master' of github.com:2392863668/GitTest into master
|\  
| * 5f7be5d (origin/master) delete first line of hello.txt
* | 085adcf delete first line and add after last line for hello.txt
|/  
* 63bb8ef add hello world in world.txt
...

有冲突情况

我们再次把本地版本退回到远端版本的上一个版本去:

[root@master GitTest]# git reset --hard HEAD^1
HEAD is now at 085adcf delete first line and add after last line for hello.txt
[root@master GitTest]# git reset --hard HEAD^1
HEAD is now at 63bb8ef add hello world in world.txt
[root@master GitTest]# git log
commit 63bb8efabbcc3759a2bd2e53d195afdaee950d62 (HEAD -> master)
Author: looking <[email protected]>
Date:   Tue Dec 22 09:54:39 2020 +0800

    add hello world in world.txt

commit b6fdaf6d53a6e298ad8ab73f903e051ecd4c81e6
Author: looking <[email protected]>
Date:   Tue Dec 22 09:51:15 2020 +0800

    add nice in hello.txt
...

远端版本是在这个的基础上删掉了第一行,为了让它冲突,我们就对本地 hello.txt 文件的第一行进行修改:

[root@master GitTest]# git diff
diff --git a/hello.txt b/hello.txt
index f4f41f3..25f7272 100644
--- a/hello.txt
+++ b/hello.txt
@@ -1,4 +1,4 @@
-hello world
+hello
 nice
 hello world
 hello world. I am Looking

然后修改 commit:

[root@master GitTest]# git add hello.txt 
[root@master GitTest]# git commit -m 'delete world in first line of hello.txt'
[master ba8b2b1] delete world in first line of hello.txt
 1 file changed, 1 insertion(+), 1 deletion(-)

[root@master GitTest]# git log
commit ba8b2b1189e9a755282c5b267f2dedd76197db80 (HEAD -> master)
Author: looking <[email protected]>
Date:   Wed Dec 23 15:24:02 2020 +0800

    delete world in first line of hello.txt

commit 63bb8efabbcc3759a2bd2e53d195afdaee950d62
Author: looking <[email protected]>
Date:   Tue Dec 22 09:54:39 2020 +0800

    add hello world in world.txt

commit b6fdaf6d53a6e298ad8ab73f903e051ecd4c81e6
Author: looking <[email protected]>
Date:   Tue Dec 22 09:51:15 2020 +0800

    add nice in hello.txt
...

然后从远端拉取:

[root@master GitTest]# git pull
Auto-merging hello.txt
CONFLICT (content): Merge conflict in hello.txt
Automatic merge failed; fix conflicts and then commit the result.

可以看到,这次自动合并失败了(毕竟远端和本地都对文件相同位置进行了不同的修改,需要手动处理冲突)。

[root@master GitTest]# vim hello.txt
<<<<<<< HEAD
hello
=======
>>>>>>> 5f7be5dbb1ebe2d662efd03b7d177c2da860e0a9
nice
hello world
hello world. I am Looking
nice to meet you too

处理后查看状态:

[root@master GitTest]# git add hello.txt 
[root@master GitTest]# git status
On branch master
Your branch and 'origin/master' 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)

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
	modified:   hello.txt

保存冲突处理结果:

[root@master GitTest]# git add hello.txt
[root@master GitTest]# git commit -m 'deal merge conflict in hello.txt'
[master 1912baa] deal merge conflict in hello.txt

大功告成,查看并推送到远端:

commit 1912baa1b9457add393f48c41ffd35957aa8b569 (HEAD -> master)
Merge: ba8b2b1 5f7be5d
Author: looking <[email protected]>
Date:   Wed Dec 23 15:34:02 2020 +0800

    deal merge conflict in hello.txt

commit ba8b2b1189e9a755282c5b267f2dedd76197db80
Author: looking <[email protected]>
Date:   Wed Dec 23 15:24:02 2020 +0800

    delete world in first line of hello.txt

commit 5f7be5dbb1ebe2d662efd03b7d177c2da860e0a9 (origin/master)
Author: looking <[email protected]>
Date:   Tue Dec 22 09:55:31 2020 +0800

    delete first line of hello.txt
...
[root@master GitTest]# git push
Enumerating objects: 8, done.
Counting objects: 100% (8/8), done.
Delta compression using up to 4 threads
Compressing objects: 100% (4/4), done.
Writing objects: 100% (4/4), 508 bytes | 254.00 KiB/s, done.
Total 4 (delta 1), reused 0 (delta 0), pack-reused 0
remote: Resolving deltas: 100% (1/1), completed with 1 local object.
To github.com:2392863668/GitTest.git
   5f7be5d..1912baa  master -> master

当然,merge 处理合并的情况仍然是有菱形框的哟:

[root@master GitTest]# git log --oneline --decorate --color --graph 
*   1912baa (HEAD -> master, origin/master) deal merge conflict in hello.txt
|\  
| * 5f7be5d delete first line of hello.txt
* | ba8b2b1 delete world in first line of hello.txt
|/  
* 63bb8ef add hello world in world.txt
...

猜你喜欢

转载自blog.csdn.net/TomorrowAndTuture/article/details/111505639
今日推荐