在Git中丢弃本地提交

由于一些糟糕的樱桃采摘,我的本地Git存储库目前领先于原点五次提交,并且状态不好。我想摆脱所有这些提交并重新开始。

显然,删除我的工作目录并重新克隆就可以了,但是再次从GitHub下载所有内容似乎有点矫枉过正,而且没有很好地利用我的时间。

也许git revert是我需要的,但我不想在原点(甚至六个)之前完成10提交,即使它确实让代码本身回到了正确的状态。我只想假装最后半个小时从未发生过。

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


请注意,这个问题是关于承诺没有的:

  • 未跟踪文件
  • 非阶段性变更
  • 分阶段但未提交的更改
1636289 次浏览

尝试:

git reset --hard <the sha1 hash>

将你的头重置到你想去的任何地方。使用gitk查看你想在哪个提交。你也可以在gitk中进行重置。

如果你的超额提交只对你可见,你可以这样做git reset --hard origin/<branch_name>返回原点。这将把存储库的状态重置为上一次提交,并丢弃所有本地更改。

执行git revert使新的提交以使每个人的历史保持理智的方式删除提交。

只需删除您的本地master分支并像这样重新创建它:

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

如果您使用的是艾特莱森SourceTree应用程序,您可以使用上下文菜单中的重置选项。

输入图片描述

在您的分支尝试中:

git reset --hard origin/<branch_name>

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

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

gitk --all

回滚到那个承诺

git reset --hard sha1_id

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

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

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

git rebase -i HEAD~2->它将重新设置最后两个提交的基础

我使用了'drop'作为我想要删除的提交签名。

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

git reset --soft HEAD~1

删除最近的提交并删除更改:

git reset --hard HEAD~1

git reset --hard @{u}*删除当前分支上的所有本地更改,包括提交。考虑到您不必查找恢复或使用分支的提交内容,我很惊讶还没有人发布这个。

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

git reset --hard <SHA-Code>

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

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

通过这种方式,您可以与分支上的最后一次提交同步。

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

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

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

git clean -df

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

git reset --hard origin/<branch_name>

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

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

这将丢弃您的本地提交并将存储库的状态重置为选定的提交。即,拉取存储库后的更改将丢失。

更新

上述过程在VS2019之前一直正常工作;在VS2022中有新的Git体验。工作流程相似,但UI有点不同。使用Git菜单中的Manage Branches而不是Team Explorer。现在只需单击左侧的分支,其历史记录就会显示在右侧。然后转到Right Click -> Reset -> Delete Changes (--hard)

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

您可以发布:

git reset --hard HEAD~5

它应该删除最后5个提交。

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

First of all what is HEAD?

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

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


detached HEAD

如果您不在最新的提交上-这意味着HEAD指向历史上的先前提交,则称为#1

在此处输入图片描述

在命令行上,它看起来像this-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 commitgit checkout -b <branch name>

git reflog

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

每次修改HEAD时,reflog中都会有一个新条目

git refloggit checkout HEAD@{...}

这将让你回到你想要的承诺

在此处输入图片描述


git reset --hard <commit_id>

“移动”你的头回到想要的提交。

# 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 stashgit reset --hard 0d1d7fc32git 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 revert <sha-1>

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

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

这个模式说明了哪个命令做什么。
如你所见,reset && checkout修改HEAD

在此处输入图片描述

如果你把你的本地仓库弄得一团糟,那么在Git中丢弃本地提交的可靠方法是…

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

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

上述过程的一个附带好处是,您将发现您的项目是否依赖于未放入git的本地文件。如果您发现您缺少文件,那么您可以从“my_broken_local_repo”复制它们并将它们添加到git。一旦您确信新的本地存储库包含您需要的一切,那么您可以删除“my_broken_local_repo”。

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

git reset --hard origin/master

PS:起源/主-是指向主分支的远程指针。您可以将master替换为任何分支名称

如果您只想丢弃本地提交并将修改保留在文件中,请执行
git重置@~
其他答案解决了硬重置问题

找到你想要恢复到的提交的sha1:

za$ git reflog... snip ...cf42fa2... HEAD@{0}: commit: fixed misc bugs~~cf42fa2... HEAD@{84}: commit: fixed params for .....73b9363... HEAD@{85}: commit: Don't symlink to themes on deployment.547cc1b... HEAD@{86}: commit: Deploy to effectif.com web server.1dc3298... HEAD@{87}: commit: Updated the theme.18c3f51... HEAD@{88}: commit: Verify with Google webmaster tools.26fbb9c... HEAD@{89}: checkout: moving to effectif

然后使用——混合标志,以便“重置HEAD和索引”:

za$ git reset --mixed cf42fa2

可用旗帜:

za$ git reset -h
-q, --quiet           be quiet, only report errors--mixed               reset HEAD and index--soft                reset only HEAD--hard                reset HEAD, index and working tree--merge               reset HEAD, index and working tree--keep                reset HEAD but keep local changes--recurse-submodules[=<reset>]control recursive updating of submodules-p, --patch           select hunks interactively-N, --intent-to-add

使用任意次数,在不删除最近创建的任何文件的情况下恢复到上次提交。

git reset --soft HEAD~1

然后使用

git reset HEAD <name-of-file/files*>

取消或取消跟踪。

您可以使用此git命令

git reset --hard origin/<branch_name>

对于所有未暂存的更改git checkout -- .

对于特定文件git checkout -- path/to/file/to/revert

更新:

您可以在此处使用新的GIT LFS:https://git-lfs.github.com/

git lfs migrate import --include="*.file_type"

然后git推送

您可以考虑使用带有drop命令的交互式rebase

所以说最后三次提交…

git rebase -i HEAD~3

交换出选择命令

pick <hash1> Commit message 1pick <hash2> Commit message 2pick <hash3> Commit message 3

用于删除命令

drop <hash1> Commit message 1drop <hash2> Commit message 2drop <hash3> Commit message 3

太长别读

在你的树枝上

git reset --hard HEAD^将丢弃最后一个本地提交

git reset --hard HEAD~n将丢弃最后n个本地提交