如何在Git中丢弃未暂存的更改?

如何丢弃不在索引中的工作副本中的更改?

3671805 次浏览

对于当前工作目录中的所有未上演文件,请使用:

git restore .

对于特定文件使用:

git restore path/to/file/to/revert

它与git switch一起替换了重载的git checkout在这里看到),从而消除了参数消歧义。

如果文件同时具有暂存和未暂存更改,则仅恢复git diff中显示的未暂存更改。git diff --staged中显示的更改保持不变。

在Git 2.23之前

对于当前工作目录中的所有未暂存文件:

git checkout -- .

对于特定文件:

git checkout -- path/to/file/to/revert

--在这里消除歧义(这被称为论据消歧)。

另一种更快的方法是:

git stash save --keep-index --include-untracked

如果您不想彻底了解它,则不需要包含--include-untracked

之后,如果您愿意,您可以使用git stash drop命令删除该存储。

这将签出当前目录的当前索引,丢弃当前目录向下的文件中的所有更改。

git checkout .

或者这个从索引中签出所有文件,覆盖工作树文件。

git checkout-index -a -f

如果您对保留未暂存的更改不感兴趣(特别是如果暂存更改是新文件),我发现这很方便:

git diff | git apply --reverse

尝试了上述所有解决方案,但仍然无法摆脱新的、未暂存的文件。

使用git clean -f删除这些新文件-但要谨慎!注意force选项。

git clean -df

从当前目录开始,通过递归删除不受版本控制的文件来清理工作树。

-d:除了未跟踪的文件外,删除未跟踪的目录

-f:强制(根据clean.requireForce设置,可能不需要)

运行git help clean查看手册

另一种摆脱新文件的方法比git Clean-df更具体(它将允许您摆脱一些文件,而不一定是所有文件),是先将新文件添加到索引中,然后存储,然后删除存储。

当由于某种原因无法通过某些普通机制(如rm)轻松删除所有未跟踪的文件时,此技术很有用。

我真的发现这篇文章有助于解释何时使用什么命令:http://www.szakmeister.net/blog/2011/oct/12/reverting-changes-git/

有几个不同的案例:

  1. 如果您还没有暂存文件,那么您可以使用git checkout。签出“更新工作树中的文件以匹配索引中的版本”。如果文件没有暂存(也就是添加到索引中)…此命令将基本上将文件恢复为您上次提交的文件。

    git checkout -- foo.txt

  2. 如果您已暂存文件,请使用git重置。重置会更改索引以匹配提交。

    git reset -- foo.txt

我怀疑使用git stash是一个流行的选择,因为它的危险性较小。如果你在使用git重置时不小心吹得太多,你可以随时返回到它。重置默认是递归的。

查看上面的文章以获得进一步的建议。

似乎完整的解决方案是:

git clean -dfgit checkout -- .

警告:虽然它不会删除. gitignore中直接提到的忽略文件,git clean -df可以删除驻留在文件夹中的忽略文件

#0删除所有未跟踪的文件,git checkout清除所有未暂存的更改。

当您想将存储转移给其他人时:

# add filesgit add .# diff all the changes to a filegit diff --staged > ~/mijn-fix.diff# remove local changesgit reset && git checkout .# (later you can re-apply the diff:)git apply ~/mijn-fix.diff

[编辑]如上所述,可以命名藏匿点。好吧,如果你想分享你的藏匿点,就用这个;)

这甚至在目录中工作;在正常的git权限之外。

