丢弃Git中的本地提交


1466

由于某些错误的选择,我的本地Git存储库当前比源服务器提前了5次提交,并且状态不佳。我想摆脱所有这些提交,然后重新开始。

显然,删除我的工作目录并重新克隆就可以做到,但是再次从GitHub下载所有内容似乎有点过头了,并且没有充分利用我的时间。

也许git revert正是我所需要的,但是我不想在源头之前(甚至是六个)结束10次提交,即使它确实使代码本身回到了正确的状态。我只想假装最后一个半小时未曾发生。

有一个简单的命令可以做到这一点吗?这似乎是一个显而易见的用例,但我没有找到任何示例。


请注意,这个问题专门针对commits而不是

  • 未跟踪的文件
  • 不分阶段的变更
  • 上演但未提交的更改

Answers:


2467

如果多余的提交仅对您可见,则可以做 git reset --hard origin/<branch_name> 回原点。这会将存储库的状态重置为上一次提交,并将丢弃所有本地更改。

做一个git revert使得提交删除的,保持每个人的历史理智的方式提交。


90
git reset --hard <commit hash, branch, or tag>如果要转到远程分支机构以外的特定参考。
Sam Soffes 2014年

55
只是要清楚,如果你没有工作master,但在另一个分支,您应该运行git reset --hard origin/<your-branch-name>
佐尔坦

33
这不仅会丢弃本地提交,而且还会丢弃工作树中的所有内容(即本地文件)。如果您只想
取消

3
您可能要在此之后执行访存。这固定了SourceTree上等待推送的提交次数计数器。
Stan

2
git reset --hard origin/<branch_name>它还将重置项目配置,因此请注意这一点。我有一个.cfg重置为默认值的大文件。我不得不再花几个小时。
MAC

271

只需删除您的本地master分支并按如下方式重新创建它:

git branch -D master
git checkout origin/master -b master

2
当回溯您的更改会花费太多时间时,这很好用,这在我进行了几次基准调整之后发生了。
2014年

1
对于团队成员之间子树的拉/推问题很有用!
豪尔赫·奥尔皮内尔

当您要还原分支而不只是主节点时,这是完美的选择。
弗拉基米尔·雷廖夫(Fladimir Ralev)2014年

1
这不是删除单个本地提交的好方法。更好地使用git reset --hard origin/<branch_name>
Kirit Vaghela

1
也许该解决方案会起作用,但这并不意味着它是正确的解决方案。
阿兹利

201

尝试:

git reset --hard <the sha1 hash>

将您的头部重置到您想要的任何位置。使用gitk查看您要执行的提交。您也可以在gitk中进行重置。


5
对此B / C提出了有用的信息,但本杰克逊(Ben Jackson)的答案得到了准确解决我想要的内容的对勾—不需要我查找提交哈希。:)
David Moles

2
这是当你的新分支从未被推到原点的一个尚未

126

删除最近的提交:

git reset --hard HEAD~1

删除最近的提交,而不会破坏您所做的工作:

git reset --soft HEAD~1


5
有用的答案。谢谢!我使用了git reset --soft origin / master
塔伦·库玛

2
@TarunKumar谢谢!我正在使用VS集成,而您的解决方案是我能够消除我不希望在没有权限检入的分支中合并的一堆合并提交的唯一方法
。– DVK

谢谢,正是我想要的,“ git reset --soft HEAD〜1”完成了我无意提交的操作,想要还原,但是有其他文件我不想在还原后被销毁。
edvard_munch

47

如果您使用的是Atlassian SourceTree应用程序,则可以使用上下文菜单中的reset选项。

在此处输入图片说明


42

在您的分支尝试:

git reset --hard origin/<branch_name>

因此,使用“ git log”或“ git status” 来验证反转(到状态,没有本地提交)。


1
@Troyseph:上面列出的所有答案,我都按原样尝试,但未解决问题。上面的任何答案中都未说明的通用方法是此处试图回答的方法。
parasrish

3
接受的答案与您的答案相同,减去通用分支名称,并且在注释中@Zoltan明确表示Just to be clear, if you're not working on master but on another branch, you should run git reset --hard origin/<your-branch-name>
Troyseph

1
我认为这是最好的答案。
dwjohnston

21

git reset --hard @{u}*删除当前分支上的所有本地更改,包括提交。令我惊讶的是,没有人发布此消息,因为考虑到您不必查找要还原到分支或与分支一起玩的提交。

*也就是说,重置为当前位置(@{upstream}通常)origin/<branchname>,但并非总是如此


1
有些外壳(例如fish)会解释“ @”,因此您可能必须在引号中加上“ @ {u}”,例如“ git reset --hard'@ {u}”。无论如何,好发现!
trysis '18

很棒的答案很棒
Marko

1
如何打印@ {u}的值?
菲利普·雷戈

12

要查看/获取您也想返回的提交的SHA-1 ID

gitk --all

回滚到该提交

git reset --hard sha1_id

!注意。在提交之后进行的所有提交都将被删除(以及您对项目的所有修改)。因此,首先最好将项目克隆到另一个分支或复制到另一个目录。


这对于远程不再可用并且只需要将其重置为某些本地提交的情况非常有用。gitk很棒-事先没有意识到。
theRiley

如果您已经在gitk中,也可以直接在提交上单击鼠标右键,然后选择“将XY分支重置到此处”。
mkrieger1年

而且,较新的提交不会立即被删除。不再有指向它们的分支了(记住,分支不过是特定提交的“书签”)。
mkrieger1年

9

