我有一个功能分支,它的所有提交都应该在master之前,但是当我尝试将master合并到我的功能分支时,如下所示:
(feature)$ git merge master
功能分支中的所有更改都将被删除。我也尝试使用 rebase ,但我一直得到相同的结果。
(feature)$ git rebase master
First, rewinding head to replay your work on top of it...
Fast-forwarded feature to master.
(feature)$ git checkout master
(master)$ git merge feature
Already up-to-date.
我只是git merge feature
来测试 rebase 是否有效,它没有Already up-to-date.
就像某种程度上我的功能分支落后于主人,我不知道这是怎么发生的。可能是功能分支已合并到主分支,然后使用新提交删除,但是当我完成功能分支时我想在将来部署它的时候将它添加到 master 。
我的问题是,如何在主分支之前移动所有提交到功能分支的提交
或者,在执行g it merge master
C1(特征分支)< - C2(将主控合并到特征中)< - C3(重新投入C1)
注意:
我弄清楚究竟发生了什么,有人从功能分支创建了一个新分支(功能-B ),而不是从主创建一个分支分支,然后将 feature-B 合并到主分支中:
(feature)$ git checkout -b feature-B
...
...
...
(feature-B)$ git checkout master
(master)$ git merge feature-B
(master)$ git push
然后在找出问题后,同一个开发人员将 feature-B 的合并恢复为 master
答案 0 :(得分:4)
...可能是
feature
分支合并到master
分支然后用新提交删除
很可能就是这种情况。但请注意以下事项:
当您说通过新提交删除时,您的意思是:有人创作了一个提交,通过合并feature
分支来撤销所带来的每一项更改。
然而,当我完成
feature
分支时,我希望将来在某个时候将其添加到master
,我想部署它。
这是真正的问题。 其他人已经添加了它,然后添加了一个新的提交,说:不,全部撤消。 Git现在确定(并且正确)已经添加了 和(因为添加了提交)正确的最终状态不能使用它。
这对您来说意味着这些提交对您不利。他们已经已经添加,然后会对他们施加一个新状态,以支持他们所做的事情。您无法再次添加它们:它们已经在那里。 您需要的是新提交,或恢复还原。
在这里,你很幸运。请参阅Re-doing a reverted merge in Git(问题和J-16 SDiZ's answer),然后另见Linus Torvald's article on the general topic of faulty merges,特别注意附录:使用原始版本重新创建主题分支(使用原始版本(现已恢复)提交。
答案 1 :(得分:2)
我担心你使用的某些非标准术语可能会让我对这个问题的理解蒙上阴影。但是,您建议几次将分支“可能已经”合并到master中,然后在master中撤消其更改。这可能是这样的:
x -- O -- x -- x -- M -- W -- x <--(master)
\ /
A --- B -- C <--(feature)
这至少与您描述的行为一致。在这种情况下,某人过早地将feature
合并到master
(M
),然后还原合并(W
)以解决问题。问题是,这使得git认为feature
中的master
中的更改永远不会。
(这是记录在案的行为,但我认为这最初是一个意想不到的结果;底线是,feature
和master
之间的任何未来合并都会将C
视为合并基础;所以将feature
合并到master
只是一个快进(或者无论如何都不包括A
,B
和C
所做的更改),以及将master
合并到feature
会将W
的“还原”更改带到功能分支上(从A
,B
和{{撤消所有工作1}},正如你所观察到的那样。)
解决此问题的一种方法是告诉git从新提交中重新创建C
分支。例如,如果你说
feature
这会给你
git rebase -f `git merge-base feature master` feature
现在,如果您尝试在 A' -- B' -- C' <--(feature)
/
x -- O -- x -- x -- M -- W -- x <--(master)
\ /
A --- B -- C
和feature
之间进行合并,则合并基数将为master
,您将获得预期的结果。
当然,如果O
已被推送到遥控器,则后续尝试推送feature
将被拒绝(非快进移动参考)。你可以强行推送
feature
但是你必须与repo的所有其他用户协调以清理他们的本地副本(参见“从上游rebase恢复”下的git push -f
文档)。
如果这种清理/协调是一个问题,还有另一种选择:你可以“恢复还原”。这有点乱,但是再次从
开始git rebase
你会
x -- O -- x -- x -- M -- W -- x <--(master)
\ /
A --- B -- C <--(feature)
现在你有了
git checkout feature
git merge master
由于x -- O -- x -- x -- M -- W -- x <--(master)
\ / \
A --- B -- C ----------- M2 <--(feature)
将M2
拉入W
,因此feature
上的工作似乎已撤消。接下来(仍然检查feature
):
feature
(使用 - 或原始还原提交的其他名称替换git revert W
。例如,在上图中你可以说
W
因为git revert master^
解析为提交master^
。这会给你
W
其中x -- O -- x -- x -- M -- W -- x <--(master)
\ / \
A --- B -- C ----------- M2 -- ~W <--(feature)
重做~W
撤消的更改。
答案 2 :(得分:0)
因此,在确定使用 git log 确切发生了什么后,我从功能分支创建了一个新分支:
(feature)$ git checkout -b feature-v2
(feature-v2)$ git merge master
然后我通过替换revert commit来恢复恢复(git revert <SHA>
):
(feature-v2)$ git revert d992f10ab1106f774e10766be8735a66aeb9eadc
修复了一些合并冲突,然后推送了提交 并确保没有人再次使用旧的功能分支,而是使用 feature-v2