如何丢弃Git中的未分级更改?

时间:2008-09-09 19:33:59

标签: git version-control

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

37 个答案:

答案 0 :(得分:4721)

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

git checkout -- .

对于特定文件用途:

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

--此处删除argument ambiguation

答案 1 :(得分:2415)

另一种更快捷的方法是:

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

如果您不想对此进行彻底解决,则无需添加--include-untracked

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

答案 2 :(得分:1744)

似乎完整的解决方案是:

git clean -df
git checkout -- .

git clean删除所有未跟踪的文件(警告:虽然它不会删除.gitignore中直接提到的忽略文件,它可能会删除隐藏在文件夹中的文件)和git checkout清除所有未分级的更改。

答案 3 :(得分:304)

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

git checkout .

或者检查索引中的所有文件,覆盖工作树文件。

git checkout-index -a -f

答案 4 :(得分:229)

git clean -df

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

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

-f:强制(可能不需要取决于clean.requireForce设置)

运行git help clean查看手册

答案 5 :(得分:93)

我最喜欢的是

git checkout -p

这可以让你有选择地还原块。

另见:

git add -p

答案 6 :(得分:82)

由于没有回答建议我使用的确切选项组合,这里是:

git clean -dfx
git checkout .

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

-d

除了未跟踪的文件外,还删除未跟踪的目录。如果未跟踪的目录由不同的Git存储库管理,则默认情况下不会删除它。如果您确实要删除此类目录,请使用-f选项两次。

-f

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

-f

请勿使用-x(每个目录)和.gitignore中的忽略规则,但仍然使用$GIT_DIR/info/exclude选项提供的忽略规则。这允许删除所有未跟踪的文件,包括构建产品。可以使用它(可能与-e一起使用)来创建一个原始的工作目录来测试干净的构建。

此外,git reset需要在回购的根目录中完成。

答案 7 :(得分:58)

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

有几种不同的情况:

  1. 如果您尚未暂存该文件,则使用git checkout。 Checkout“更新工作树中的文件以匹配索引中的版本”。如果文件尚未暂存(也就是添加到索引中)...此命令将基本上将文件还原为您上次提交的内容。

    git checkout -- foo.txt

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

    git reset -- foo.txt

  3. 我怀疑使用git stash是一个受欢迎的选择,因为它不那么危险。如果你在使用git reset时意外地吹得太厉害,你可以随时回到它。默认情况下,重置是递归的。

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

答案 8 :(得分:51)

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

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

git checkout -- .

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

在git命令中,使用以下命令来隐藏未跟踪的文件:

git stash -u

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

答案 9 :(得分:46)

如果您只希望删除对现有文件的更改,请使用checkoutdocumented here)。

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

如果您希望删除自上次提交后添加的文件,请使用cleandocumented here):

git clean -i 
  • -i选项启动交互式clean,以防止错误删除。
  • 还有一些其他选项可以更快地执行;看文档。

如果您希望将更改移至保留空间以供日后访问,请使用stashdocumented here):

git stash
  • 所有更改都将移至Git的Stash,以便以后访问。
  • 有一些选项可用于更细微的存储;看文档。

答案 10 :(得分:44)

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

git diff | git apply --reverse

答案 11 :(得分:42)

当您输入git status时, (使用" git checkout - ..."放弃工作目录中的更改) 显示。

e.g。 git checkout -- .

答案 12 :(得分:41)

git checkout -f


man git-checkout

-f, --force

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

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

答案 13 :(得分:36)

你可以使用git stash - 如果出现问题,你仍然可以从藏匿处恢复。 与此处的其他答案类似,但此处还会删除所有未暂存的文件以及所有未暂存的删除:

git add .
git stash

如果你检查一切正常,就把它藏起来:

git stash drop

Bilal Maqsood和git clean的回答对我来说也很有用,但是我有更多的控制权 - 如果我不小心做了,我仍然可以得到我的改变

<强>更新

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

git add . -A代替git add .

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

答案 14 :(得分:33)

我没有丢弃更改,而是将遥控器重置为原点。注意 - 此方法是将文件夹完全还原到repo的文件夹。

所以我这样做是为了确保他们在我git reset时不会坐在那里(稍后 - 在Origin / branchname上排除gitignores)

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

git add --all

然后我

git fetch --all

然后我重置为原点

git reset --hard origin/branchname

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

以下用户评论已更新: 变化以重置用户所在的当前分支。

git reset --hard @{u}

答案 15 :(得分:27)

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

使用git clean -f删除这些新文件 - 但要小心!注意强制选项。

