恢复多个git提交

我有一个像这样的git仓库:

A -> B -> C -> D -> HEAD 

我想要分支的头指向A,即我想B,C,D和HEAD消失,我想要头是A的同义词。

这听起来好像我可以尝试重设(不适用,因为我推动了变化之间),或恢复。 但是,我如何恢复多个提交? 我是否一次回复一个? 订单重要吗?

扩大我在评论中写的内容

一般的规则是,你不应该改写(改变)你已经发表的历史,因为有人可能已经基于他们的工作。 如果您重写(更改)历史logging,则会在合并其更改并更新它们时遇到问题。

因此,解决scheme是创build一个新的提交恢复您想要摆脱的更改 。 你可以使用git revert命令来做到这一点。

您有以下情况:

 A < -  B < -  C < -  D < -  master < -  HEAD

(这里的箭头指向指针的方向:在提交的情况下为“父”引用,在分支头(分支引用)的情况下为顶部提交,在HEAD引用的情况下为分支的名称)。

你需要创build以下内容:

 A < -  B <-C < -  D < -  [(BCD)^  -  1] < -  master < -  HEAD

其中“[(BCD)^ – 1]”表示提交恢复提交B,C,D中的改变的提交。math告诉我们(BCD)^ – 1 = D ^ -1 C ^ -1 B ^ -1,您可以使用以下命令获得所需的情况:

 $ git revert --no-commit D $ git revert --no-commit C $ git revert --no-commit B $ git commit -m "the commit message" 

替代的解决scheme是检查提交A的内容 ,并提交这个状态:

 $ git checkout -f A -- . $ git commit -a 

那么你会有以下情况:

 A < -  B < -  C < -  D < -  A'< -  master < -  HEAD

提交A'具有与提交A相同的内容,但是是不同的提交(提交消息,父母,提交date)。

由Charles Bailey修改的Jeff Ferland的解决schemebuild立在相同的想法上,但是使用git reset :

 $ git reset --hard A $ git reset --soft @{1} # (or ORIG_HEAD), which is D $ git commit 

为此,您只需使用revert命令,指定要恢复的提交范围。

考虑到你的例子,你必须这样做(假设你在分支'主'):

 git revert master~3..master 

这将在你的本地创build一个新的提交,反向提交B,C和D(这意味着它将撤销这些提交引入的更改):

 A <- B <- C <- D <- BCD' <- HEAD 
 git reset --hard a git reset --mixed d git commit 

这将立即成为所有人的回归。 给出一个好的提交信息。

与Jakub的答案类似,这可以让您轻松select连续的提交来恢复。

 # revert all commits from B to HEAD, inclusively $ git revert --no-commit B..HEAD $ git commit -m 'message' 

首先确保你的工作副本没有被修改。 然后:

 git diff HEAD commit_sha_you_want_to_revert_to | git apply 

然后只是提交。 不要忘记logging回复的原因。

我很沮丧,不能回答这个问题。 其他问题都是关于如何正确恢复和保存历史。 这个问题说: “我想要分支的头指向A,即我想B,C,D和HEAD 消失 ,我想要头是A的同义词。

 git checkout <branch_name> git reset --hard <commit Hash for A> git push -f 

我在Jakub的文章中学到了很多东西,但是公司里的一些人(可以不用Pull-Request就可以访问我们的“testing”分支)像5个不好的提交,试图修复和修复他提交的5个提交的错误。 不仅如此,还接受了一两个合并请求,现在已经不好了。 所以忘了吧,我find了最后一个好的提交(abc1234),然后运行基本脚本:

 git checkout testing git reset --hard abc1234 git push -f 

我告诉其他5个人在这个回购工作,他们最好记下他们在过去几个小时的变化,并从最新的testing擦拭/重新分支。 故事结束。

干净的方式,我觉得有用

 git revert --no-commit HEAD~3.. 

这个命令只用一次提交即可恢复最后3次提交。

也不重写历史。

在共享库(人们使用并且你想保留历史logging)上恢复一组提交的简单方法是使用git revert和git rev-list 。 后者将为您提供一个提交列表,前者将自行恢复。

有两种方法可以做到这一点。 如果你想在一次提交中恢复多次提交,请使用:

 for i in `git rev-list <first-commit-sha>^..<last-commit-sha>`; do git revert -n $i; done 

这将恢复你需要的一组提交,但是保留你工作树上的所有更改,你应该像往常一样提交它们。

另一个select是每个还原的更改都有一个提交:

 for i in `git rev-list <first-commit-sha>^..<last-commit-sha>`; do git revert --no-edit -s $i; done 

例如,如果你有一个提交树

  o---o---o---o---o---o---> fff eee ddd ccc bbb aaa 

eee恢复到bbb的变化,运行

 for i in `git rev-list eee^..bbb`; do git revert --no-edit -s $i; done 

这是Jakub的答案中提供的一个解决scheme的扩展

我面临的情况是,我需要回滚的提交有些复杂,有些提交是合并提交,我需要避免重写历史logging。 我无法使用一系列的git revert命令,因为我最终遇到了正在添加的reversion变更之间的冲突。 我结束了使用以下步骤。

首先,在离开HEAD的时候查看目标提交的内容:

 $ git checkout -f <target-commit> -- . 

( – 确保被解释为一个提交而不是一个文件;这个。是指当前目录。)

然后,确定在回滚的提交中添加了哪些文件,因此需要删除:

 $ git diff --name-status --cached <target-commit> 

添加的文件应该在行的开头显示为“A”,不应该有其他的区别。 现在,如果需要删除任何文件,请移除这些文件以进行删除:

 $ git rm <filespec>[ <filespec> ...] 

最后,提交回复:

 $ git commit -m 'revert to <target-commit>' 

如果需要,请确保我们回到了所需的状态:

 $git diff <target-commit> <current-commit> 

应该没有区别。

没有一个为我工作,所以我有三个提交(最后三个提交),所以我做了:

 git revert HEAD git revert HEAD~2 git revert HEAD~4 git rebase -i HEAD~3 # pick, squash, squash 

工作就像一个魅力:)

如果您想暂时恢复某个function的提交,则可以使用以下一系列命令。

下面是它的工作原理

git log –pretty = oneline | grep'feature_name'| 切-d''-f1 | xargs -n1 git revert –no-edit