git pull 和 git pull --rebase 区别理解

git pull = git fetch + git merge

git pull --rebase = git fetch + git rebase

git pull 就不多说了,直接来看 git pull --rebase 吧。

现在,用户 A,用户 B 和 远程仓库的代码版本都是最新且保持一致的。

用户 A 在本地提交了两次 commit ,领先远程仓库 2 commit:

# User A
Administrator@PC-20200713AJJH MINGW64 /d/MyProject/Python/GitTest (master)
$ git status
On branch master
Your branch is ahead of 'origin/master' by 2 commits.
  (use "git push" to publish your local commits)

nothing to commit, working tree clean


Administrator@PC-20200713AJJH MINGW64 /d/MyProject/Python/GitTest (master)
$ git log
commit db412233fd10dbf782147ae678310ef7a412ccf4 (HEAD -> master)
Author: 2392863668 <[email protected]>
Date:   Wed Jul 29 22:28:31 2020 +0800

    mv test.txt to test dir

commit 32b9c4ee0b74b629e1d1e99f1d0173a831638d7c
Author: 2392863668 <[email protected]>
Date:   Wed Jul 29 22:15:01 2020 +0800

    delete d.txt

commit 70f19e6d0788ad7fca07b129a8615084fe08f1e9 (origin/master, origin/HEAD)
Author: 2392863668 <[email protected]>
Date:   Wed Jul 29 21:58:26 2020 +0800

    modify c.txt

commit 082b01177112fc3ccb93f234435fb06a930c19fb
Author: 2392863668 <[email protected]>
Date:   Wed Jul 29 21:05:16 2020 +0800

    add hello world in b.txt
# User B
[root@master GitTest]# git log
commit 70f19e6d0788ad7fca07b129a8615084fe08f1e9
Author: 2392863668 <[email protected]>
Date:   Wed Jul 29 21:58:26 2020 +0800

    modify c.txt

commit 082b01177112fc3ccb93f234435fb06a930c19fb
Author: 2392863668 <[email protected]>
Date:   Wed Jul 29 21:05:16 2020 +0800

    add hello world in b.txt

commit d38440866faa62ff1a2c383be1fc780bbbb859f7
Author: 2392863668 <[email protected]>
Date:   Wed Jul 29 20:53:13 2020 +0800

然后 A 将提交 git push 到了远程仓库:

Administrator@PC-20200713AJJH MINGW64 /d/MyProject/Python/GitTest (master)
$ git push
Enumerating objects: 8, done.
Counting objects: 100% (8/8), done.
Delta compression using up to 8 threads.
Compressing objects: 100% (5/5), done.
Writing objects: 100% (6/6), 572 bytes | 572.00 KiB/s, done.
Total 6 (delta 2), reused 0 (delta 0)
remote: Resolving deltas: 100% (2/2), completed with 1 local object.
To github.com:2392863668/GitTest.git
   70f19e6..db41223  master -> master

B 也在本地提交了一次commit:

[root@master GitTest]# vi looking.txt 
[root@master GitTest]# git add looking.txt 
[root@master GitTest]# git commit -m "add hello world in looking.txt"
[master 9983c69] add hello world in looking.txt
 1 file changed, 1 insertion(+)
[root@master GitTest]# git log
commit 9983c69644ade74a4fa0a2fa4f7bd1c1771f39a5
Author: looking <[email protected]>
Date:   Wed Jul 29 23:29:39 2020 +0800

    add hello world in looking.txt

commit 70f19e6d0788ad7fca07b129a8615084fe08f1e9
Author: 2392863668 <[email protected]>
Date:   Wed Jul 29 21:58:26 2020 +0800

    modify c.txt

commit 082b01177112fc3ccb93f234435fb06a930c19fb
Author: 2392863668 <[email protected]>
Date:   Wed Jul 29 21:05:16 2020 +0800

    add hello world in b.txt

然后 B 也准备将提交 git push 到远程仓库:

[root@master GitTest]# git push
warning: push.default is unset; its implicit value is changing in
Git 2.0 from 'matching' to 'simple'. To squelch this message
and maintain the current behavior after the default changes, use:

  git config --global push.default matching

To squelch this message and adopt the new behavior now, use:

  git config --global push.default simple

See 'git help config' and search for 'push.default' for further information.
(the 'simple' mode was introduced in Git 1.7.11. Use the similar mode
'current' instead of 'simple' if you sometimes use older versions of Git)

