通过1次提交回滚本地和远程git存储库


188

我已经阅读过有关该主题的类似文章,并且终生无法弄清楚如何正确执行此操作。

我检入了大约1000个我不想要的文件,而我不想不必经过1by1并将它们全部从存储库中删除。

  • 我有一个远程master分支。
  • 我有当地的master分公司。

他们都是在同一修订版。

我想通过1次提交回滚我的遥控器。

说我的历史masterA--B--C--D--E
我想将本机回滚到D
然后将其推送到远程,这样我当前的哈希值将同时为远程和本地D。

我在执行此操作时遇到问题。
我正在使用Git Tower,但对命令行感到满意。有什么帮助吗?

更新: 很棒的评论如下。似乎不鼓励使用重置,尤其是在与其他用户共享存储库的情况下。 取消上一次提交的更改而不使用硬重置的最佳方法是什么?有办法吗?


我已将答案更新为“无需使用硬重置即可撤消上一次提交的更改”。
VonC

3
使用git revert了没有硬重置做的和不干扰用户。
user562374 2011年


不鼓励回滚遥控器,但是如果您要这样做,请这样做。有数百种方法可以做到这一点,但是在服务器端结果是相同的。
FelipeC

Answers:


306

如果还没有人拉过您的远程存储库,则可以更改分支HEAD并强制将其推送到所述远程存储库:

git reset --hard HEAD^ 
git push -f 

(或者,如果您可以直接访问远程仓库,即使它是裸仓库,也可以更改其HEAD引用

请注意,正如Alien-technology在Windows(CMD会话)上的以下注释所注释的,您需要^^

git reset --hard HEAD^^
git push -f 

自2011年以来的更新:
使用git push --force-with-lease我在这里介绍的内容,于2013年在Git 1.8.5中引入)更安全。

有关说明,请参见Schwern答案


如果有人已经撤回了仓库怎么办?那我该怎么办?

然后,我建议不要重写历史记录的内容:

  • git revert 在本地,您的上一次提交(创建一个新的提交,该操作将撤销上一次提交的操作)
  • 推送由生成的“还原” git revert

1
如果有人已经撤回了仓库怎么办?那我该怎么办?
贾米斯·查尔斯

1
@gwho创建了一个分支?不,它会移动分支的HEAD,但是您仍在同一分支中。但是,由于推送不再是一种快进方式,因此,您需要强制执行该推送。
VonC'4

1
有没有办法知道是否有人撤回了回购协议?
Pinkerton

4
在Windows中,^字符用于换行并转义一个字符,执行以下命令:git reset --hard HEAD ^^
Alien Technology

1
@AlienTechnology在Windows 10上使用Powershell,我只需要键入reset --hard HEAD^而不reset --hard HEAD^^重置上一次提交。
加斯帕基奥(Jaspacchio)

56

将本地分支设置为一个修订版本(HEAD^意味着返回一个修订版本):

git reset --hard HEAD^

将更改推送到原点:

git push --force

您将不得不强制执行推送,因为否则git会认识到您落后origin一次提交,因此一切都不会改变。

这样做可以--force告诉git HEAD在远程仓库中覆盖它,而不考虑那里的任何进展。


1
我建议不要将此称为还原,因为这是一个特定的术语,在git中的含义非常不同。
卡斯卡贝尔2011年

@Jefromi:谢谢提示。编辑。
eckes 2011年

好答案。我已经读到,不建议使用重置,尤其是在与其他用户共享存储库的情况下,不建议使用重置。有没有一种更干净的方法可以撤销先前提交的所有更改?
贾米斯·查尔斯

小心!存放未提交的更改或丢失的更改
Nosov Pavel

这很酷。那么,这是否意味着当我们这样做时git push origin master,Git能够在远程创建一个新的提交,因为本地分支至少提前一次提交了吗?此外,后者必须与远程回购所指向的头有本质区别吗?
MadPhysicist

18

如果要还原上一次提交,请听:

第1步:

使用消息检查您的本地提交

$ git log

第2步:

删除上一次提交而无需从本地分支(或主节点)重置更改

$ git reset HEAD^

或者,如果您不希望最后的提交文件和更新监听