sudo chmod -R 664 ./* && git checkout -- . && git clean -dfx

最近发生在我身上

如果您正在使用存储库的分叉,并且您经常与另一个存储库同步(例如拉取请求),那么以下实际上只是一个解决方案。简短的回答:删除分叉和重新分叉,但阅读github上的警告

我有一个类似的问题,也许不完全相同,我很遗憾地说,我的解决方案并不理想,但它最终是有效的。

我经常会有这样的git状态消息(至少涉及2/4个文件):

$ git status# Not currently on any branch.# Changes to be committed:#   (use "git reset HEAD <file>..." to unstage)##       modified:   doc/PROJECT/MEDIUM/ATS-constraint/constraint_s2var.dats#       modified:   doc/PROJECT/MEDIUM/ATS-constraint/parsing/parsing_s2var.dats## Changes not staged for commit:#   (use "git add <file>..." to update what will be committed)#   (use "git checkout -- <file>..." to discard changes in working directory)##       modified:   doc/PROJECT/MEDIUM/ATS-constraint/constraint_s2Var.dats#       modified:   doc/PROJECT/MEDIUM/ATS-constraint/parsing/parsing_s2Var.dats

敏锐的眼睛会注意到这些文件有一个单独的字母,以防丢失。不知何故,我不知道是什么让我走上了这条路(因为我自己没有从上游存储库处理这些文件),我已经切换了这些文件。尝试本页面(和其他页面)上列出的许多解决方案似乎没有帮助。

我能够通过删除我的分叉存储库和所有本地存储库并重新分叉来解决问题。仅此还不够;上游必须将有问题的文件重命名为新文件名。只要你没有任何未提交的工作,没有wiki,也没有与上游存储库发散的问题,你就应该很好。至少可以说,上游可能对你不太满意。至于我的问题,毫无疑问是用户错误,因为我不是那么精通git,但事实上,修复git的问题也远非容易。

git checkout -f


man git-checkout

-f, --force

切换分支时,即使索引或工作树与HEAD不同,也继续进行。这用于丢弃本地更改。

从索引中签出路径时,不要在未合并的条目上失败;相反,未合并的条目将被忽略。

cd path_to_project_folder  # take you to your project folder/working directorygit checkout .             # removes all unstaged changes in working directory

我最喜欢的是

git checkout -p

这允许您选择性地恢复块。

另见:

git add -p

如果所有暂存文件都已提交,则可以简单地重置分支,例如从您的GUI中重置,只需单击三次鼠标:重置

所以我在实践中经常做的恢复不需要的本地更改的事情是提交所有好的东西,然后重置分支。

如果好的东西是在一次提交中提交的,那么你可以使用“修改最后一次提交”将其恢复到暂存或未暂存状态,如果你最终想以不同的方式提交它。

这可能不是您正在寻找的问题的技术解决方案,但我发现它是一个非常实用的解决方案。它允许您有选择地丢弃未分阶段的更改,重置您不喜欢的更改并保留您喜欢的更改。

所以总结一下,我只做了提交分支复位修改最后一次提交

简单地说

git stash

它将删除所有本地更改。您也可以稍后使用,例如

git stash apply

或git stash pop

我没有放弃更改,而是将遥控器重置为原点。注意-此方法是将您的文件夹完全恢复到存储库的文件夹。

所以我这样做是为了确保当我git重置时它们不会坐在那里(稍后-排除Origin/分支名称上的gitignores)

注意:如果您想保留尚未跟踪的文件,但不是在GITIGNORE中,您可能希望跳过此步骤,因为它会擦除在远程存储库中找不到的这些未跟踪的文件(感谢@XtrmJosh)。

git add --all

然后我

git fetch --all

然后我回到原点

git reset --hard origin/branchname

这将使它回到原点。就像重新克隆分支一样,同时将我所有的gitignored文件保存在本地和适当的位置。

根据下面的用户评论更新:将用户重置为当前分支的变量。

git reset --hard @{u}

您可以使用git stash-如果出现问题,您仍然可以从stash恢复。类似于这里的其他答案,但这个也删除了所有未暂存的文件和所有未暂存的删除:

git add .git stash

如果你检查一切正常,扔掉藏匿:

git stash drop

来自Bilal Maqsood的答案git clean也对我有用,但是我有更多的控制权-如果我不小心做了某事,我仍然可以拿回我的更改

更新

我认为还有一个变化(不知道为什么这对我有用):

git add . -A而不是git add .

如果没有-A,删除的文件将不会被暂存

如果你是在子模块的情况下,没有其他解决方案的工作尝试:

  • 要检查问题是什么(可能是“脏”情况),请使用:

    git diff

  • 删除存储

    git submodule update

如果您只是更改了文件的权限(这是在DOS/Windoze上),这些解决方案都不起作用

Mon 23/11/2015-15:16:34.80 C:\...\work\checkout\slf4j+> git statusOn branch SLF4J_1.5.3Changes not staged for commit:(use "git add ..." to update what will be committed)(use "git checkout -- ..." to discard changes in working directory)
modified:   .gitignoremodified:   LICENSE.txtmodified:   TODO.txtmodified:   codeStyle.xmlmodified:   pom.xmlmodified:   version.pl
no changes added to commit (use "git add" and/or "git commit -a")
Mon 23/11/2015-15:16:37.87 C:\...\work\checkout\slf4j+> git diffdiff --git a/.gitignore b/.gitignoreold mode 100644new mode 100755diff --git a/LICENSE.txt b/LICENSE.txtold mode 100644new mode 100755diff --git a/TODO.txt b/TODO.txtold mode 100644new mode 100755diff --git a/codeStyle.xml b/codeStyle.xmlold mode 100644new mode 100755diff --git a/pom.xml b/pom.xmlold mode 100644new mode 100755diff --git a/version.pl b/version.plold mode 100644new mode 100755
Mon 23/11/2015-15:16:45.22 C:\...\work\checkout\slf4j+> git reset --hard HEADHEAD is now at 8fa8488 12133-CHIXMISSINGMESSAGES MALCOLMBOEKHOFF 20141223124940 Added .gitignore
Mon 23/11/2015-15:16:47.42 C:\...\work\checkout\slf4j+> git clean -f
Mon 23/11/2015-15:16:53.49 C:\...\work\checkout\slf4j+> git stash save -uSaved working directory and index state WIP on SLF4J_1.5.3: 8fa8488 12133-CHIXMISSINGMESSAGES MALCOLMBOEKHOFF 20141223124940 Added .gitignoreHEAD is now at 8fa8488 12133-CHIXMISSINGMESSAGES MALCOLMBOEKHOFF 20141223124940 Added .gitignore
Mon 23/11/2015-15:17:00.40 C:\...\work\checkout\slf4j+> git stash dropDropped refs/stash@{0} (cb4966e9b1e9c9d8daa79ab94edc0c1442a294dd)
Mon 23/11/2015-15:17:06.75 C:\...\work\checkout\slf4j+> git stash dropDropped refs/stash@{0} (e6c49c470f433ce344e305c5b778e810625d0529)
Mon 23/11/2015-15:17:08.90 C:\...\work\checkout\slf4j+> git stash dropNo stash found.
Mon 23/11/2015-15:17:15.21 C:\...\work\checkout\slf4j+> git checkout -- .
Mon 23/11/2015-15:22:00.68 C:\...\work\checkout\slf4j+> git checkout -f -- .
Mon 23/11/2015-15:22:04.53 C:\...\work\checkout\slf4j+> git statusOn branch SLF4J_1.5.3Changes not staged for commit:(use "git add ..." to update what will be committed)(use "git checkout -- ..." to discard changes in working directory)
modified:   .gitignoremodified:   LICENSE.txtmodified:   TODO.txtmodified:   codeStyle.xmlmodified:   pom.xmlmodified:   version.pl
no changes added to commit (use "git add" and/or "git commit -a")
Mon 23/11/2015-15:22:13.06 C:\...\work\checkout\slf4j+> git diffdiff --git a/.gitignore b/.gitignoreold mode 100644new mode 100755diff --git a/LICENSE.txt b/LICENSE.txtold mode 100644new mode 100755diff --git a/TODO.txt b/TODO.txtold mode 100644new mode 100755diff --git a/codeStyle.xml b/codeStyle.xmlold mode 100644new mode 100755diff --git a/pom.xml b/pom.xmlold mode 100644new mode 100755diff --git a/version.pl b/version.plold mode 100644new mode 100755

解决此问题的唯一方法是手动重置更改文件的权限:

Mon 23/11/2015-15:25:43.79 C:\...\work\checkout\slf4j+> git status -s | egrep "^ M" | cut -c4- | for /f "usebackq tokens=* delims=" %A in (`more`) do chmod 644 %~A
Mon 23/11/2015-15:25:55.37 C:\...\work\checkout\slf4j+> git statusOn branch SLF4J_1.5.3nothing to commit, working directory clean
Mon 23/11/2015-15:25:59.28 C:\...\work\checkout\slf4j+>
Mon 23/11/2015-15:26:31.12 C:\...\work\checkout\slf4j+> git diff

无论你的repo处于什么状态,你都可以重置为之前的任何提交:

git reset --hard <commit hash>

这将丢弃在该提交之后所做的所有更改。

由于没有答案表明我使用的确切选项组合,这里是:

git clean -dxn .  # dry-run to inspect the list of files-to-be-removedgit clean -dxf .  # REMOVE ignored/untracked files (in the current directory)git checkout -- . # ERASE changes in tracked files (in the current directory)

这是使用的git clean选项的在线帮助文本:

-d

除了未跟踪的文件外,还删除未跟踪的目录。如果未跟踪的目录由不同的Git存储库管理,则默认不会删除它。如果您真的想删除这样的目录,请使用-f选项两次。

-x

不要使用从.gitignore(每个目录)和$GIT_DIR/info/exclude读取的标准忽略规则,但仍然使用-e选项给出的忽略规则。这允许删除所有未跟踪的文件,包括构建产品。这可以用于(可能与git reset一起使用)创建一个原始工作目录来测试干净的构建。

-n

实际上不要删除任何东西,只是显示会做什么。

-f

如果Git配置变量clean.requireForce未设置为false,Git Clean将拒绝删除文件或目录,除非给出-f-n-i。Git将拒绝删除.git子目录或文件中的目录,除非给出第二个-f

当您键入git状态时,(使用“git check out--…”丢弃工作目录中的更改)显示。

例如git checkout -- .

在我看来,

git clean -df

应该做的把戏。根据Git留档

git-Clean-从工作树中删除未跟踪的文件

特性介绍

通过递归删除以下文件来清理工作树不受版本控制,从当前目录开始。

通常,仅删除Git未知的文件,但如果-x选项被指定时,忽略的文件也会被删除。例如,这可以可以删除所有构建产品。

如果给出了任何可选的…参数,则只有这些路径影响

选项

-d除了未跟踪的文件外,还删除未跟踪的目录。如果未跟踪的目录由不同的Git存储库管理,则默认情况下不删除。如果您真的想要,请使用-f选项两次删除这样的目录。

-f--force如果Git配置变量clean.requireForce未设置为false,除非给定-f、-n或-i,否则git Clean将拒绝运行。

只需使用:

git stash -u

成交。放松。

如果你真的关心你的藏匿堆栈,那么你可以跟随git stash drop。但在这一点上,你最好使用(来自Mariusz诺瓦克):

git checkout -- .git clean -df

尽管如此,我还是最喜欢git stash -u,因为它在一个命令中“丢弃”了所有跟踪和未跟踪的更改。然而git checkout -- .只丢弃跟踪的更改,git clean -df只丢弃未跟踪的更改……输入两个命令工作量太大:)

只需使用:

git stash -k -u

这将隐藏非阶段性变更未跟踪的文件(新文件)并保留分阶段文件。

它比reset/checkout/clean要好,因为你可能希望它们稍后(在git stash pop之前)回来。将它们保存在藏匿处比丢弃它们要好。

我遇到了一个奇怪的情况,文件总是未分阶段,这有助于我解决。

git rm. git属性库
git add-a
#添加代码git重置--hard

最简单的方法是使用此命令:

此命令用于丢弃工作目录中的更改-

git checkout -- .

https://git-scm.com/docs/git-checkout

在git命令中,隐藏未跟踪的文件是通过使用:

git stash -u

http://git-scm.com/docs/git-stash

您可以创建自己的别名,以描述性的方式描述如何做到这一点。

我使用下一个别名来丢弃更改。


丢弃工作树中文件(列表)中的更改

discard = checkout --

然后你可以使用它作为下一步来丢弃所有更改:

discard .

或者只是一个文件:

discard filename

否则,如果您想丢弃所有更改以及未跟踪的文件,我将使用签出和清理的混合:

清理并丢弃工作树中的更改和未跟踪文件

cleanout = !git clean -df && git checkout -- .

所以用法很简单,如下所示:

cleanout

Now在下一个包含很多别名的Github存储库中可用:

如果几乎不可能排除对文件的修改,您是否考虑过忽略它们?如果这句话是正确的,并且您在开发过程中不会接触这些文件,则此命令可能很有用:

git update-index --assume-unchanged file_to_ignore

如果你只是希望删除对现有文件的更改,使用checkout这里记录)。

git checkout -- .
  • 没有指定分支,因此它签出当前分支。
  • 双连字符(--)告诉Git下面的内容应该作为它的第二个参数(路径),您跳过了分支的规范。
  • 周期(.)表示所有路径。

如果你想要自上次提交以来的删除添加的文件,请使用clean这里记录):

git clean -i
  • -i选项启动交互式clean,以防止错误删除。
  • 还有一些其他选项可用于更快的执行;请参阅留档。

如果您希望将更改移动到保存空间以供以后访问,请使用stash这里记录):

git stash
  • 所有更改都将移动到Git的Stash,以便以后访问。
  • 有一些选项可用于更细致入微的存储;请参阅留档。

要执行永久丢弃:git reset --hard

为以后保存更改:git stash

你有一个非常简单的git命令git checkout .

2019更新

您现在可以丢弃一个跟踪文件中未暂存的更改:

git restore <file>

在当前目录中的所有跟踪文件中(递归):

git restore .

如果您从存储库的根目录运行后者,它将丢弃项目中所有跟踪文件中未暂存的更改。

备注

  • git restore2019年7中引入,并在2.23版中发布,作为git checkout命令拆分为git restore用于文件和git switch用于分支的一部分。
  • git checkout仍然像以前一样,旧的答案仍然完全有效。
  • 当运行git status并在工作树中进行未分阶段的更改时,这就是Git现在建议使用的丢弃它们(而不是v2.23之前的git checkout -- <file>)。
  • git checkout -- .一样,这仅丢弃跟踪文件中的更改。因此马吕斯·诺瓦克的回答仍然适用,如果您想丢弃所有未暂存的更改,包括未跟踪的文件,您可以按照他的建议运行额外的git clean -df

提醒一下,较新版本的git有恢复命令,这也是在更改文件时输入git状态的建议:

(使用“git add…”更新将要提交的内容)

(使用“git恢复…”放弃工作目录中的更改)

所以git'恢复'是这个问题的现代解决方案。输入'git state'后阅读git的建议总是一个好主意:-)

如果您想恢复未暂存的文件,请使用git恢复--分阶段。

git checkout .

这将丢弃对分支的任何未提交的更改。如果有任何更改被提交,它不会重置它。当你做了一些更改并决定出于某种原因不想要它们并且你没有提交这些更改时,这很方便。它实际上只是再次签出分支并丢弃任何当前未提交的更改。

(必须在应用程序的根目录或主目录中才能正常工作)

要删除未分阶段的更改,我尝试了“git恢复”。正如Git告诉我的那样,但它就是不起作用。一个非常好的方法是使用:

git revert --hard

它工作得很好。它的Git帮助完美地解释了这一点:

<强>--硬重置索引和工作树。此后对工作树中跟踪文件的任何更改都将被丢弃。写入任何跟踪文件的方式中的任何未跟踪文件或目录都会被简单地删除。

PS:我使用的是git版本2.35.3.windows.1。我认为这里的一些答案使问题变得过于复杂。

放弃工作目录使用中的更改git checkout -- <file>--表示当前分支的更改引用:-