答案 16 :(得分:21)

简单地说

git stash

它会删除所有本地更改。您也可以稍后再说

git stash apply 

或     git stash pop

答案 17 :(得分:21)

只需使用:

git stash -u

完成。容易。

如果您真的关心您的藏匿堆栈,那么您可以关注git stash drop。但在那时你最好不要使用(来自Mariusz Nowak):

git checkout -- .
git clean -df

尽管如此,我最喜欢git stash -u,因为它&#34;丢弃&#34;仅一个命令中所有已跟踪和未跟踪的更改。但是git checkout -- .只会丢弃跟踪的更改, 并且git clean -df只会丢弃未跟踪的更改...并且键入两个命令工作太多了:)

答案 18 :(得分:16)

这甚至可以在以下目录中使用;超出正常的git权限。

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

最近发生在我身上

答案 19 :(得分:14)

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

答案 20 :(得分:12)

2019更新:

July 2019起,已经有一个新的命令执行此操作:git restore

git status中,现在Git建议使用此命令,而不要像以前那样使用git checkout

虽然此命令还可用于将工作树还原到特定的提交或还原索引的内容,但默认情况下,工作树将还原到索引中的状态(此处要求)。 / p>

因此,为了恢复与pathspec匹配的文件(摆脱它们未进行的暂存更改),您可以这样做:

git restore <pathspec>

并删除当前存储库中所有未暂存的更改:

git restore .

git checkout -- .一样,这只会丢弃对Git跟踪的文件的更改,而不会丢弃任何新的未跟踪的文件。如果您要放弃任何暂存的更改,包括新的未跟踪的文件,则可以运行其他:

git clean -dff

请谨慎使用此稍后的命令,因为您可能会丢弃不想删除的文件。


注意git restore:由于这是一个新命令,因此its man page会发出警告:

  

此命令是实验性的。行为可能会改变。

因此,如果将来的行为发生变化,则此答案可能会过时。因此,在使用man git-restore之前先运行它是明智的选择。

答案 21 :(得分:11)

无论您的仓库处于什么状态,您都可以随时重置为之前的任何提交:

git reset --hard <commit hash>

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

答案 22 :(得分:10)

在我看来,

git clean -df

应该做的伎俩。根据{{​​3}}

  

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

说明

  

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

     

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

     

如果给出任何可选的...参数,则只有那些路径   影响。

选项

  

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

     

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

答案 23 :(得分:10)

摆脱比git clean -df更具体的新文件的另一种方法(它将允许你摆脱一些不一定的文件),是先将新文件添加到索引,然后存储,然后放下藏匿处。

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

答案 24 :(得分:9)

如果您正在使用存储库的分支,而您经常与另一个存储库同步(例如,拉取请求),那么以下内容实际上只是一种解决方案。简短回答:删除fork和refork,但读取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

敏锐的眼光会注意到这些文件中的doppleganger是一个单独的字母,以防万一。不知何故,我不知道是什么导致我开始这条路(因为我自己从上游回购中没有使用这些文件),我已经切换了这些文件。尝试此页面上列出的许多解决方案(和其他页面)似乎没有帮助。

我能够通过删除我的分叉存储库和所有本地存储库来重新解决问题。仅这一点还不够;上游必须将有问题的文件重命名为新的文件名。只要您没有任何未完成的工作,没有wiki,也没有与上游存储库不同的问题,您应该没问题。至少可以说,上游可能对你不满意。至于我的问题,它无疑是一个用户错误,因为我不是那么精通git,但事实上它很容易修复指向git的问题。

答案 25 :(得分:7)

如果您想将藏匿条件转移给其他人:

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

[编辑]评论说,它可以命名为藏匿处。好吧,如果你想分享你的藏品,请使用它;)

答案 26 :(得分:7)

您可以创建自己的别名,描述如何以描述性方式执行此操作。

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

放弃工作树

中(文件列表)中的更改
discard = checkout --

然后您可以将其用作下一个以丢弃所有更改:

discard .

或只是一个文件:

discard filename

否则,如果您想要丢弃所有更改以及未跟踪的文件,我会使用checkout和clean的混合:

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

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

所以下次使用很简单:

cleanout

现在可以在下一个包含大量别名的Github仓库中使用:

答案 27 :(得分:6)

如果所有暂存的文件都已实际提交,则可以简单地重置分支,例如只需点击三下鼠标即可在GUI中显示:分支重置

因此,我在实践中经常做的是还原不需要的本地更改是提交所有好东西,然后重置分支。

