题 你怎么藏匿一个未跟踪的文件?


我对文件进行了更改,加上一个新文件,并希望在切换到另一个任务时使用git stash将它们丢弃。但是git stash本身只会隐藏对现有文件的更改;新文件仍然存在于我的工作树中,使我未来的工作变得混乱。如何存放这个未跟踪的文件?


935
2018-05-07 15:54


起源


请注意,如果您的藏匿处中只有未跟踪的文件,则它看起来像是空的,如同 git stash show 什么都不返回,你可能会想放弃它(就像我刚刚做的那样,它包含了我几个月前写的有用的脚本→ 如何恢复被丢弃的藏匿处) - Maxime R.


答案:


2018年5月17日更新:

新版本的git现在有了 git stash --all 它存储所有文件,包括未跟踪和忽略的文件。
git stash --include-untracked 不再触及被忽略的文件(在git 2.16.2上测试)。

原答案如下:

警告,如果您的gitignore文件中有任何目录/ *条目,执行此操作将永久删除您的文件。

从版本1.7.7开始,您可以使用 git stash --include-untracked 要么 git stash save -u 保存未跟踪的文件而不进行分段。

添加(git add)文件并开始跟踪它。然后藏匿。由于文件的全部内容都是新的,因此它们将被隐藏,您可以根据需要对其进行操作。


1186
2018-05-07 16:02



为什么stash仍然存储已更改现有文件,即使这些更改尚未暂存? - Alan Christensen
@ alan-christensen阅读描述 kernel.org/pub/software/scm/git/docs/git-stash.html。重点是在存放后有一个干净的工作树。 - Kelvin
@ alan-christensen当你说“改变了现有的文件......还没有上演”时,我认为这意味着之前已经提交过的文件,然后进行了修改,但尚未添加到索引中。如果您的意思是未跟踪文件,那么也许您打算问“为什么不”而不是“为什么”。 - Kelvin
@Kelvin在我的评论中我的意思是它不会存储新文件,除非它们已被暂存,但它会存储现有文件,即使它们尚未被暂存。似乎与我不一致。 - Alan Christensen
@AlanChristensen关键是要隐藏可能被结帐的另一个分支覆盖的东西。 - jwg


从git 1.7.7开始, git stash 接受 --include-untracked 选项(或简写 -u)。要在存储中包含未跟踪的文件,请使用以下任一命令:

git stash --include-untracked
git stash -u

警告,如果您的gitignore文件中有任何目录/ *条目,执行此操作将永久删除您的文件。


351
2017-07-25 15:49



