Git 还原多个提交

Git revert several commits

我已经对我的本地分支 estimation 进行了多次提交,并将它们推送到远程分支 estimation

现在,我想完全删除最后 3 次提交。

我尝试执行 git reset HEAD^git reset HEAD --hard 3 次,但是当我尝试推送更改时,它抱怨 HEAD 的尖端未对齐。

我该怎么做?

编辑:

历史如下所示:

commit e572aab4e18

commit e21e7310bc4

commit 4f372a513da

commit 31a4ac607ae

commit a1a6e3f02dd

我想删除前 4 个并返回 commit a1a6e3f02dd 并在同一个 HEAD 上创建本地和远程分支。

如果您已经推送了提交(并且不想强制推送和覆盖远程存储库中的数据,您可以做几件事):

您可以使用 git revert 代替 git reset:

$ git revert ~4..HEAD

或者您可以使用 git checkout 然后提交更改:

$ git checkout ~3 -- .
$ git commit

git revert 将进行 3 次独立的还原提交。 git checkout 方法将允许您在一次提交中恢复更改。

对于你的情况,你可以这样做:

$ git reset --hard $REMOTE/$BRANCH
$ git checkout a1a6e3f02dd -- .
$ git commit

首先:您应该只对您不共享的分支执行此操作;如果分支被其他人签出,这个过程将使他们的本地副本与远程不同步,他们将无法再将提交推送到分支。这可以解决,但可能会造成混乱。

鉴于此,如果我理解正确的话,你处于这种情况:

xxxxxxx Bad commit #3
yyyyyyy Bad commit #2
zzzzzzz Bad commit #3
wwwwwww This and everything before it are fine

您想删除 wwwwwwww 之后的提交并修复远程分支以匹配。

首先,备份你正在做手术的分支,这样如果你搞砸了你可以恢复它,然后切换回你想要从中删除提交的分支。

git checkout -b broken-estimation
git checkout estimation

运行 git log 找到您要保留的第一个提交的 SHA1。获得 SHA1 后,将分支重置为:

git reset --hard kkkkkkk

其中 kkkkkk 是您要保留在分支上的第一个提交的 SHA1。

再次

运行 git log 以确保您已获得所需的 SHA1 作为此分支的提示;它应该是您在 git log 输出中看到的第一个提交。如果您没有削减足够的提交,请使用正确的 SHA1 重做 git reset --hard 以删除更多提交。

如果您删除了太多 提交,请从您的备份中恢复estimation 分支:

git checkout -B estimation broken-estimation

并重做 git log 以在提示处找到您想要的提交的 SHA1,然后是 git reset --hard kkkkkkkkkkkkkk 是您真正想要的 SHA1)以删除该提交之后不希望的提交。

获得所需状态的分支后,您可以将固定分支推送到远程,替换旧版本:

git push -f the_proper_remote estimation

一旦你确定你的修复是正确的,你可以删除分支的备份副本:

git branch -d broken-estimation

您可以通过三个命令完成:

首先,重写远程分支的历史:

git push origin +a1a6e3f02dd:estimation

请注意,“+”使其成为 "force-push"。此命令表示 "force a1a6e3f02dd to be the tip of the origin/estimation branch."

完成后,您只需让本地 "estimation" 分支与远程分支同步:

git checkout estimation
get reset --hard origin/estimation

大功告成!但请注意:'git reset --hard' 将清除您在该项目中所有未提交的工作。

如果其他人也在使用 'estimation' 分支,并且他们已经将您的 4 "bad" 提交拉到他们的分支中,那么协调就会有点混乱。但根据我的经验,所有关于 "never rewrite history of shared branches" 的警告和警告都被夸大了。应该重申:永远不要重写 long-lived 共享分支的历史。