我有一个功能分支,我有一些提交。然后我确实运行了git rebase master并将该分支合并回master。
所以就像
git checkout -b somebranch
......some work commits here .....
git checkout master
git fetch
git merge origin/master
git checkout somebranch
git rebase master
git checkout master
git merge somebranch
现在我需要完全从master中取出所有我提交的提交,可能需要稍后将它合并回master。
更新:一段时间之前更改被推送到掌握,并且合并后有很多提交,因此重置为head将无法正常工作
答案 0 :(得分:3)
git checkout -b somebranch # from "A"
......some work commits here x, y, z .....
git checkout master
git pull # call new HEAD "B"
所以我们有像
这样的东西A -> a1 -> a2 -> B <= master
\
x -> y -> z <= somebranch
然后:
git checkout somebranch
git rebase master
A -> ... -> B <= master
\
x' -> y' -> z' <= somebranch
git checkout master
git merge somebranch # call new HEAD "C"
A -> ... -> B -------------> C <= master
\ /
x' -> y' -> z' <= somebranch
因此,此时,只需将master重新绑定到B
,即可轻松撤消您不需要的合并。但是,一旦你推送 C
(其他人已经看到它,和/或在它上面完成工作),这就变得很难。
简单的解决方案是恢复somebranch
上的所有提交:
git revert x'..z'
并推送。
现在,在您再次合并somebranch
之前,您必须重新绑定它(就像您最初那样)。这样可行,但你最终会在主人的历史中留下一些噪音。
如果有限数量的人已经看到和/或有过孩子,并且您可以与他们协调,那么可以避免这种情况,但这需要做很多工作。 你必须确保他们正在处理的所有事情都被提交并推送,如果可能的话,你可以改变它:
A -> ... -> B -------------> C -> c1 -> c2 -> D <= master
\ /
x' -> y' -> z' <= somebranch
到此:
c1' -> c2' -> D' <= master
/
A -> ... -> B -------------> C -> c1 -> c2 -> D
\ /
x' -> y' -> z' <= somebranch
现在中间分支将成为孤儿,新主管D'
没有您的更改,somebranch
仍然完好无损,因此您可以稍后合并。
为此,请使用:
git rebase --onto B C c1
git push --force
其他人现在必须更新到新头D'
,例如:
git fetch
git checkout master
git reset --hard origin/master
请注意,如果任何人 仍然依赖于C
进行本地提交(并且在您重新投放时在c1..D
链中尚未显示),那么他们将会需要对它们进行改造或挑选它们以适应新的历史。这可能是很多(容易出错的)工作,所以最好尽可能避免。
答案 1 :(得分:1)
在master
的本地副本上,您可以尝试以下操作,这将创建一个带有恢复更改的新提交(与您在master上已经完成的操作相反)。
git revert OLDER_COMMIT^..NEWER_COMMIT
其中OLDER_COMMIT
是您的功能分支提交的第一次提交,而NEWER_COMMIT
是功能分支的最后一次提交。
或者,您可以尝试
git revert -n OLDER_COMMIT..NEWER_COMMIT
将恢复提交所做的更改,但不会使用恢复的更改创建任何新提交。恢复仅修改工作树和索引。
注意:使用1.7.4+
答案 2 :(得分:0)
如果合并提交仍然是最新的,并且如果您还没有将该提交推回到上游,git reset --hard HEAD^
应该让您在合并之前返回提交 - 即返回您的master
分支在git merge origin/master
之后的地方。