酷 - 它最终按照手册页中的描述工作。不存储(和清理)新文件是破坏的行为。 - Steve Bennett
我的git版本是1.9.1,即使我拥有它 .gitignore 看起来像这样 ignoredDirectory 并不是 ignoredDirectory/* 它仍然删除未跟踪的那些。即使是未跟踪的文件,也不仅仅是目录。 - theUnknown777
你能解释一下警告吗?为什么要删除这些文件?它会删除它们而不是存储它们吗?我已经使用Git一段时间了,并没有遇到这个问题。 - Aleksandr Dubinsky
警告是否适用于 *.extension 条目也是? - arekolek
@ aleksandr-dubinsky,@arekolek - git 1.8.3 -u (--include-untracked)选项可以存储和弹出未跟踪的文件,但是 git stash show 不会列出存储中未跟踪的文件 - xilef


将文件添加到索引:

git add path/to/untracked-file
git stash

索引的全部内容以及对现有文件的任何未分级更改都将进入存储。


55
2018-05-07 15:57



如果您不想存储已存在于索引中的更改,该怎么办?是否仍然可以存储新文件? - allyourcode
提交索引,存储新文件,然后恢复提交和/或检查提交中的文件。这是一个kludgy解决方案,但它应该工作。 - Gdalya


在git bash中,使用该命令可以实现对未跟踪文件的存储

git stash --include-untracked

要么

git stash -u

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

git stash从工作区中删除任何未跟踪或未提交的文件。您可以使用以下命令恢复git stash

git stash pop

这会将文件放回本地工作区。

我的经验

我不得不对我的gitIgnore文件执行修改,以避免将.classpath和.project文件移动到远程仓库中。 到目前为止,我不允许在远程仓库中移动此修改后的.gitIgnore。

.classpath和.project文件对于eclipse很重要 - 这是我的java编辑器。

我首先有选择地添加了我的其余文件并提交了暂存。但是,除非修改后的.gitIgnore fiels和未跟踪的文件,否则无法执行最终推送。 .project和.classpath没有被隐藏。

我用了

 git stash 

用于存储修改后的.gitIgnore文件。

对于存储.classpath和.project文件,我用过

git stash --include-untracked

它从我的工作区中删除了文件。缺少这些文件会剥夺我在eclipse中工作的能力。 我继续完成将提交的文件推送到远程的过程。 一旦成功完成,我就用了

git stash pop

这会将相同的文件粘贴回我的工作区。这让我有机会在eclipse中处理同一个项目。 希望这可以撇开误解。


44
2017-08-28 20:46



为什么不在IDE文件中使用全局gitignore? IE浏览器。使用 ~/.gitignore。 - Antti Pihlaja


正如其他地方所说,答案是 git add 文件。例如。:

git add path/to/untracked-file
git stash

但是,另一个答案也提出了这个问题:如果你真的不想添加文件怎么办?好吧,据我所知,你必须这样做。以下是  工作:

git add -N path/to/untracked/file     # note: -N is short for --intent-to-add
git stash

这将失败,如下:

path/to/untracked-file: not added yet
fatal: git-write-tree: error building trees
Cannot save the current index state

所以,你可以做什么?好吧,你必须真正添加文件, 然而,您可以在以后有效地取消添加 git rm --cached

git add path/to/untracked-file
git stash save "don't forget to un-add path/to/untracked-file" # stash w/reminder
# do some other work
git stash list
# shows:
# stash@{0}: On master: don't forget to un-add path/to/untracked-file
git stash pop   # or apply instead of pop, to keep the stash available
git rm --cached path/to/untracked-file

然后你可以继续工作,处于你之前的状态 git add (即使用未跟踪的文件调用 path/to/untracked-file;以及您可能必须跟踪文件的任何其他更改)。

工作流程的另一种可能性是:

git ls-files -o > files-to-untrack
git add `cat files-to-untrack` # note: files-to-untrack will be listed, itself!
git stash
# do some work
git stash pop
git rm --cached `cat files-to-untrack`
rm files-to-untrack

[注意:如@mancocapac的评论中所述,您可能希望添加 --exclude-standard 到了 git ls-files 命令(所以, git ls-files -o --exclude-standard)。]

...也可以轻松编写脚本 - 甚至别名也可以(用zsh语法表示;根据需要进行调整)[另外,我缩短了文件名,使其全部适合屏幕而不滚动此答案;随意替换您选择的备用文件名]:

alias stashall='git ls-files -o > .gftu; git add `cat .gftu`; git stash'
alias unstashall='git stash pop; git rm --cached `cat .gftu`; rm .gftu'

请注意,后者可能更好地作为shell脚本或函数,以允许提供参数 git stash,万一你不想要 pop 但 apply,和/或希望能够指定一个特定的藏匿,而不是仅仅采取最重要的藏匿。也许这(而不是上面的第二个别名)[空格被剥离以适应而不滚动;重新添加以增加易读性]:

function unstashall(){git stash "${@:-pop}";git rm --cached `cat .gftu`;rm .gftu}

注意:在这种形式中,如果要提供存储标识符,则需要提供操作参数和标识符,例如: unstashall apply stash@{1} 要么 unstashall pop stash@{1}


17
2018-02-06 02:00



git ls-files -o显示的文件比我感兴趣的文件多得多。来自以下内容 git状态 我发现添加--exclude-standard工作。 git ls-files -o --exclude-standard。我对此的看法是它只包含你通常不会忽略的未跟踪文件,即仅显示你的.gitignore不会过滤的未跟踪文件 - mancocapac
谢谢。我已经添加了一个注释。 - lindes


在git版本2.8.1:以下为我工作。

在没有名称的存储中保存已修改和未跟踪的文件

git stash save -u

使用名称保存已存储的已修改和未跟踪文件

git stash save -u <name_of_stash>

您可以使用pop和以后应用,如下所示。

git stash pop

git stash apply stash@{0}

8
2018-02-20 09:23





我能够藏匿 只是 执行未跟踪的文件:

git stash save "tracked files I'm working on"
git stash save -u "untracked files I'm trying to stash"
git stash pop stash@{1}

最后一个弹出被跟踪文件的藏匿处,因此只留下未跟踪的文件。


4
2018-05-06 22:33





这里有几个正确的答案,但我想指出,对于新的整个目录, 'git add path' 将  工作。所以,如果你有一堆新文件 未经跟踪路径 这样做:

git add untracked-path
git stash "temp stash"

这将隐藏以下消息:

Saved working directory and index state On master: temp stash
warning: unable to rmdir untracked-path: Directory not empty

而如果 未经跟踪路径 是你收藏的唯一途径,藏匿的“临时存储”将是一个空洞藏匿。正确的方法是添加整个路径,而不仅仅是目录名称(即以'/'结束路径):

git add untracked-path/
git stash "temp stash"

1
2017-08-19 23:59



至少在我的系统上你的假设是错误的。它没有斜线!无论如何都会忽略空目录。 (macos git 2.6.2) - phobie


我认为这可以通过告诉git文件是否存在来解决,而不是将其所有内容提交到临时区域,然后调用 git stash。 Araqnid 介绍 怎么做前者。

git add --intent-to-add path/to/untracked-file

要么

git update-index --add --cacheinfo 100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 path/to/untracked-file

但是,后者不起作用:

$ git stash
b.rb: not added yet
fatal: git-write-tree: error building trees
Cannot save the current index state

0
2017-10-11 10:10



据我所知,前者也不起作用。看到 我的答案 为了解决这个问题。 - lindes


您可以使用以下命令执行此操作

git stash save --include-untracked

要么

git stash save -u

有关git stash的更多信息 访问此帖子(点击这里)


0
2018-05-28 07:35





我曾经思考并渴望同样的功能。 但随着时间的推移,我注意到它真的不需要。 当您藏匿时,可以保留新文件。没有什么“坏”可以发生在他们身上(当你查看别的东西时,git会出错并且不会覆盖现有的未跟踪文件)

而且因为通常是时间框架之间的 git stash 和 git stash pop 相当小,你将再次快速地需要未跟踪的文件。 所以我想说文件出现的不便之处 git status 当你在做别的事情时(在...之间) git stash 和 git stash pop)小于工作造成的不便,并且需要注意,否则尝试将未跟踪的文件添加到您的存储中会花费成本。


-6
2018-02-18 09:12



这取决于项目。假设未跟踪文件是(半写)单元测试,测试工具运行目录中的所有单元测试。等等。 - Steve Bennett
另一个例子是如果您在两台计算机上工作,并且您被允许将数据从A移动到B,而不是从B移动到A.如果您创建一段新代码来解决首先发生在B上的问题但是您想要在A和B上,你希望能够将文件存储在B上,这样当你在A上重新创建该文件然后将其带到一个包中时,你可以git diff这个存储的版本来验证你没有犯了一个错误。 - Gdalya
仅仅因为没有在一个分支中跟踪文件,并不意味着它不会与另一个分支中的跟踪文件冲突。 - jwg
简单的反例:.conf.d目录中的配置文件,或只有在那里的任何其他文件修改软件的行为。 - fotanus
当然需要功能。作为一个附加示例,如果您有要隐藏的本地未跟踪文件,则无法从一个分支切换到另一个分支。 - Demitrian