如何在Git中丢弃本地提交?

331

我一直在做某件事情,但后来发现它完全搞砸了......在提交了其中一部分之后。因此,我尝试了以下步骤:

git reset --hard
git rebase origin
git fetch
git pull
git checkout

在哪个时刻我收到了这条消息

Your branch is ahead of 'origin/master' by 2 commits.

我想放弃我的本地提交,而不必擦除我的本地目录并重新下载所有东西。我该如何实现这一点?


7
不必执行 git fetchgit pull 两个命令 -- pull 命令已经包含了 fetch 和 merge 的操作。 - Ether
14
注意:该问题的主要问题与消息“您的分支领先于'origin/master' N个提交”无关。请不要因为这个消息而关闭其他问题作为该问题的重复。请停止这样做。 - user456814
6个回答

729
git reset --hard origin/master

将删除所有不在origin/master中的提交。其中origin是仓库名称,master是分支名称。


1
我认为带有斜杠的语法“origin/master”是指本地仓库? - Daniel C. Sobral
12
更准确地说,它将重置当前分支,使其指向与 origin/master 相同的提交。 - Christoffer Hammarström
@DanielC.Sobral 不是的,origin/master 是指向名为 origin 的远程仓库中 master 分支的引用。 - Matt
在我的分支中,我在项目内创建一个新文件夹,并提交它但不推送。然后我切换到主分支。我想创建一个没有那个文件夹的新分支。所以我使用了这个命令,而主分支已经有的文件又变得与主分支一致了。但是那个主分支之前没有的新文件夹还在那里。而且在主分支中,“git status”告诉我它很干净。我该怎么办? - littletiger
1
@littletiger git 不会跟踪文件夹,只会跟踪文件及其路径。因此,它将完全忽略空文件夹(没有文件或仅有被忽略的文件)。由于里面没有任何内容,它们不会出现在任何地方。 - Mumbleskates
显示剩余2条评论

42

顺便提一下,除了 mipadi 的答案(顺便说一句,那个答案应该是可行的),你还应该知道这样做:

git branch -D master
git checkout master

你想要的功能可以通过Git轻易实现,而且不必重新下载所有东西(引用你的话进行了简述)。这是因为你的本地仓库包含远程仓库的一份副本(该副本与你的本地目录不同,甚至与你所检出的分支都不同)。

删除一个分支是非常安全的,重建该分支也非常快速,并且不涉及任何网络流量。请记住,Git的设计初衷是主要作为本地仓库使用的。即使是远程分支在本地也有一份副本。只有一点元数据告诉Git指定的本地副本实际上是一个远程分支。在Git中,所有文件始终在您的硬盘驱动器上。

如果您除了主分支没有其他分支,您应该:

git checkout -b 'temp'
git branch -D master
git checkout master
git branch -D temp

4
但这如何区分本地提交和在远程仓库提交的提交呢?实际上,这告诉我“无法删除您当前所在的 'master' 分支。” - Daniel C. Sobral
4
当然,您不能删除当前被检出的分支。要删除主分支,请先检出另一个分支。如果没有其他分支,只需创建一个临时分支:git checkout -b temp; git branch -D master; git checkout master; git branch -D temp - slebetman
这对我有用。也许 git branch -D master 不是必要的,因为它会生成一个错误。 - Alexis Wilke
@Nyerguds我不知道您在哪个操作系统上使用什么shell,因为我已经十年没有使用Windows了,也不知道Powershell的语法,但通常'是shell语法的一部分,git checkout -b 'temp'将创建一个名为temp而不是'temp'的分支。您可能正在考虑git checkout -b "'temp'"git checkout -b '\''temp'\''。当然,这对于Linux和Mac OS是正确的。正如我所说,我不知道Windows。 - slebetman
我在Windows上执行了命令,它告诉我没有名为“temp”的分支,当我执行第4个命令时。我不得不使用文字 'temp' 来删除用该命令创建的分支。在Windows上,用双引号来围绕参数是唯一有效的引号。但是这个分支名称不包含空格或其他任何字符,所以无论如何都没有添加引号的必要;你应该在你的回答中将其省略掉。 - Nyerguds
显示剩余3条评论

22

我所做的是尝试硬重置到 HEAD。这将清除所有本地提交记录:

git reset --hard HEAD^

这是最好的答案,真的很有效。放弃所有本地提交并重置到HEAD。^字符有什么用? - karim
@karim '^' 可能是正则表达式的东西,可能是我不知道或者很久以前在手册文件中读到的深层次的东西... 抱歉啊 :) - giang nguyen
1
虽然有点晚了,但是 ^ 表示父提交,因此将重置为 HEAD^ 将放弃未提交的更改并将分支移动到上一个提交,有效地“删除”最近的提交(尽管提交仍然存在,但分支不再指向它)。答案将只有一个本地提交,其余都是未提交的更改。 @karim @giang - Invariance
1
根据learngitbranching.js.org的说法,^运算符引用提交的父级。因此,如果运行git checkout HEAD^^^,它将在git图表上“上面”3个提交处检出时间点。 - Shad

2
你需要运行。
git fetch

获取所有更改,这样你就不会收到“你的分支领先”的消息。

7
获取操作与提问者的主要问题无关,其主要问题是如何摆脱本地提交。 - user456814
1
如果我已经在本地提交了文件,然后尝试执行所提到的命令,会显示相同的错误消息。我尝试了git fetch和git fetch -p,但仍然显示相同的错误。 - Morez

2

我曾经见过远程变得不同步并需要更新的情况。如果 reset --hard 或者 branch -D 操作无效,请尝试

git pull origin
git reset --hard 

这并没有回答问题,reset --hard 在这种情况下是有效的。 - CharlesB
2
嗨 Charles,你说得对,reset --hard 在这里应该有效。然而,我只是想指出它有时无法正确重置分支,而 git pull origin 将重新同步远程并允许 reset --hard 正常工作。 - Jim Clouse

0

我必须做一个:

git checkout -b master

正如Git所说,它不存在了,因为它已经被擦除了。

git -D master

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