我有一个功能分支和一个主分支。
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*
现在,尽管我能理解他在拉动之后加载了冲突;我不明白需要拉。从逻辑上讲,它应该在分支时回滚到master,保存在分支上的提交,转发到master上的最新提交,然后应用保存的提交。
我不明白Applying
消息所引用的内容:什么是应用哪个版本的提交?
答案 0 :(得分:60)
tl; dr 您应该先使用master
和feature
更新git pull
和git pull --rebase
重新定位{在feature
之上{1}}。 <{strong> 之后
根据您当前的工作流程,master
告诉您的原因是:
您的分支机构和&#39;来源/功能&#39;有分歧, 并分别有27个和2个不同的提交。
是因为您的重新定位的git pull
分支现在有 25 新提交,无法从feature
到达(因为它们来自{{1}上的rebase +)加上 2 提交, 可以从master
访问,但具有不同的提交ID。这些提交包含相同的更改(即它们补丁等效)但它们具有不同的SHA-1哈希值,因为它们基于git status
中的不同提交而不是您的提交在本地存储库中重新启用它们。
这是一个例子。我们假设这是在<{1}}上feature
之前的历史记录:
origin/feature
在master
之后,origin/feature
提交了origin/feature
:
git pull
此时,您在master
之上重新A - B - C (master)
\
D - E (feature)
,其中适用 git pull
和master
:
F
与此同时,远程分支A - B - C - F (master, origin/master)
\
D - E (feature)
仍然基于提交feature
:
master
如果您在D
上执行E
,Git会告诉您,A - B - C - F (master, origin/master)
\
D - E (feature)
分支已与origin/feature
分歧 3 ({ {1}},C
,A - B - C - F (master, origin/master)
\ \
\ D' - E' (feature)
\
D - E (origin/feature)
)和 2 (git status
,feature
)分别提交。
请注意,
feature
和origin/feature
包含与F
和D'
相同的更改,但具有不同的提交ID,因为它们已在E'
之上重新定位
解决方案是D
和E
上D'
{/ 1}} {/ 1}} E'
D
之前E
。但是,由于您可能已经F
提交但尚未推送到git pull
,您可能希望这样做:
master
以避免在feature
与您的本地feature
之间创建合并提交。
根据this comment,我扩展了分支。 master
在rebase之后报告feature
和origin
分歧的原因是由于rebase带来了对git checkout feature && git pull --rebase
的新提交,加上重写之前推送到origin/feature
的提交。
在之后考虑的情况,但在之前
feature
此时,git status
和feature
指向相同的提交origin/feature
- 换句话说,他们会在&#34; 同步&#34 ;.在feature
之上重新定位origin/feature
之后,历史记录将如下所示:
A - B - C - F (master)
\
D - E (feature, origin/feature)
如您所见,feature
和origin/feature
分歧,他们的共同祖先是提交E
。这是因为feature
现在包含来自master
加A - B - C - F (master)
\ \
\ D' - E' (feature)
\
D - E (origin/feature)
和feature
的新提交origin/feature
(读作&#34; D prime &#34;和&#34; E prime &#34;)这些提交C
和feature
应用于F
之上。尽管它们包含相同的更改,但Git认为它们是不同的,因为它们具有不同的提交ID。同时,master
仍引用D'
和E'
。
此时,您已经重写了历史记录:您已经通过对其进行重新定位来修改现有提交,从而有效地创建了&#34; new&#34;的。
现在,如果您要在D
上运行E
,这将会发生什么:
F
由于origin/feature
执行D
+ E
,这将导致创建合并提交git pull
,其父项为feature
且{{1 }}
相反,如果您运行了A - B - C - F (master)
\ \
\ D' - E'- M (feature)
\ /
D - E - (origin/feature)
(即git pull
+ git fetch
),那么Git会:
git merge
以提交M
(E'
和E
的共同祖先)git pull --rebase
git fetch
和git rebase
feature
,C
和feature
但是,注意到origin/feature
和D
包含与E
和origin/feature
相同的更改,Git会丢弃它们,导致历史记录如下:< / p>
F
请注意先前可从D'
访问的提交E'
如何应用于D'
之上,从而导致E'
。此时,D
会告诉您:
您的分支机构领先于原创/功能&#39;由1提交。
当然,提交是E
。
答案 1 :(得分:7)
如果Table 'my_db.wrong_table_name' doesn't exist
和master
的远程版本是单独更新的,则只需重置您的本地功能分支
feature/branch
然后,如果您想在git checkout feature/branch
git fetch origin feature/branch
git reset --hard origin/feature/branch
分支中引入更改,
master
答案 2 :(得分:1)
当您在master上重新设置功能分支时,您创建了一堆新提交。但是,您的origin/feature
分支仍指向旧分支。这是rebase之后的情况:
C' (feature)
B'
A'
* (master, origin/master)
*
*
| C (origin/feature)
| B
| A
|/
* some base commit
虽然提交A'
包含与提交A
类似的更改集,但它绝不是相同的提交。它包含一个不同的树,并且具有不同的父级。
现在,当您尝试再次提取feature
时,您会尝试创建此历史记录:
* (feature)
|\
C'|
B'|
A'|
* | (master, origin/master)
* |
* |
| C (origin/feature)
| B
| A
|/
* some base commit
您正在合并两个分支,它们引入了非常相似的,不同的喷射变化。除了毫无意义之外,这必然会造成大量冲突。
您需要做的是使用git push -f
通知您的上游代表有关rebase的信息。 这将丢失旧历史记录,并将其替换为重写的。
另一种方法是避免在已经推送到任何其他存储库的分支上使用git rebase
,或者完全避免使用git rebase
。 这是一种更清洁的方法:它会产生历史,而不是像git rebase
那样对历史撒谎。这至少是我喜欢的。
答案 3 :(得分:0)
have 27 and 2 different commits each
告诉您,您现在有{27}个来自master
的新提交和2个新提交,而origin/<yourbranch>
中没有这些提交。
由于rebase已大量更改了origin/<yourbranch>
,因此它不再与origin/<yourbranch>
具有共同基础。因此,您不希望在rebase之后从origin/<yourbranch>
提取更改,因为如您所见,所有H ***都会松动。
如果您知道本地分支机构中需要origin/<yourbranch>
的变化,那么请在重新定位之前将其拉出来。
如果您确定自上次推送以来没有人更改origin/<yourbranch>
(如果这是您自己的功能分支,则可以安全下注),您可以使用push --force
将它们再次同步。然后origin/<yourbranch>
将再次与您的本地分支具有相同的基础,并且该基数将包含所有最新的master
更改。