我遇到了一种情况,我想删除未推送的提交,但是该提交在另一个提交之前。为此,我使用了以下命令

git rebase -i HEAD~2 ->它将重新建立最后两次提交的基准

我使用“ drop”作为要删除的提交签名。


9

删除未跟踪的文件(未提交的本地更改)

git clean -df

永久删除所有本地提交并获取最新的远程提交

git reset --hard origin/<branch_name>

8

对于未推送的本地提交,您还可以使用git rebase -i删除或压缩提交。


1
我知道这可能不是最短的解决方案,但是我赞成您的看法,因为IMHO git rebase -i是解决许多类似问题的更通用的方法,并且可以在各种情况下提供帮助。
Stefan Marinov

1
drop删除所有提交时,请使用关键字(而不是删除行),以避免中止基准。
MichalČizmazia,

6

简单的解决方案是将本地主分支HEAD与源/主分支HEAD相匹配

git reset --hard origin/master

PS:origin / master-是指向master分支的远程指针。您可以使用任何分支名称替换master


4

在回答之前,让我们添加一些背景,解释一下这是什么HEAD。因为以下某些选项会导致头部分离

First of all what is HEAD?

HEAD只是对当前分支上当前提交(最新)的引用。在任何给定时间
只能有一个HEAD。(不包括git worktree

的内容HEAD存储在内部.git/HEAD,它包含当前提交的40个字节的SHA-1。


detached HEAD

如果您不在最新的提交上,这意味着它HEAD指向历史上的先前提交detached HEAD

在此处输入图片说明

在命令行上,它看起来像这样-SHA-1而不是分支名称,因为HEAD并不指向当前分支的尖端

在此处输入图片说明

在此处输入图片说明

有关如何从分离的HEAD中恢复的几种选择:


git checkout

git checkout <commit_id>
git checkout -b <new branch> <commit_id>
git checkout HEAD~X // x is the number of commits t go back

这将签出指向所需提交的新分支。
该命令将签出给定的提交。
此时,您可以创建一个分支并从此开始工作。

# Checkout a given commit. 
# Doing so will result in a `detached HEAD` which mean that the `HEAD`
# is not pointing to the latest so you will need to checkout branch
# in order to be able to update the code.
git checkout <commit-id>

# create a new branch forked to the given commit
git checkout -b <branch name>

git reflog

您也可以随时使用reflog
git reflog将显示任何更新的更改,HEAD并签出所需的reflog条目,将HEAD后退设置为此提交。

每次修改HEAD时,都会在 reflog

git reflog
git checkout HEAD@{...}

这将使您回到所需的提交

在此处输入图片说明


git reset --hard <commit_id>

将“ HEAD”“移动”回所需的提交。

# This will destroy any local modifications.
# Don't do it if you have uncommitted work you want to keep.
git reset --hard 0d1d7fc32

# Alternatively, if there's work to keep:
git stash
git reset --hard 0d1d7fc32
git stash pop
# This saves the modifications, then reapplies that patch after resetting.
# You could get merge conflicts if you've modified things which were
# changed since the commit you reset to.
  • 注意:(从Git 2.7开始),
    您也可以使用git rebase --no-autostash

git revert <sha-1>

“撤消”给定的提交或提交范围。
reset命令将“撤消”在给定提交中所做的任何更改。
带有撤消补丁的新提交将被提交,而原始提交也将保留在历史记录中。

# add new commit with the undo of the original one.
# the <sha-1> can be any commit(s) or commit range
git revert <sha-1>

该模式说明了哪个命令可以执行什么操作。
如您所见,reset && checkout修改HEAD

在此处输入图片说明


3

对于那些对Visual Studio解决方案感兴趣的人,这里的练习如下:

  1. Team Explorer窗口中,连接到目标存储库。
  2. 然后从中Branches,右键单击所需分支,然后选择View history
  3. History窗口中右键单击提交,然后选择Reset -> Delete changes (--hard)

这将丢弃您的本地提交,并将您的回购状态重置为选定的提交。即,您在撤回仓库后所做的更改将丢失。


2

如果您的分支比“ origin/XXX” 提前5次提交。

您可以发出:

git reset --hard HEAD~5

并且应该删除最后5次提交。


0
git reset --hard <SHA-Code>

如果您在本地副本上犯了一些错误,想要确保不会被错误地推送到远程分支,这将派上用场。

可以通过查看git仪表板的webVersion获取分支上的最后一次提交来获得SHA代码。

这样,您可以与分支上的最后一次提交同步。

您可以git pull在成功完成硬重置后执行操作,以确认syn没有任何新内容,即您可以看到该消息。

您的分行是最新的 Origin/<Branch Name>


0

如果您将本地存储库弄得一团糟,那么丢弃Git中本地提交的一种可靠方法是...

  1. 使用“ git config --get remote.origin.url”获取远程来源的URL
  2. 将本地git文件夹重命名为“ my_broken_local_repo”
  3. 使用“ git clone <url_from_1>”获取远程git存储库的新本地副本

以我的经验,Eclipse能够很好地处理周围的环境。但是,您可能需要在Eclipse中选择受影响的项目并清理它们以强制Eclipse重新构建它们。我想其他IDE也可能需要强制重建。

上述过程的一个附带好处是,您将发现您的项目是否依赖于未放入git的本地文件。如果发现丢失的文件,则可以从“ my_broken_local_repo”中复制它们并将其添加到git中。一旦确定新的本地存储库已具备所需的一切,就可以删除“ my_broken_local_repo”。


0

如果您只想丢弃本地提交并保留对文件的修改,请执行
git reset @〜
其他答案解决了硬重置

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.