To [email protected]:2392863668/GitTest.git
 ! [rejected]        master -> master (fetch first)
error: failed to push some refs to '[email protected]:2392863668/GitTest.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 merge the remote changes (e.g.,
hint: 'git pull') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.

由于远程分支已经继续往前走了,所以 B 自然而然 push 失败了,而且消息也提示让先 'git pull',这时候我们的 git pull --rebase 该上场了,git pull --rebase 以后,我们查看版本日志图,发现 modify c.txt 后面的日志记录并没有像之前那样有直观的合并记录了。直接先 git pull, 再 git merge 的话则无法避免这种情况。

[root@master GitTest]# git pull --rebase
remote: Enumerating objects: 6, done.
remote: Counting objects: 100% (6/6), done.
remote: Compressing objects: 100% (3/3), done.
remote: Total 6 (delta 2), reused 6 (delta 2), pack-reused 0
Unpacking objects: 100% (6/6), done.
From github.com:2392863668/GitTest
   70f19e6..db41223  master     -> origin/master
First, rewinding head to replay your work on top of it...
Applying: add hello world in looking.txt

[root@master GitTest]# git log
commit 3fceb8a9bdb24500a68477d4560c33cb305b5d5f
Author: looking <[email protected]>
Date:   Wed Jul 29 23:29:39 2020 +0800

    add hello world in looking.txt

commit db412233fd10dbf782147ae678310ef7a412ccf4
Author: 2392863668 <[email protected]>
Date:   Wed Jul 29 22:28:31 2020 +0800

    mv test.txt to test dir

commit 32b9c4ee0b74b629e1d1e99f1d0173a831638d7c
Author: 2392863668 <[email protected]>
Date:   Wed Jul 29 22:15:01 2020 +0800

    delete d.txt

commit 70f19e6d0788ad7fca07b129a8615084fe08f1e9
Author: 2392863668 <[email protected]>
Date:   Wed Jul 29 21:58:26 2020 +0800

[root@master GitTest]# git log --oneline --decorate --color --graph
* 3fceb8a (HEAD, master) add hello world in looking.txt
* db41223 (origin/master) mv test.txt to test dir
* 32b9c4e delete d.txt
* 70f19e6 modify c.txt
* 082b011 add hello world in b.txt
* d384408 mv a.txt to test directory
*   648e3e1 Merge branch 'dev' to 'master'
|\  
| * d2009f7 (dev) add one line in c.txt by user B again
| * 4505d98 add one line in b.txt by user B again
* | cc12a89 add one line in a.txt by user A again
|/ 

然后 B 再次尝试提交 git push 到远程仓库(这次 push 成功):

[root@master GitTest]# git push
warning: push.default is unset; its implicit value is changing in
Git 2.0 from 'matching' to 'simple'. To squelch this message
and maintain the current behavior after the default changes, use:

  git config --global push.default matching

To squelch this message and adopt the new behavior now, use:

  git config --global push.default simple

See 'git help config' and search for 'push.default' for further information.
(the 'simple' mode was introduced in Git 1.7.11. Use the similar mode
'current' instead of 'simple' if you sometimes use older versions of Git)

Counting objects: 3, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (2/2), 233 bytes | 0 bytes/s, done.
Total 2 (delta 1), reused 0 (delta 0)
remote: Resolving deltas: 100% (1/1), completed with 1 local object.
To [email protected]:2392863668/GitTest.git
   db41223..3fceb8a  master -> master

如果以上直接 git pull 的话,git 会直接弹出一个类似下面这种的 merge 界面(如果有冲突的话还需要处理冲突):

Administrator@PC-20200713AJJH MINGW64 /d/MyProject/Python/GitTest (master)
$ git pull
remote: Enumerating objects: 2, done.
remote: Counting objects: 100% (2/2), done.
remote: Total 2 (delta 1), reused 2 (delta 1), pack-reused 0
Unpacking objects: 100% (2/2), done.
From github.com:2392863668/GitTest
   db41223..3fceb8a  master     -> origin/master
Merge made by the 'recursive' strategy.
 looking.txt | 1 +
 1 file changed, 1 insertion(+)

 而且可以看到直观的合并记录了(虽然不一定是你想要的)。

整个例子讲下来,相信你已经知道 git pull --rebase 的作用了。 

猜你喜欢

转载自blog.csdn.net/TomorrowAndTuture/article/details/107677939