我有一个Git存储库,看起来像这样:
A <- B <- C <- D <- HEAD
我希望分支的头部指向A,即,我希望B、C、D和head消失,我希望头部与A同义。
听起来我可以尝试重新设置基础(不适用,因为我已经在两者之间进行了更改),也可以恢复。但如何恢复多次提交?我一次回复一个吗?订单重要吗?
我有一个Git存储库,看起来像这样:
A <- B <- C <- D <- HEAD
我希望分支的头部指向A,即,我希望B、C、D和head消失,我希望头部与A同义。
听起来我可以尝试重新设置基础(不适用,因为我已经在两者之间进行了更改),也可以恢复。但如何恢复多次提交?我一次回复一个吗?订单重要吗?
当前回答
可能比这里的其他方法不那么优雅,但我一直使用get-reset--hardHEAD~N来撤销多次提交,其中N是您想要返回的提交次数。
或者,如果不确定确切的提交次数,只需多次运行git-reset--hardHEAD^(返回一次提交),直到达到所需的状态。
其他回答
在我看来,一个非常简单和干净的方法可以是:
回到A
git checkout -f A
将master的头指向当前状态
git symbolic-ref HEAD refs/heads/master
save
git commit
如果您想暂时恢复功能的提交,那么可以使用以下一系列命令。
下面是它的工作原理
git log --pretty=oneline | grep 'feature_name' | cut -d ' ' -f1 | xargs -n1 git revert --no-edit
我真的想避免硬重置,这就是我想到的。
A -> B -> C -> D -> HEAD
返回A(后退4步):
git pull # Get latest changes
git reset --soft HEAD~4 # Set back 4 steps
git stash # Stash the reset
git pull # Go back to head
git stash pop # Pop the reset
git commit -m "Revert" # Commit the changes
还原共享存储库上的一组提交的简单方法是将git-rever与git-rev列表结合使用。后者将为您提供一个提交列表,前者将自己进行还原。
有两种方法可以做到这一点。如果要在一次提交中还原多次提交,请使用:
for i in `git rev-list <first-commit-sha>^..<last-commit-sha>`; do git revert --no-commit $i; done
这将恢复您需要的一组提交,但将所有更改保留在工作树上,之后应照常提交。
另一种选择是对每个还原的更改进行一次提交:
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回答中提供的解决方案之一的扩展。
我面临的情况是,我需要回滚的提交有些复杂,其中几个提交是合并提交,我需要避免重写历史。我无法使用一系列git-restore命令,因为我最终在添加的反转更改之间遇到了冲突。我最终使用了以下步骤。
首先,检查目标提交的内容,同时将HEAD留在分支的顶端:
git checkout -f <target-commit> -- .
(--确保<targetcommit>被解释为提交而不是文件;.指的是当前目录。)
然后,确定在回滚的提交中添加了哪些文件,因此需要删除这些文件:
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>
应该没有区别。