从主服务器恢复本地分支的提交

时间:2012-11-20 20:23:50

标签: git commit revert

我有一个功能分支,我有一些提交。然后我确实运行了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将无法正常工作

3 个答案:

答案 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之后的地方。