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


当前回答

将文件添加到索引:

git add path/to/untracked-file
git stash

索引的全部内容,加上对现有文件的任何未标记的更改,都将被放入存储库。

其他回答

从git1.7.7开始,gitstash接受--include未跟踪选项(或短手-u)。要将未跟踪的文件包含在存储库中,请使用以下任一命令:

git stash --include-untracked
# or
git stash -u

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

我过去常常思考和渴望相同的特征。但随着时间的推移,我发现它确实不需要。当你藏起来时,留下新文件是可以的。它们不会发生任何“坏”情况(当您签出其他文件时,git将出错,不会覆盖现有的未跟踪文件)

而且,由于git stash和git stashpop之间的时间间隔通常很短,因此您将再次需要未跟踪的文件。所以我想说,当你在做其他事情时(在git stash和git stashpop之间),文件以git状态显示所带来的不便要比工作带来的不便小得多,而且需要注意的是,否则尝试将未跟踪的文件添加到你的stash中所需的费用。

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

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添加之前的状态相同(即,使用名为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的评论中所提到的,您可能希望在git-ls-files命令中添加--exclude standard(因此,git-ls-file-o--excludestandard)。]

…这也可以很容易地编写脚本——即使是别名也可以(以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而是应用,和/或希望能够指定特定的stash,而不是只使用顶部的一个。也许是这样(而不是上面的第二个别名)[去掉空格以适应无需滚动;重新添加以增加易读性]:

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

注意:在此表单中,如果要提供存储标识符,则需要提供操作参数和标识符,例如unsshall apply stash@{1}或unsshall pop stash@}

当然,你会把你的.zshrc或同等文件放进去,以使其长期存在。

希望这个答案对某人有帮助,将所有事情都放在一个答案中。

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

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

or

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

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

git add views.json

然后:

git stash

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

git checkout other-nice-branch