您如何存储未跟踪的文件?


1431

我对一个文件进行了更改,再加上一个新文件,并希望在我切换到另一项任务时使用git stash进行保存。但是git stash本身仅存储对现有文件的更改;新文件保留在我的工作树中,使以后的工作变得混乱。我如何隐藏这个未跟踪的文件?


27
请注意,如果您的存储中仅包含未跟踪的文件,则它看起来像是一个空文件,因为in中git stash show什么也没有返回,因此您可能会尝试删除它(就像我几个月前写的有用脚本一样) → 如何恢复掉下的藏书
Maxime R.

Answers:


1918

要存储您的工作目录,包括未跟踪的文件(尤其是.gitignore中的文件),则可能要使用此cmd:

git stash --include-untracked

更多细节:

2018年5月17日更新:

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

原始答案如下:

警告,如果您在gitignore文件中有任何目录/ *条目,这样做将永久删除您的文件。

从1.7.7版开始,您可以使用git stash --include-untrackedgit stash save -u存放未跟踪的文件,而无需暂存它们。

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


4
为什么即使尚未进行更改,存储仍仍存储更改的现有文件?
艾伦·克里斯滕森

6
@ alan-christensen阅读kernel.org/pub/software/scm/git/docs/git-stash.html的描述。关键是隐藏后要有干净的工作树。
开尔文

3
@Kelvin在我的评论中的意思是,除非已暂存,否则它不会存储新文件,但是即使尚未暂存,它也会存储现有文件。似乎与我不一致。
艾伦·克里斯滕森

11
@AlanChristensen的重点是隐藏可能因其他分支的签出而覆盖的内容。
jwg 2013年

3
正如你在这里有最多的回答,我会要求您列出git stash --include-untracked之前git stash --all在你的答案有两个原因。首先,它会在2019年更好地回答OP的问题,其次,因为-所有用户可能不希望执行的所有操作,因为它会删除所有.gitignored的文件
Daniel Flippance

411

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

git stash --include-untracked
git stash -u

警告,如果您在gitignore文件中有任何目录/ *条目,这样做将永久删除您的文件。


15
很酷-它终于可以按照手册页中的描述工作。不存储(和清理)新文件的行为已损坏。
史蒂夫·贝内特