如果在一次提交中提交了好东西,那么你可以使用&#34;修改最后一次提交&#34;如果你最终想要以不同的方式提出它,那就把它带回上演或不上演。

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

总而言之,我只是做提交分支重置修改上次提交

答案 28 :(得分:6)

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

答案 29 :(得分:6)

我有一个奇怪的情况,即文件总是未分级,这有助于我解决。

  

git rm .gitattributes
  git add -A
  git reset --hard

答案 30 :(得分:6)

如果您遇到子模块且其他解决方案无效,请尝试:

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

    git diff

  • 删除藏匿

    git submodule update

答案 31 :(得分:5)

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

git update-index --assume-unchanged file_to_ignore

答案 32 :(得分:5)

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

Mon 23/11/2015-15:16:34.80 C:\...\work\checkout\slf4j+> git status
On branch SLF4J_1.5.3
Changes not staged for commit:
  (use "git add ..." to update what will be committed)
  (use "git checkout -- ..." to discard changes in working directory)

        modified:   .gitignore
        modified:   LICENSE.txt
        modified:   TODO.txt
        modified:   codeStyle.xml
        modified:   pom.xml
        modified:   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 diff
diff --git a/.gitignore b/.gitignore
old mode 100644
new mode 100755
diff --git a/LICENSE.txt b/LICENSE.txt
old mode 100644
new mode 100755
diff --git a/TODO.txt b/TODO.txt
old mode 100644
new mode 100755
diff --git a/codeStyle.xml b/codeStyle.xml
old mode 100644
new mode 100755
diff --git a/pom.xml b/pom.xml
old mode 100644
new mode 100755
diff --git a/version.pl b/version.pl
old mode 100644
new mode 100755

Mon 23/11/2015-15:16:45.22 C:\...\work\checkout\slf4j+> git reset --hard HEAD
HEAD 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 -u
Saved working directory and index state WIP on SLF4J_1.5.3: 8fa8488 12133-CHIXMISSINGMESSAGES MALCOLMBOEKHOFF 20141223124940 Added .gitignore
HEAD is now at 8fa8488 12133-CHIXMISSINGMESSAGES MALCOLMBOEKHOFF 20141223124940 Added .gitignore

Mon 23/11/2015-15:17:00.40 C:\...\work\checkout\slf4j+> git stash drop
Dropped refs/stash@{0} (cb4966e9b1e9c9d8daa79ab94edc0c1442a294dd)

Mon 23/11/2015-15:17:06.75 C:\...\work\checkout\slf4j+> git stash drop
Dropped refs/stash@{0} (e6c49c470f433ce344e305c5b778e810625d0529)

Mon 23/11/2015-15:17:08.90 C:\...\work\checkout\slf4j+> git stash drop
No 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 status
On branch SLF4J_1.5.3
Changes not staged for commit:
  (use "git add ..." to update what will be committed)
  (use "git checkout -- ..." to discard changes in working directory)

        modified:   .gitignore
        modified:   LICENSE.txt
        modified:   TODO.txt
        modified:   codeStyle.xml
        modified:   pom.xml
        modified:   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 diff
diff --git a/.gitignore b/.gitignore
old mode 100644
new mode 100755
diff --git a/LICENSE.txt b/LICENSE.txt
old mode 100644
new mode 100755
diff --git a/TODO.txt b/TODO.txt
old mode 100644
new mode 100755
diff --git a/codeStyle.xml b/codeStyle.xml
old mode 100644
new mode 100755
diff --git a/pom.xml b/pom.xml
old mode 100644
new mode 100755
diff --git a/version.pl b/version.pl
old mode 100644
new 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 status
On branch SLF4J_1.5.3
nothing 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

答案 33 :(得分:5)

提醒一下,较新版本的git具有restore命令,这也是在更改文件后键入git status时的建议:

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

(使用“ git restore ...”放弃工作目录中的更改)

因此git'restore'是现代的解决方案。键入“ git status”后,从git中读取建议总是一个好主意:-)

答案 34 :(得分:1)

只需使用:

git stash -k -u

这将隐藏非分页更改未跟踪文件(新文件)并保留暂存文件。

它比reset / checkout / clean更好,因为您可能希望稍后(git stash pop)回复它们。将它们放在藏匿处比丢弃它们更好。

答案 35 :(得分:1)

git reset --hard->永久丢弃所有内容

git stash->放弃所有本地更改,但保存以供以后使用

答案 36 :(得分:0)

如果要恢复未暂存的文件,请使用 git restore --staged .