git pull --rebase导致意外的图形

时间:2015-02-13 14:46:18

标签: git git-rebase

我正在分支foo工作。根据我的方框,我没有未分期更改,没有工作更改,完全干净的状态,HEAD == foo == origin/foo

$ git status
# On branch foo
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#   some_irrelevant_file_here

$ git log --pretty=...
* 456520c 2015-02-13 (HEAD, origin/foo, foo) Commit A
* 23bfcd1 2015-02-11 Commit B
* b0bdd18 2015-02-12 Commit C

然后我被要求查看同事推动的一些变化,所以我这样做:

$ git pull --rebase origin foo
remote: Counting objects: 47, done.
remote: Compressing objects: 100% (34/34), done.
remote: Total 36 (delta 22), reused 0 (delta 0)
Unpacking objects: 100% (36/36), done.
From ...
 * branch            foo       -> FETCH_HEAD
First, rewinding head to replay your work on top of it...
Fast-forwarded foo to 43dad88c737762e0f1e84fdcd135155080bdce2a.

此时,我的图表看起来像:

$ git log --pretty=...
* 43dad88 2015-02-13 (HEAD, foo) Commit D
* 40039f9 2015-02-13 Commit E
* 456520c 2015-02-13 (origin/foo) Commit A
* 23bfcd1 2015-02-11 Commit B
* b0bdd18 2015-02-12 Commit C

为什么我的本地foo看起来好于origin/fooDE都不是我的提交,我只是从origin中提取了这两个 - 我现在期望仍然HEAD == {{ 1}} == foo

3 个答案:

答案 0 :(得分:3)

pull --rebase之前你所拥有的是:

x--x--x (foo, HEAD, origin/foo)
       \
        y--y (actual origin/foo)

当您pull --rebase时,您要求在origin/foo之上重播您的本地提交:
foo重置/签出origin/foo(在FETCH_HEAD中提取),因为您的提交“x”已经是新更新FETCH_HEAD的一部分},foo只是快进:

x--x--x--y--y (foo, HEAD, FETCH_HEAD)
      |
 (origin/foo)

origin/foo 更改的事实是典型的git older than 1.8.4(例如在Ubuntu Precise 12.04中找到,其中包含旧git-core } 1.7.9.5)

简单的git fetch应该足以更新origin/foo,而不仅仅是FETCH_HEAD

更新的git(1.8.4 +)会同时更新FETCH_HEADorigin/foo,使额外的git fetch变得多余。


注意:使用Git 2.12(2017年第一季度),这种情况(pull --rebase)将是一个简单的快进合并。

commit 33b842a查看Junio C Hamano (gitster)(2016年6月29日)。 Junio C Hamano -- gitster --合并于commit 2fb11ec,2016年12月19日)

  

pull:快进“pull --rebase=true

     

git pull --rebase”在获取后始终运行“git rebase”   承诺作为新基地,即使新基地是一个   当前HEAD的后代,即我们没有做任何工作。

     

在这种情况下,我们可以在没有的情况下快进到新基地   调用rebase过程

答案 1 :(得分:0)

因为它没有被推到repo那是正常的行为。你怎么能在原产地之前得到你的本地提交?他们将始终处于最佳状态。

答案 2 :(得分:0)

  

为什么看起来我的本地foo超前于原点/ foo?

预计会foo提前remote/foo,因为rebase plays back your current branch on top of the upstream branch。您在foo之上重新remote/foo,因此foo应该早于remote/foo

  根据我的方框,

HEAD == foo == origin / foo。

因此,提交顺序也如预期。以下是在一个rebase或merge之前你的分支看起来的方式,其中A是远程的实际状态,而C是远程的陈旧表示。

D <------C (HEAD, foo, remote/foo) <------B <------A (remote/foo)

你做的相当于&#34;快进&#34;变基。即它对提交没有任何作用;没有什么可以回到remote/foo!结果应该只更改ref位置:

D <------C <------B <------A (HEAD, foo, remote/foo)
  

为什么看起来我的本地foo超前于原点/ foo?

这是我无法回答的问题。在变基之后,我会再次期待HEAD == foo == remote/foo,但事实并非如此。为什么在fooremote/foo之后,后者似乎落后了?