1
我的git版本是1.9.1,即使我所拥有的.gitignore看起来像这样ignoredDirectoryignoredDirectory/*但仍会删除那些未跟踪的内容。甚至未跟踪的文件也不仅仅是目录。
theUnknown777'2015-4-13

22
您能解释一下警告吗?为什么会删除这些文件?它会删除它们而不隐藏它们吗?我已经使用Git一段时间了,还没有遇到这个问题。
Aleksandr Dubinsky

该警告也适用于*.extension条目吗?
arekolek

3
@ aleksandr-dubinsky,@ arekolek- git1.8.3 -u--include-untracked)选项可以隐藏和弹出未跟踪的文件,但git stash show不会列出
隐藏

77

将文件添加到索引:

git add path/to/untracked-file
git stash

索引的全部内容,再加上对现有文件的任何未暂存的更改,都将使其全部存储起来。


如果您不想隐藏索引中已经存在的更改怎么办?是否仍可以存储新文件?
allyourcode

提交索引,存储新文件,然后还原提交和/或从提交中检出文件。这是一个笨拙的解决方案,但它应该可以工作。
格达利亚

git add .出于某种原因未将其考虑在内
TheBilTheory

53

在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文件和未跟踪的文件可见,否则无法执行最终推送。.project和.classpath不会隐藏。

我用了

 git stash 

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

为了存放.classpath和.project文件,我使用了

git stash --include-untracked

并从我的工作区中删除了文件。这些文件的缺失使我无法在Eclipse中工作。我继续完成将提交的文件推送到远程的过程。一旦成功完成,我就使用

git stash pop

这会将相同的文件粘贴回我的工作区中。这使我有能力在Eclipse中处理同一项目。希望这可以消除误解。


2
为什么不对IDE文件使用全局gitignore?就是 使用~/.gitignore
Antti Pihlaja 2015年

20

正如在其他地方所说的,答案是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-standardgit 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}

当然,您将投入哪个.zshrc或同等价值才能长期存在。

希望这个答案对某人有帮助,将所有内容集中在一个答案中。


1
git ls-files -o显示的文件比我感兴趣的更多。从以下git状态,我发现添加了--exclude-standard作品。git ls-files -o --exclude-standard。我对此的看法是,它仅“包含”通常不会忽略的未跟踪文件,即,仅显示未过滤掉的.gitignore的未跟踪文件
mancocapac

20

在git版本2.8.1上:以下对我有用。

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

git stash save -u

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

git stash save -u <name_of_stash>

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

git stash pop

git stash apply stash@{0}

尽管没有将未跟踪的文件不再列为未跟踪文件,但这并未从我的计算机中删除这些文件。git stash show没有给他们看。当我尝试时git stash apply,出现“错误:无法从存储中还原未跟踪的文件”。但是,这些文件随后再次被列为未跟踪文件,但是未恢复对跟踪文件的更改。我认为可以通过从存储中将它们检出来单独还原这些文件,但是这种解决方案不是我所希望的。
hBrent

9

我能藏匿只是做未跟踪文件:

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}

最后一个弹出跟踪文件的存储,因此仅保留未跟踪文件。


git stash save -u不仅保存untracked文件,还保存trackeduntracked。我认为在这种情况下,您不必进行第一次保存。atlassian.com/git/tutorials/saving-changes/…中
Drenai

2
问题是如何仅存储未跟踪的文件。如果您跳过第一个存储区,那么会弹出什么?这个想法是:1)追踪藏匿处。2)藏匿未追踪。3)流行追踪。结果:未追踪的遗物被藏起来。
奥德

3

如果您想隐藏未跟踪的文件,但保留索引文件(例如,您将要提交的文件),只需将-k(保留索引)选项添加到-u

git stash -u -k


2

让我们假设新的未跟踪文件名为:“ views.json”。如果您想通过隐藏应用程序的状态来更改分支,通常输入:

git add views.json

然后:

git stash

它会藏起来。然后我可以用

git checkout other-nice-branch

1

有几个正确的答案在这里,但我想指出的是,新的整个目录,'git add path'工作。因此,如果您在untracked-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

并且如果untracked-path是您要存储的唯一路径,则存储“临时存储”将是一个空存储。正确的方法是添加整个路径,而不仅仅是目录名称(即,路径以“ /”结尾):

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

至少在我的系统上,您的假设是错误的。它没有斜杠就可以工作!空目录仍然被忽略。(macos git 2.6.2)
phobie 2015年

0

我认为可以通过告诉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

1
据我所知,前者也不起作用。请参阅我的答案以解决此问题。
lindes 2011年


0

在将Sourcetree与新创建的文件一起使用时,我遇到了类似的问题(它们也不会包含在存储中)。

当我首先选择“全部完成”,然后将新添加的组件存放在已跟踪的地方,因此包含在存放中。


这个问题是11岁,已经有14个答案。在发布之前,您阅读过它们吗?
Mickael B.

-7

我曾经思考并渴望拥有相同的功能。但是随着时间的流逝,我发现确实不需要它。存放时,可以保留新文件。它们不会发生任何“不良”情况(当您签出其他内容时,git将会出错并且不会覆盖现有的未跟踪文件)

而且由于通常介于git stash和之间的时间范围git stash pop很小,因此您将很快需要未跟踪的文件。因此,我要说的是,git status在您处理其他内容(在git stash和之间git stash pop)时,出现在文件中的不便要比由工作引起的不便小,需要引起注意,否则尝试将未跟踪的文件添加到文件中会产生成本你的藏匿处。


15
这取决于项目。假设未跟踪的文件是一个(半写的)单元测试,并且测试工具将运行目录中的所有单元测试。等等
史蒂夫·贝内特

1
另一个示例是,如果您在两台计算机上工作,并且被允许将数据从A移到B,而不是从B移到A。如果您创建了一段新的代码来解决最初在B上发生的问题,但您如果想同时在A和B上存储文件,则希望将其存储在B上,以便在A上重新创建该文件然后将其打包时,可以git diff存放的版本以验证您没有犯了一个错误。
格达利亚

7
仅仅因为一个分支中没有跟踪文件,并不意味着它不会与另一个分支中的跟踪文件冲突。
jwg

3
简单的反例:.conf.d目录中的配置文件,或仅存在于此文件中的任何其他文件都会修改软件的行为。
fotanus 2014年

当然需要功能。作为另一个示例,如果您有要存储的本地未跟踪文件,则无法从一个分支切换到另一个分支。
德米特里安2015年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.