我有一个功能分支和一个主分支.
Master分支已经发展,我的意思是让这些更新尽可能少地与master分支发生分歧.
所以我git pull在两个分支,git checkout feature/branch最后git rebase master.
现在,我要么期望一切顺利运行,要么在继续rebase之前需要解决冲突,直到所有主提交在功能分支上成功重新应用.
现在在我的案例中真正发生的是我不明白的事情:
$>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*
Run Code Online (Sandbox Code Playgroud)
现在,我可以理解他在拉动之后加载了冲突; 我不明白需要拉.从逻辑上讲,它应该在分支时回滚到master,保存在分支上进行的提交,转发到master上的最新提交,然后应用保存的提交.
我不明白Applying消息所指的是什么:什么是应用提交哪个版本?
Enr*_*lio 65
文艺青年最爱的你应该同时更新master,并feature用git pull和git pull --rebase 以前重订基feature之上master.在 你的分支重新设置git pull 之后,没有必要做.featuremaster
根据您当前的工作流程,原因git status告诉您:
您的分支和"origin/feature"已经分歧,每个分别有27个和2个不同的提交.
是因为你的重建基础feature分支现在有25个新提交不是来自可达origin/feature(因为他们从底垫上前来master加)2所提交这是从可达的origin/feature,但有不同的提交的ID.这些提交包含相同的更改(即它们是相同的修补程序)但它们具有不同的SHA-1哈希值,因为它们基于origin/feature与您在本地存储库中重新引用它们的提交不同的提交.
这是一个例子.让我们假设这是你的历史之前做git pull的master:
A - B - C (master)
\
D - E (feature)
Run Code Online (Sandbox Code Playgroud)
之后git pull,master得到了承诺F:
A - B - C - F (master, origin/master)
\
D - E (feature)
Run Code Online (Sandbox Code Playgroud)
在这一点上,你变基feature之上master,其中应用 D和E:
A - B - C - F (master, origin/master)
\
D - E (feature)
Run Code Online (Sandbox Code Playgroud)
与此同时,远程分支origin/feature仍然基于提交C:
A - B - C - F (master, origin/master)
\ \
\ D' - E' (feature)
\
D - E (origin/feature)
Run Code Online (Sandbox Code Playgroud)
如果你做git status的feature,Git会告诉你,你feature的分支已经从分歧origin/feature与3(F,D',E')和2(D,E分别)款.
请注意
D'并E'包含相同的更改D,E但具有不同的提交ID,因为它们已经重新定位F.
解决的办法是做git pull上都master和feature 之前衍合feature上master.但是,由于您可能已经提交了feature尚未推送的提交origin,您可能希望:
git checkout feature && git pull --rebase
Run Code Online (Sandbox Code Playgroud)
避免在您和本地之间创建合并提交.origin/featurefeature
根据这一评论,我扩大了分歧.在rebase之后git status报告feature和origin/feature 分歧的原因是由于rebase引入了新的提交feature,而且它重写了之前推送的提交origin/feature.
审时度势后拉,但前底垫:
A - B - C - F (master)
\
D - E (feature, origin/feature)
Run Code Online (Sandbox Code Playgroud)
此时,feature并origin/feature指向相同的提交E- 换句话说,它们处于" 同步 "状态.经过重订feature之上master,历史将是这样的:
A - B - C - F (master)
\ \
\ D' - E' (feature)
\
D - E (origin/feature)
Run Code Online (Sandbox Code Playgroud)
正如你所看到的,feature并且origin/feature已经分歧,他们的共同祖先正在承诺C.这是因为feature现在包含F来自masterplus 的新提交D'和E'(读作" D prime "和" E prime "),它们是提交D并E应用于上面F.尽管它们包含相同的更改,但Git认为它们是不同的,因为它们具有不同的提交ID.同时,origin/feature仍然参考D和E.
此时,您已经重写了历史记录:您已经通过对其进行重新定义来修改现有提交,从而有效地创建"新"提交.
现在,如果您要继续运行git pull,feature那将会发生什么:
A - B - C - F (master)
\ \
\ D' - E'- M (feature)
\ /
D - E - (origin/feature)
Run Code Online (Sandbox Code Playgroud)
由于git pull是git fetch+ git merge,这将导致创建合并提交M,其父母是E'和E.
相反,如果您运行git pull --rebase(即git fetch+ git rebase),那么Git会:
feature提交C(的共同祖先feature和origin/feature)D和E来自origin/featureF,D'和E'然而,注意到,D'并且E'包含相同的变化D和E,Git的也只是将它们丢弃,造成了历史看起来像这样:
A - B - C - F (master)
\
D - E - F' (feature)
^
(origin/feature)
Run Code Online (Sandbox Code Playgroud)
请注意F,之前可以从中获取的提交是如何feature应用于origin/feature生成的F'.在这一点上,git status会告诉你这个:
您的分支通过1次提交超过"origin/feature".
当然,这是承诺F'.
ash*_*oli 11
如果远程版本的master和feature/branch单独更新,则只需重置本地功能分支即可
git checkout feature/branch
git fetch origin feature/branch
git reset --hard origin/feature/branch
Run Code Online (Sandbox Code Playgroud)
那么如果你想引入master分支的变化,
git rebase origin/master
Run Code Online (Sandbox Code Playgroud)
当你在 master 之上重新建立你的特性分支时,你创建了一堆新的提交。但是,您的origin/feature分支仍然指向旧的分支。这是rebase后的情况:
C' (feature)
B'
A'
* (master, origin/master)
*
*
| C (origin/feature)
| B
| A
|/
* some base commit
Run Code Online (Sandbox Code Playgroud)
虽然提交A'包含与commit类似的更改集A,但它绝不是相同的提交。它包含一个不同的树,并且有一个不同的父节点。
现在,当您feature再次尝试拉取时,您会尝试创建此历史记录:
* (feature)
|\
C'|
B'|
A'|
* | (master, origin/master)
* |
* |
| C (origin/feature)
| B
| A
|/
* some base commit
Run Code Online (Sandbox Code Playgroud)
您正在合并两个引入了非常相似、不同的变化的分支。除了完全没有意义之外,这势必会造成大量冲突。
您需要做的是使用git push -f. 这将失去旧的历史,并用重写的历史代替它。
另一种方法是避免git rebase在您已经推送到任何其他存储库的分支上使用,或者git rebase完全避免使用。这是更简洁的方法:它导致历史的发生,而不是像过去那样对历史撒谎git rebase。这至少是我更喜欢的。