git pull *after* git rebase?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/42861353/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
git pull *after* git rebase?
提问by tisek
I have a feature branch, and a master branch.
我有一个功能分支和一个主分支。
Master branch has evolved and I mean to have those updates to diverging as little as possible from master branch.
Master 分支已经发展,我的意思是让这些更新尽可能少地与 master 分支分开。
So I git pull
in both branches, git checkout feature/branch
and finally git rebase master
.
所以我git pull
在两个分支,git checkout feature/branch
最后git rebase master
。
Now here I either expect everything to work smoothly orconflicts showing up that I need to resolve before continuing rebase until all master commits are re-applied successfully on feature branch.
现在在这里,我要么希望一切顺利,要么在继续 rebase 之前需要解决冲突,直到所有主提交都成功地重新应用到功能分支上为止。
Now what really happened in my case is something I do not understand:
现在在我的情况下真正发生的是我不明白的事情:
$>git rebase master
First, rewinding head to replay your work on top of it...
Applying: myFirstCommitDoneOnTheBranch
Applying: myOtherCommitDoneOnTheBranch
$>git status
On branch feature/branch
Your branch and 'origin/feature/feature' have diverged,
and have 27 and 2 different commits each, respectively.
(use "git pull" to merge the remote branch into yours)
nothing to commit, working tree clean
$>git pull
*load of conflicts*
Now, as much as I can understand he load of conflicts after the pull; I do not understand the need for a pull. Logically, it should rollback to master when it got branched, save the commits made on the branch, forward to latest commit on master and then apply the saved commits.
现在,据我所知,拉动后他有很多冲突;我不明白需要拉。从逻辑上讲,它应该在分支时回滚到 master,保存在分支上所做的提交,转发到 master 上的最新提交,然后应用保存的提交。
I do not understand to what the Applying
message refers to: what is applying the commits on which version?
我不明白该Applying
消息指的是什么:什么应用了哪个版本的提交?
回答by Enrico Campidoglio
tl;drYou should update both master
and feature
with git pull
and git pull --rebase
beforerebasing feature
on top of master
. There is no need to do agit pull
afteryou have rebased your feature
branch on top of master
.
文艺青年最爱的你应该同时更新master
,并feature
用git pull
和git pull --rebase
以前重订基feature
之上master
。有没有必要做了git pull
之后,你已经重订的feature
分支之上master
。
With your current workflow, the reason why git status
is telling you this:
使用您当前的工作流程,原因git status
告诉您:
Your branch and 'origin/feature' have diverged, and have 27 and 2 different commits each, respectively.
您的分支和 'origin/feature' 有分歧,分别有 27 次和 2 次不同的提交。
is because your rebased feature
branch now has 25new commits that aren't reachable from origin/feature
(since they came from the rebase on master
) plus 2commits that arereachable from origin/feature
but have different commit IDs. Those commits contain the same changes (i.e. they're patch equivalent) but they have different SHA-1 hashes because they are based off of a different commit in origin/feature
than the one you rebased them on in your local repository.
是因为你的衍合feature
分支现在有25个新提交不是来自可达origin/feature
(因为他们从底垫来master
加)2所提交这是从可达的origin/feature
,但有不同的提交的ID。这些提交包含相同的更改(即它们是补丁等效的),但它们具有不同的 SHA-1 哈希值,因为它们基于origin/feature
与您在本地存储库中重新基于它们的提交不同的提交。
Here's an example. Let's assume that this is your history beforedoing git pull
on master
:
这是一个例子。让我们假设这是你的历史之前做git pull
的master
:
A - B - C (master)
\
D - E (feature)
After git pull
, master
got commit F
:
之后git pull
,master
得到提交F
:
A - B - C - F (master, origin/master)
\
D - E (feature)
At that point, you rebase feature
on top of master
, which appliesD
and E
:
在这一点上,您feature
基于master
,适用于D
和E
:
A - B - C - F (master, origin/master)
\
D - E (feature)
In the meantime, the remote branch origin/feature
is still based off commit C
:
同时,远程分支origin/feature
仍然基于 commit C
:
A - B - C - F (master, origin/master)
\ \
\ D' - E' (feature)
\
D - E (origin/feature)
If you do a git status
on feature
, Git will tell you that your feature
branch has diverged from origin/feature
with 3(F
, D'
, E'
) and 2(D
, E
) commits, respectively.
如果您执行git status
on feature
,Git 会告诉您您的feature
分支已分别origin/feature
与3( F
, D'
, E'
) 和2( D
, E
) 提交不同。
Note that
D'
andE'
contain the same changes asD
andE
but have different commit IDs because they have been rebased on top ofF
.
请注意,
D'
andE'
包含与and相同的更改D
,E
但具有不同的提交 ID,因为它们已重新基于F
.
The solution is to do git pull
on both master
and feature
beforerebasing feature
on master
. However, since you may have commits on feature
that you haven't yet pushed to origin
, you would want to do:
解决的办法是做git pull
上都master
和feature
之前衍合feature
上master
。但是,由于您可能已经提交了feature
尚未推送到的提交origin
,因此您需要执行以下操作:
git checkout feature && git pull --rebase
to avoid creating a merge commitbetween origin/feature
and your local feature
.
避免产生合并提交之间origin/feature
和当地feature
。
Update on the consequences of rebasing:
更新重新定位的后果:
In light of this comment, I expanded on the diverging branches. The reason why git status
reports that feature
and origin/feature
divergeafter the rebase is due to the fact that rebasing brings in new commits to feature
, plus it rewritesthe commits that were previously pushed to origin/feature
.
鉴于此评论,我扩展了不同的分支。在 rebase 后git status
报告feature
和origin/feature
分歧的原因是因为 rebase 带来了新的提交feature
,而且它重写了之前推送到的提交origin/feature
。
Consider the situation afterthe pull but beforethe rebase:
审时度势后拉,但前底垫:
A - B - C - F (master)
\
D - E (feature, origin/feature)
At this point, feature
and origin/feature
point to the same commit E
—in other words, they're in "sync". After rebasing feature
on top of master
, history will look like this:
在这一点上,feature
并origin/feature
指向相同的提交E
-换句话说,他们在“同步”。在feature
基于之后master
,历史将如下所示:
A - B - C - F (master)
\ \
\ D' - E' (feature)
\
D - E (origin/feature)
As you can see, feature
and origin/feature
have diverged, their common ancestor being commit C
. This is because feature
now contains the new commit F
from master
plus D'
and E'
(read as "D prime" and "E prime") which are commits D
and E
applied on top of F
. Even though they contain the same changes, Git considers them to be different because they have different commit IDs. Meanwhile, origin/feature
still references D
and E
.
正如您所看到的,feature
并且origin/feature
已经发生分歧,他们的共同祖先是 commit C
。这是因为feature
现在包含F
来自master
plusD'
和E'
(读作“ D prime”和“ E prime”)的新提交,它们是提交D
并E
应用在F
. 即使它们包含相同的更改,Git 也会认为它们不同,因为它们具有不同的提交 ID。同时,origin/feature
仍然引用D
和E
。
At this point, you've rewritten history: you've modified existing commits by virtue of rebasing them, effectively creating "new" ones.
在这一点上,您已经改写了历史:您通过重新设置现有提交修改了它们,有效地创建了“新”提交。
Now, if you were to run git pull
on feature
this is what would happen:
现在,如果你要运行git pull
,feature
会发生什么:
A - B - C - F (master)
\ \
\ D' - E'- M (feature)
\ /
D - E - (origin/feature)
Since git pull
does git fetch
+ git merge
, this would result in the creation of the merge commit M
, whose parents are E'
and E
.
由于git pull
不git fetch
+ git merge
,这将导致在创建合并的提交M
,其父母E'
和E
。
If, instead, you ran git pull --rebase
(that is, git fetch
+ git rebase
) then Git would:
相反,如果您运行git pull --rebase
(即git fetch
+ git rebase
),那么 Git 将:
- Move
feature
to commitC
(the common ancestor offeature
andorigin/feature
) - Apply
D
andE
fromorigin/feature
- Apply
F
,D'
andE'
- 移动
feature
提交C
(的共同祖先feature
和origin/feature
) - 申请
D
并E
从origin/feature
- 申请
F
,D'
和E'
However, noticing that D'
and E'
contain the same changes as D
and E
, Git would just discard them, resulting in a history looking like this:
然而,注意到,D'
并且E'
包含相同的变化D
和E
,Git的也只是将它们丢弃,造成了历史看起来像这样:
A - B - C - F (master)
\
D - E - F' (feature)
^
(origin/feature)
Notice how commit F
, previously reachable from feature
, got applied on top of origin/feature
resulting in F'
. At this point, git status
would tell you this:
请注意如何提交F
,以前从可达feature
,得到了应用之上origin/feature
产生F'
。此时,git status
会告诉你:
Your branch is ahead of 'origin/feature' by 1 commit.
您的分支领先于 'origin/feature' 1 次提交。
That commit being, of course, F'
.
当然,那个提交是F'
.
回答by ashmaroli
If the remote versions of master
and feature/branch
are up-to-date individually, then simply reset your local feature branch
如果远程版本master
,并feature/branch
均达到最新的独立,然后只需重置您的本地特性分支
git checkout feature/branch
git fetch origin feature/branch
git reset --hard origin/feature/branch
then if you want to bring in changes in the master
branch,
那么如果你想在master
分支中引入变化,
git rebase origin/master
回答by Greg Tarsa
The have 27 and 2 different commits each
is telling you that you now have 27 new commits from master
and 2 new commits in your branch that are not present in origin/<yourbranch>
.
这have 27 and 2 different commits each
告诉您,您master
的分支中现在有 27 个新提交和 2 个新提交,它们不存在于origin/<yourbranch>
.
Because origin/<yourbranch>
has been massively changed by the rebase, it no longer has a common base with origin/<yourbranch>
. Therefore, you don't want to then pull the changes from origin/<yourbranch>
after the rebase, because, as you see, all H*** breaks loose.
因为origin/<yourbranch>
已经被 rebase 大规模改变,它不再与origin/<yourbranch>
. 因此,您不想origin/<yourbranch>
在 rebase之后拉取更改,因为如您所见,所有 H*** 都松动了。
If you know there are changes in origin/<yourbranch>
that you need in your local branch, then pull those before you rebase.
如果您知道origin/<yourbranch>
本地分支中有您需要的更改,请在变基之前拉取这些更改。
If you are sure no one has changed origin/<yourbranch>
since your last push (a safe bet if this is your own feature branch), you can use push --force
to put them into sync again. Then origin/<yourbranch>
will again have the same base as your local branch and that base will contain all the latest master
changes.
如果您确定origin/<yourbranch>
自上次推送以来没有任何人更改(如果这是您自己的功能分支,这是一个安全的赌注),您可以使用push --force
将它们再次同步。然后origin/<yourbranch>
将再次与您的本地分支具有相同的基础,并且该基础将包含所有最新master
更改。
回答by cmaster - reinstate monica
When you rebased your feature branch on top of master, you created a bunch of new commits. However, your origin/feature
branch is still pointing to the old ones. This is the situation after the rebase:
当你在 master 之上重新建立你的特性分支时,你创建了一堆新的提交。但是,您的origin/feature
分支仍然指向旧的分支。这是rebase后的情况:
C' (feature)
B'
A'
* (master, origin/master)
*
*
| C (origin/feature)
| B
| A
|/
* some base commit
While the commit A'
contains a similar change set as commit A
, it is by no means the same commit. It contains a different tree, and has a different parent.
虽然提交A'
包含与commit类似的更改集A
,但它绝不是相同的提交。它包含一个不同的树,并且有一个不同的父节点。
Now, when you try to pull feature
again, you try to create this history:
现在,当您feature
再次尝试拉取时,您会尝试创建此历史记录:
* (feature)
|\
C'|
B'|
A'|
* | (master, origin/master)
* |
* |
| C (origin/feature)
| B
| A
|/
* some base commit
You are merging two branches that have introduced very similar, jet different changes. This is bound to create a ton of conflicts, apart from being entirely pointless.
您正在合并两个引入了非常相似、不同的变化的分支。除了完全没有意义之外,这势必会造成大量冲突。
What you need to do is inform your upstream repo about the rebase by using git push -f
. This will loose the old history, and replace it with the rewritten one.
您需要做的是使用git push -f
. 这将失去旧的历史,并用重写的历史代替它。
The alternative is to avoid using git rebase
on branches that you have already pushed to any other repository, or avoid git rebase
altogether. This is the cleaner approach: It results in the history as it has happened, instead of telling lies about history as git rebase
does. That's at least what I prefer.
另一种方法是避免git rebase
在您已经推送到任何其他存储库的分支上使用,或者git rebase
完全避免使用。这是更简洁的方法:它导致历史的发生,而不是像过去那样对历史撒谎git rebase
。这至少是我更喜欢的。