如何丢弃工作副本中不在索引中的更改?
37 回答
另一种更快的方法是:
git stash save --keep-index --include-untracked
--include-untracked
如果您不想彻底了解它,则不需要包括在内。
之后,您可以根据需要使用git stash drop
命令删除该存储。
似乎完整的解决方案是:
git clean -df
git checkout -- .
git clean
删除所有未跟踪的文件(警告:虽然它不会删除 .gitignore 中直接提到的被忽略的文件,但它可能会删除位于文件夹中的被忽略的文件)并git checkout
清除所有未暂存的更改。
这将检查当前目录的当前索引,从当前目录向下丢弃文件中的所有更改。
git checkout .
或者这个从索引中检查所有文件,覆盖工作树文件。
git checkout-index -a -f
git clean -df
从当前目录开始,通过递归删除不受版本控制的文件来清理工作树。
-d
: 除未跟踪的文件外,删除未跟踪的目录
-f
:强制(根据设置可能不需要 clean.requireForce
)
运行git help clean
看说明书
2019 年更新
您现在可以通过以下方式丢弃一个跟踪文件中的未暂存更改:
git restore <file>
并在当前目录(递归)中的所有跟踪文件中:
git restore .
如果您从存储库的根目录运行后者,它将丢弃项目中所有跟踪文件中的未暂存更改。
笔记
git restore
于2019 年 7 月推出,并在 2.23 版中发布,作为git checkout
命令拆分git restore
为文件和git switch
分支的一部分。git checkout
仍然像以前一样运行,旧的答案仍然完全有效。- 当
git status
在工作树中运行未暂存的更改时,这是 Git 现在建议用来丢弃它们的方法(而不是git checkout -- <file>
以前 v2.23 之前的做法)。 - 与 一样
git checkout -- .
,这只会丢弃跟踪文件中的更改。所以Mariusz Nowak 的回答仍然适用,如果你想放弃所有未暂存的更改,包括未跟踪的文件,你可以按照他的建议运行一个额外的git clean -df
.
我最喜欢的是
git checkout -p
这使您可以有选择地还原块。
也可以看看:
git add -p
由于没有答案表明我使用的确切选项组合,这里是:
git clean -dxn . # dry-run to inspect the list of files-to-be-removed
git 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
(per directory) 和读取的标准忽略规则$GIT_DIR/info/exclude
,但仍然使用-e
选项给出的忽略规则。这允许删除所有未跟踪的文件,包括构建产品。这可以用于(可能与 结合使用git reset
)来创建原始工作目录以测试干净的构建。
-n
实际上不要删除任何东西,只是显示将要做什么。
-f
如果 Git 配置变量clean.requireForce
未设置为false
,Git clean 将拒绝删除文件或目录,除非给定-f
,-n
或-i
. Git 将拒绝删除.git
子目录或文件中的目录,除非-f
给出一秒钟。
如果您只想删除对现有文件的更改,请使用checkout
(在此处记录)。
git checkout -- .
- 没有指定分支,所以它检查出当前分支。
- 双连字符 (
--
) 告诉 Git 应该将后面的内容作为它的第二个参数(路径),即您跳过了分支的规范。 - 句点 (
.
) 表示所有路径。
如果您想删除自上次提交后添加的文件,请使用clean
(在此处记录):
git clean -i
- 该
-i
选项启动交互式clean
,以防止错误删除。 - 还有一些其他选项可用于更快地执行;请参阅文档。
如果您希望将更改移动到保留空间以供以后访问,请使用stash
(在此处记录):
git stash
- 所有更改都将移至 Git 的 Stash,以供以后访问。
- 有一些选项可用于更细微的存储;请参阅文档。
最简单的方法是使用以下命令:
此命令用于丢弃工作目录中的更改 -
git checkout -- .
https://git-scm.com/docs/git-checkout
在 git 命令中,未跟踪文件的存储是通过以下方式实现的:
git stash -u
我真的发现这篇文章有助于解释何时使用什么命令:http ://www.szakmeister.net/blog/2011/oct/12/reverting-changes-git/
有几种不同的情况:
如果您尚未暂存文件,则使用
git checkout
. 签出“更新工作树中的文件以匹配索引中的版本”。如果文件还没有被暂存(也就是添加到索引中)......这个命令基本上会将文件恢复到你上次提交的状态。git checkout -- foo.txt
如果您已暂存文件,请使用 git reset。重置更改索引以匹配提交。
git reset -- foo.txt
我怀疑使用git stash
是一种流行的选择,因为它的危险性要小一些。如果您在使用 git reset 时不小心吹走太多东西,您可以随时返回它。默认情况下,重置是递归的。
请查看上面的文章以获取更多建议。
如果您对保留未暂存的更改不感兴趣(特别是如果暂存的更改是新文件),我发现这很方便:
git diff | git apply --reverse
当您键入 git status 时, (使用“git checkout -- ...”放弃工作目录中的更改) 会显示。
例如git checkout -- .
git checkout -f
man git-checkout
:
-f, --force
切换分支时,即使索引或工作树与 HEAD 不同,也要继续。这用于丢弃本地更改。
从索引中检出路径时,不要在未合并的条目上失败;相反,未合并的条目将被忽略。
您可以使用 git stash - 如果出现问题,您仍然可以从 stash 中恢复。与此处的其他答案类似,但此答案也删除了所有未暂存的文件以及所有未暂存的删除:
git add .
git stash
如果您检查一切正常,请将藏匿处扔掉:
git stash drop
Bilal Maqsood 的回答git clean
也对我有用,但是有了藏匿处我有更多的控制权——如果我不小心做了某事,我仍然可以取回我的更改
更新
我认为还有1个变化(不知道为什么这对我有用):
git add . -A
代替git add .
没有-A
删除的文件将不会上演
我没有放弃更改,而是将遥控器重置为原点。注意 - 此方法是将您的文件夹完全恢复到存储库的文件夹。
所以我这样做是为了确保当我 git reset 时它们不会坐在那里(稍后 - 不包括 Origin/branchname 上的 gitignores)
注意:如果您想保留尚未跟踪的文件,但不在 GITIGNORE 中,您可能希望跳过此步骤,因为它将擦除在您的远程存储库中找不到的这些未跟踪文件(感谢@XtrmJosh)。
git add --all
然后我
git fetch --all
然后我重置为原点
git reset --hard origin/branchname
这将使它回到原点。就像重新克隆分支一样,同时将我所有的 gitignored 文件保存在本地和适当的位置。
更新了下面的每个用户评论:将 重置为用户所在的任何当前分支的变体。
git reset --hard @{u}
尝试了上述所有解决方案,但仍然无法摆脱新的未暂存文件。
用于git clean -f
删除那些新文件——不过要小心!注意强制选项。
要永久丢弃:
git reset --hard
要保存更改以备后用:
git stash
只需使用:
git stash -u
完毕。简单的。
如果您真的关心您的存储堆栈,那么您可以使用git stash drop
. 但那时你最好使用(来自 Mariusz Nowak):
git checkout -- .
git clean -df
尽管如此,我还是最喜欢它,因为它在一个命令git stash -u
中“丢弃”了所有已跟踪和未跟踪的更改。然而,只丢弃跟踪的更改,只丢弃未跟踪的更改......并且输入这两个命令是太多的工作:)git checkout -- .
git clean -df
简单地说
git stash
它将删除您的所有本地更改。你也可以通过说稍后使用
git stash apply
或 git stash pop
你有一个非常简单的 git 命令git checkout .
这甚至适用于以下目录;在正常的 git 权限之外。
sudo chmod -R 664 ./* && git checkout -- . && git clean -dfx
最近发生在我身上
cd path_to_project_folder # take you to your project folder/working directory
git checkout . # removes all unstaged changes in working directory
无论您的仓库处于何种状态,您都可以随时重置为任何先前的提交:
git reset --hard <commit hash>
这将丢弃该提交后所做的所有更改。
在我看来,
git clean -df
应该做的伎俩。根据git clean 上的 Git 文档
git-clean - 从工作树中删除未跟踪的文件
描述
从当前目录开始,通过递归删除不受版本控制的文件来清理工作树。
通常,只删除 Git 未知的文件,但如果指定了 -x 选项,也会删除忽略的文件。例如,这对于删除所有构建产品很有用。
如果给出任何可选的 ... 参数,则只有那些路径受到影响。
选项
-d 除了未跟踪的文件之外,还删除未跟踪的目录。如果未跟踪的目录由不同的 Git 存储库管理,则默认情况下不会将其删除。如果您真的想删除这样的目录,请使用两次 -f 选项。
-f --force 如果 Git 配置变量 clean.requireForce 没有设置为 false,除非给定 -f、-n 或 -i,否则 git clean 将拒绝运行。
摆脱比 git clean -df 更具体的新文件的另一种方法(它可以让您摆脱一些文件不一定全部),是首先将新文件添加到索引中,然后存储,然后删除藏。
当由于某种原因无法通过某种普通机制(如 rm)轻松删除所有未跟踪的文件时,此技术很有用。
如果您正在使用您定期与另一个存储库同步(例如拉取请求)的存储库的分支,那么接下来的内容实际上只是一个解决方案。简短回答:删除 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
敏锐的眼光会注意到这些文件有一个单独的字母以防万一。不知何故,我不知道是什么导致我走上这条道路(因为我自己没有从上游仓库处理这些文件),我已经切换了这些文件。尝试此页面(和其他页面)上列出的许多解决方案似乎没有帮助。
我能够通过删除我的分叉存储库和所有本地存储库并重新分叉来解决问题。仅此还不够;上游必须将相关文件重命名为新文件名。只要您没有任何未提交的工作、没有 wiki 以及与上游存储库不同的问题,您应该没问题。至少可以说,上游可能对您不太满意。至于我的问题,这无疑是一个用户错误,因为我对 git 不是很精通,但它远非容易修复的事实也表明 git 存在问题。
我有一个奇怪的情况,文件总是未暂存,这有助于我解决。
git rm .gitattributes
git add -A
git reset --hard
当您想将存储转移给其他人时:
# 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
[编辑] 如评论所述,可以命名 stash。好吧,如果您想分享您的藏匿处,请使用它;)
您可以创建自己的别名,以描述性方式描述如何执行此操作。
我使用下一个别名来丢弃更改。
丢弃工作树中文件(列表)中的更改
discard = checkout --
然后您可以将其用作 next 来丢弃所有更改:
discard .
或者只是一个文件:
discard filename
否则,如果您想丢弃所有更改以及未跟踪的文件,我会混合使用 checkout 和 clean:
清理并丢弃工作树中的更改和未跟踪的文件
cleanout = !git clean -df && git checkout -- .
所以使用很简单,如下所示:
cleanout
现在可以在下一个 Github 存储库中使用,其中包含很多别名:
如果您遇到子模块并且没有其他解决方案有效,请尝试:
要检查问题所在(可能是“脏”案例),请使用:
git diff
删除存储
git submodule update
如果几乎不可能排除对文件的修改,您是否考虑过忽略它们?如果这个说法是正确的,并且您在开发过程中不会接触这些文件,那么这个命令可能很有用:
git update-index --assume-unchanged file_to_ignore
如果实际提交了所有暂存文件,则可以简单地重置分支,例如从您的 GUI 中单击大约三下鼠标:Branch、Reset、Yes!
所以我在实践中经常做的恢复不需要的本地更改是提交所有好的东西,然后重置分支。
如果好东西是在一次提交中提交的,那么如果您最终希望以不同的方式提交它,则可以使用“修改最后一次提交”将其恢复为暂存或非暂存状态。
这可能不是您正在寻找的解决问题的技术解决方案,但我发现它是一个非常实用的解决方案。它允许您有选择地丢弃未暂存的更改,重置您不喜欢的更改并保留您所做的更改。
所以总而言之,我只是简单地提交、分支重置和修改最后一次提交。
如果您只是更改了文件的权限(这是在 DOS/Windoze 上) ,则任何解决方案都不起作用
星期一 23/11/2015-15:16:34.80 C:\...\work\checkout\slf4j+> git status 在分支 SLF4J_1.5.3 未为提交暂存的更改: (使用“git add ...”来更新将要提交的内容) (使用“git checkout -- ...”丢弃工作目录中的更改) 修改:.gitignore 修改:LICENSE.txt 修改:TODO.txt 修改:codeStyle.xml 修改:pom.xml 修改:version.pl 没有添加到提交的更改(使用“git add”和/或“git commit -a”) 星期一 23/11/2015-15:16:37.87 C:\...\work\checkout\slf4j+> git diff 差异 --git a/.gitignore b/.gitignore 旧模式 100644 新模式 100755 差异 --git a/LICENSE.txt b/LICENSE.txt 旧模式 100644 新模式 100755 差异 --git a/TODO.txt b/TODO.txt 旧模式 100644 新模式 100755 差异 --git a/codeStyle.xml b/codeStyle.xml 旧模式 100644 新模式 100755 差异 --git a/pom.xml b/pom.xml 旧模式 100644 新模式 100755 差异 --git a/version.pl b/version.pl 旧模式 100644 新模式 100755 星期一 23/11/2015-15:16:45.22 C:\...\work\checkout\slf4j+> git reset --hard HEAD HEAD 现在位于 8fa8488 12133-CHIXMISSINGMESSAGES MALCOLMBOEKHOFF 20141223124940 已添加 .gitignore 星期一 23/11/2015-15:16:47.42 C:\...\work\checkout\slf4j+> git clean -f 周一 23/11/2015-15:16:53.49 C:\...\work\checkout\slf4j+> git stash save -u 在 SLF4J_1.5.3 上保存的工作目录和索引状态 WIP:8fa8488 12133-CHIXMISSINGMESSAGES MALCOLMBOEKHOFF 20141223124940 添加了 .gitignore HEAD 现在位于 8fa8488 12133-CHIXMISSINGMESSAGES MALCOLMBOEKHOFF 20141223124940 已添加 .gitignore 星期一 23/11/2015-15:17:00.40 C:\...\work\checkout\slf4j+> git stash drop 删除 refs/stash@{0} (cb4966e9b1e9c9d8daa79ab94edc0c1442a294dd) 星期一 23/11/2015-15:17:06.75 C:\...\work\checkout\slf4j+> git stash drop 删除 refs/stash@{0} (e6c49c470f433ce344e305c5b778e810625d0529) 星期一 23/11/2015-15:17:08.90 C:\...\work\checkout\slf4j+> git stash drop 没有找到藏匿处。 星期一 23/11/2015-15:17:15.21 C:\...\work\checkout\slf4j+> git checkout -- 。 星期一 23/11/2015-15:22:00.68 C:\...\work\checkout\slf4j+> git checkout -f -- 。 星期一 23/11/2015-15:22:04.53 C:\...\work\checkout\slf4j+> git status 在分支 SLF4J_1.5.3 未为提交暂存的更改: (使用“git add ...”来更新将要提交的内容) (使用“git checkout -- ...”丢弃工作目录中的更改) 修改:.gitignore 修改:LICENSE.txt 修改:TODO.txt 修改:codeStyle.xml 修改:pom.xml 修改:version.pl 没有添加到提交的更改(使用“git add”和/或“git commit -a”) 星期一 23/11/2015-15:22:13.06 C:\...\work\checkout\slf4j+> git diff 差异 --git a/.gitignore b/.gitignore 旧模式 100644 新模式 100755 差异 --git a/LICENSE.txt b/LICENSE.txt 旧模式 100644 新模式 100755 差异 --git a/TODO.txt b/TODO.txt 旧模式 100644 新模式 100755 差异 --git a/codeStyle.xml b/codeStyle.xml 旧模式 100644 新模式 100755 差异 --git a/pom.xml b/pom.xml 旧模式 100644 新模式 100755 差异 --git a/version.pl b/version.pl 旧模式 100644 新模式 100755
解决此问题的唯一方法是手动重置更改文件的权限:
星期一 23/11/2015-15:25:43.79 C:\...\work\checkout\slf4j+> git status -s | egrep "^ M" | 切-c4- | for /f "usebackq tokens=* delims=" %A in (`more`) do chmod 644 %~A 星期一 23/11/2015-15:25:55.37 C:\...\work\checkout\slf4j+> git status 在分支 SLF4J_1.5.3 没有什么可提交的,工作目录干净 星期一 23/11/2015-15:25:59.28 C:\...\work\checkout\slf4j+> 星期一 23/11/2015-15:26:31.12 C:\...\work\checkout\slf4j+> git diff
提醒一下,较新版本的 git 具有 restore 命令,这也是在更改文件时键入 git status 时的建议:
(使用“git add ...”来更新将要提交的内容)
(使用“git restore ...”丢弃工作目录中的更改)
所以 git 'restore' 是解决这个问题的现代解决方案。在输入“git status”后阅读 git 的建议总是一个好主意:-)
如果要恢复未暂存的文件,请使用 git restore --staged 。
只需使用:
git stash -k -u
这将存储未暂存的更改和未跟踪的文件(新文件)并保留暂存文件。
它比reset
/ checkout
/好clean
,因为您可能希望它们稍后回来(按git stash pop
)。把它们藏起来总比丢弃它们好。