我有一个Git存储库,看起来像这样:

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

我希望分支的头部指向A,即,我希望B、C、D和head消失,我希望头部与A同义。

听起来我可以尝试重新设置基础(不适用,因为我已经在两者之间进行了更改),也可以恢复。但如何恢复多次提交?我一次回复一个吗?订单重要吗?


当前回答

还原共享存储库上的一组提交的简单方法是将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

其他回答

我真的想避免硬重置,这就是我想到的。

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

与Jakub的回答类似,这允许您轻松选择要还原的连续提交。

# Revert all commits from and including B to HEAD, inclusively
git revert --no-commit B^..HEAD
git commit -m 'message'

我很沮丧,这个问题无法得到回答。其他所有问题都与如何正确还原和保存历史有关。这个问题说:“我希望分支的头部指向A,即我希望B、C、D和head消失,我希望头部与A同义。”

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

我在阅读Jakub的帖子时学到了很多东西,但公司里的一些人(可以在没有Pull Request的情况下推送到我们的“测试”分支)推送了五次错误的提交,试图修复他在五次提交之前犯的错误。不仅如此,还接受了一到两个拉取请求,但现在情况很糟糕。所以忘掉它吧;我找到了最后一个好的提交(abc1234),并运行了基本脚本:

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

我告诉在这个仓库工作的其他五个人,他们最好记录下过去几个小时的变化,并从最新的测试中删除/重新广播。故事结束。

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

考虑到您的示例,您必须这样做(假设您在分支“master”上):

git revert master~3..master

或git revert B…D或git return D C B

这将使用B、C和D的反向提交在本地创建一个新的提交(这意味着它将撤消这些提交带来的更改):

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

这些都不适用于我,所以我有三次提交要恢复(最后三次提交),所以我做到了:

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

工作起来很有魅力:)