关于git:你如何存储未跟踪的文件?

How do you stash an untracked file?

我有一个文件的更改,加上一个新的文件,我想在切换到另一个任务时使用git stash将它们保存起来。但是git本身只存储对现有文件的更改;新文件仍保留在我的工作树中,使我未来的工作变得混乱。如何保存这个未跟踪的文件?


更新日期:2018年5月17日:

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

原始答案如下:

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

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

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


截至Git 1.7.7,git stash接受--include-untracked期权(或短手-u期权)。要在存储中包含未跟踪的文件,请使用以下任一命令:

1
2
git stash --include-untracked
git stash -u

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


将文件添加到索引:

1
2
git add path/to/untracked-file
git stash

索引的全部内容,加上对现有文件的任何未经保存的更改,都将使其成为存储。


在git bash中,通过使用命令来存储未跟踪的文件

1
git stash --include-untracked

1
git stash -u

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

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

1
git stash pop

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

我的经验

我必须修改gitignore文件,以避免.classpath和.project文件移动到远程repo中。我不允许移动这个修改的.gitignore在远程回购目前。

CLSASTH和.Project文件对于Eclipse是重要的,这是我的Java编辑器。

首先,我有选择地添加了其余的文件,并承诺进行分段。但是,除非修改后的.gitignore域和未跟踪的文件viz,否则无法执行最终推送。.project和.classpath未被存储。

我用过

1
 git stash

用于存储修改过的.gitignore文件。

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

1
git stash --include-untracked

它从我的工作区中删除了文件。缺少这些文件会降低我在Eclipse中工作位置的能力。我继续完成将提交的文件推送到远程的过程。成功完成后,我使用

1
git stash pop

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


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

1
2
git add path/to/untracked-file
git stash

然而,另一个答案也提出了这个问题:如果您真的不想添加文件呢?好吧,据我所知,你必须这么做。以下内容不起作用:

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

这将失败,如下所示:

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

那么,你能做什么?好吧,您必须真正添加文件,但是,您可以在以后使用git rm --cached有效地取消添加:

1
2
3
4
5
6
7
8
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的未跟踪文件,以及您可能必须跟踪文件的任何其他更改)。

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

1
2
3
4
5
6
7
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

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

…这也可以很容易地编写脚本——甚至别名也可以(以zsh语法显示;根据需要进行调整)【另外,我缩短了文件名,使其完全适合屏幕,而不必在这个答案中滚动;请随意替换您选择的另一个文件名】:

1
2
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脚本或函数可能更好,以便在您不希望pop,而希望apply和/或希望能够指定一个特定的stash时,允许向git stash提供参数。可能是这样(而不是上面的第二个别名)【去掉空白以适应而不滚动;重新添加以增加易读性】:

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

注:在本表中,如果要提供存储标识符,如unstashall apply stash@{1}unstashall pop stash@{1},则需要提供操作参数和标识符。

当然,你会把它放在你的.zshrc里,或者与之相当的东西里,使之长期存在。

希望这个答案对某人有帮助,把所有的东西都放在一个答案里。


在Git版本2.8.1上:以下是我的作品。

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

1
git stash save -u

将修改过的和未跟踪过的文件以名称保存到存储库中

1
git stash save -u <name_of_stash>

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

1
2
3
git stash pop

git stash apply stash@{0}


我可以通过这样做来存储未跟踪的文件:

1
2
3
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}

最后一个会弹出被跟踪文件的存储,因此只留下未跟踪的文件。


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

1
git stash -u -k

让我们假设新的和未跟踪的文件称为:"views.json"。如果您想通过存储应用程序的状态来更改分支,我通常会键入:

git add views.json

然后:

git stash

它会被藏起来。那我就可以把树枝换成

git checkout other-nice-branch


你只需使用下面的命令就可以做到。

1
git stash save --include-untracked

1
git stash save -u

有关git stash的更多信息,请访问此文章(单击此处)


这里有几个正确的答案,但我想指出,对于新的整个目录,'git add path'将不起作用。因此,如果在未跟踪的路径中有大量新文件,请执行以下操作:

1
2
git add untracked-path
git stash"temp stash"

这将隐藏以下消息:

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

如果没有追踪的路径是你唯一藏匿的路径,"临时藏匿"将是一个空藏匿。正确的方法是添加整个路径,而不仅仅是目录名(即以"/"结束路径):

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


我认为这可以通过告诉Git文件存在来解决,而不是将文件的所有内容提交到临时区域,然后调用git stash。Araqnid描述了如何实现前者。

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

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

但是,后者不起作用:

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


我曾经思考和渴望同样的特征。但随着时间的推移,我发现它确实是不需要的。当你藏起来的时候,可以留下新的文件。它们不会发生任何"坏"情况(当您签出其他内容时,Git会出错,不会覆盖现有的未跟踪文件)

而且,由于通常git stashgit stash pop之间的时间范围相当小,因此您将需要再次快速获取未跟踪的文件。所以我想说,当你在做其他事情时(在git stashgit stash pop之间),出现在git status中的文件带来的不便比工作造成的不便要小,需要注意,否则,把未跟踪的文件添加到你的藏身处会花费很多。