如何放弃对分支所做的所有更改?

180

我目前在一个分支(即design)中工作,并且已经做了许多更改,但是我需要放弃它们并将其重置为匹配存储库版本。 我认为git checkout design可以实现这一点,但它只是告诉我我已经在design分支中,并且有3个修改过的文件。

我该如何放弃这些更改并获取远程服务器上当前分支的状态?


这是我在相关问题上的答案链接:https://dev59.com/h2Eh5IYBdhLWcg3wRBj5#65398480 - anupamkrishna
15个回答

301
注意:这个操作无法撤销
尝试使用git checkout -f命令,这将会放弃所有未在所有分支和主分支中提交的本地更改。

成功了!谢谢!我一直试图结账,但它不让我。它一直说我必须“提交”或“藏起来”,但我想要的只是抛弃我所做的每一个更改。这个方法奏效了!谢谢。 - No One

124

git reset --hard 命令可以帮助你放弃最近一次提交之后的所有更改。


10
或者 git reset --hard HEAD^ 的意思是撤销最近一次的提交并删除所有未提交的更改。 - deadfish
54
“git reset --hard HEAD^” 应该真正成为被接受的答案。原帖没有询问其他分支…… - riddle_me_this
2
我尝试了这个,并且我认为它删除了自从上次提交以来的所有内容,而不仅仅是我的最后一次提交。 - Chase Roberts
4
我尝试了 git reset --hard HEAD^,但仍有一堆未被跟踪的文件。现在要通过谷歌找出如何用一个简单的命令来删除它们。 - John Deighan
1
你也可以使用 git reset origin/[你的分支] --hard。这与之前的命令相同,但更容易理解正在发生的事情。 - Roberto Fernandes

38
git diff master > branch.diff
git apply --reverse branch.diff

如果你的目标是将特定分支的状态设置为与主分支相同,以下步骤可能非常有用。要做到这一点,请在特定分支内运行以下命令,然后在完成后使用 git rm [branch name].diff 删除 [branch name].diff 文件。 - karolus
1
这里不起作用。我收到了“错误:在删除一个前导路径组件(第5行)时,git diff标头缺少文件名信息”的错误。 - guettli

21

如果你不想让设计有任何改变,而且一定要与远程分支完全匹配,那么你也可以删除该分支并重新创建它:

# Switch to some branch other than design
$ git br -D design
$ git co -b design origin/design            # Will set up design to track origin's design branch

9
同时执行以下命令:git checkout design; git reset --hard origin/design - Dan
在删除分支之前,我也会进行提交。 - Asarluhi
如果您在本地分支中有提交,而这些提交不在远程分支上,那么在我看来,这是陷入非常混乱的情况的配方。我绝对不会使用这个解决方案。 - erewok
1
@erewok:好的,问题明确表示提问者想要放弃所有更改。 - mipadi
1
@erewok:但是如果您在重新拉取后获得了这些提交,那么您是否会“放弃提交以匹配存储库版本”?换句话说,如果它们在远程存储库中并且您在拉取后获取了它们,则您正在执行此问题想要执行的操作。如果您还想将它们从远程存储库中删除,则确实需要执行更多命令,但这不是此问题所要求的。它想要本地分支与远程分支匹配。 - mipadi
显示剩余4条评论

11

当您想要丢弃本地分支中的更改时,可以使用git stash命令将这些更改储存。

git stash save "some_name"

您的更改将被储存,如果需要,您可以稍后检索这些更改,否则您也可以删除它。 执行此操作后,您的分支将没有任何未提交的代码,并且您可以使用git pull从主分支拉取最新的代码。


7
在源根目录下: git reset ./ HEAD <--取消暂存已经暂存的更改 git checkout ./ <--放弃未暂存的更改

7

@Will,Git Immersion 是一个非常好而且简单的 Git 教程。它会向你展示如何撤销以下情况的更改:未暂存、已暂存以及已提交。请参考第14-18个实验。


2
我只想说,一年多以后,我现在已经完成了Git的沉浸式学习。哎呀!我早该做这个了... - Will
1
这需要安装Ruby,但似乎并不总是一个选择。 - Vishnu
请在此贴中添加相关信息,以避免链接失效时答案消失。 - LudvigH

6

可逆方法以放弃所有更改:

在合并后忘记立即检出develop之后,我发现了这个问题。你猜对了:我直接在master上修改了一些文件。天啊!由于我的情况并不是独特的(我们都做过这样的事情,不是吗;->),我将提供一种可逆的方法,用于放弃所有更改,使master再次看起来像develop

执行git diff查看哪些文件被修改并评估我的错误范围后,我执行了以下操作:

git stash
git stash clear

首先,将所有更改存储起来,然后再清除它们。所有误写到master文件中的更改都将消失,使其恢复正常。

假设我现在想要恢复这些更改。我可以这样做。第一步是找到刚刚清除/删除的保存的哈希值:

git fsck --no-reflog | awk '/dangling commit/ {print $3}'

学习了哈希后,我成功地使用以下方法还原了未提交的更改:
git stash apply hash-of-cleared-stash

我并不真正想恢复那些更改,只是想验证我能否再次获取它们,所以我又清除了它们。
另一个选项是将存储应用于不同的分支(apply the stash to a different branch),而不是擦除更改。因此,在清除从错误分支工作产生的更改方面,stash为您提供了许多灵活性,以从您的错误中恢复过来。
总之,如果您想要一种可逆的清除分支更改的方法,则上述方法在这种用例中是一种较少危险的方式。

3

git checkout -f

这个命令可以满足你的需求。唯一需要注意的是,一旦执行完毕,就无法撤销。


3

对于其他人,如果您只想还原单个文件上的更改:

git restore <fileName>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接