恢复多个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