$ git reset HEAD^ --hard

第三步:

我们可以更新文件和代码,再次需要强行推送,它将删除以前的提交。它将保留新的提交。

$ git push origin branch -f

而已!


那不是还原提交,而是替换一个。请不要通过滥用常规术语来混淆我们git新手。
Suncat2000

7

输入贝娄命令,您可以查看自己的git commit历史记录-

$ git日志

假设您在特定分支上的历史记录类似于-commit_A,commit_B,commit_C,commit_D。其中,commit_D是最后的提交,这是HEAD保留的位置。现在,要从本地和远程删除最后一次提交,您需要执行以下操作:

第1步:通过-在本地删除最后一次提交

$ git reset --hard HEAD〜

这会将您的提交HEAD更改为commit_C

步骤2:将您的更改推送到新的HEAD提交到远程

$ git push origin + HEAD

该命令将从远程删除最后一次提交。

PS:此命令已在Mac OSX上进行了测试,并且也应在其他操作系统上也可以使用(尽管不声称具有其他操作系统)



3

这是更安全的过程的更新版本。

git reset --hard HEAD^ 
git push --force-with-lease

git push -f将用您自己的更改随意替换远程存储库。如果其他人推动了更改,则它们将丢失。git push --force-with-lease如果存储库符合您的期望,则只会推送您的基准。如果其他人已经推送,则推送将失败。

参见– 认为有害的力量;了解git的–force-with-lease

我建议将其别名为repush = push --force-with-lease

如果有人已经撤回了仓库怎么办?那我该怎么办?

告诉他们git pull --rebase=merges。而不是a git fetch origingit merge origin/master它将git fetch origingit rebase -r origin/master。这会将其所有本地更改重写master为新的rebased之上origin/master-r将保留他们可能进行的所有合并。

我建议将此作为默认行为。它很安全,可以处理其他人的重新定基,并减少不必要的合并。

[pull]
        rebase = merges

1
同意并赞成。为了辩护,我的2011年旧答案是在引入期权之前两年写的--force-with-lease
VonC

我以为我已经做到了(昨天):stackoverflow.com/posts/4647362/revisions
VonC



0

我只是想从远程删除最后一个提交,并清除提交历史。以下作品像魅力

git reset --hard HEAD^ 
git push -f 

但是“以下”与我上面的答案有何不同?
VonC

0

重置磁头并还原为先前提交的方式是通过

$ git reset HEAD^ --hard
$ git push <branchname> -f

但是有时它可能在远程分支中不被接受:

To ssh:<git repo>
 ! [rejected]        develop -> develop (non-fast-forward)
error: failed to push some refs to 'ssh:<git repo>'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. Integrate the remote changes (e.g.
hint: 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.

那么另一种方法是

git revert HEAD
git push <remote branch>

这很好。

注意:请记住是否git push -f <force>失败,然后尝试还原。git pull先做一个,使远程和本地同步,然后再尝试git revert
检查git log以确保远程和本地处于同一SHA1提交位置。

git revert 
A --> B --> C -->D
A--> B --> C --> D --> ^D(taking out the changes and committing reverted diffs)

0

在本地大师

git reflog
-- this will list all last commit
  e.g Head@{0} -- wrong push
      Head@{1} -- correct push  
git checkout Head@{1} .
  -- this will reset your last modified files

git status 
git commit -m "reverted to last best"
git push origin/master

无需担心其他人是否被撤消。

做完了!


0

如果您只想从远程存储库中删除最后一个提交而又不会弄乱本地存储库,那么这里有一个代码:

git push origin +origin/master~:master

这使用以下语法:

git push <remote> <refspec>

在这里,<remote>origin,并<refspec>具有以下结构:

+origin/master~:master

详细信息可以在中找到git-push(1)。前面的+意思是“强制推送此引用”,另一部分意思是“从origin/master~master(远程origin)”。不难知道这origin/master~是最后一次提交origin/master,对吗?


0

对我来说这两个命令:

git checkout commit_id
git push origin +name_of_branch

0

您也可以这样做:

git reset --hard <commit-hash>
git push -f origin master

并让其他所有获得最新错误提交的人重置:

git reset --hard origin/master
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.