【问题标题】:How do you stash an untracked file?您如何存储未跟踪的文件?
【发布时间】:2009-05-07 15:54:20
【问题描述】:

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

【问题讨论】:

  • 请注意,如果您的存储中只有未跟踪的文件,它看起来就像是一个空文件,因为git stash show 什么都不返回,您可能会想放弃它(就像我刚刚做的那样虽然它包含我几个月前写的一个有用的脚本→how to recover a dropped stash)

标签: git git-stash


【解决方案1】:

要隐藏您的工作目录,包括未跟踪的文件(尤其是 .gitignore 中的文件),那么您可能想要使用此 cmd:

git stash --include-untracked

或者,您可以使用简写 -u 代替 --include-untracked,或者简单地使用 git stash --all 来存储所有文件,包括 未跟踪忽略 文件。这种行为在 2018 年发生了变化,因此请确保您的 git 是最新的。


警告:似乎有(或曾经有过)被忽略目录的内容可能被永久删除的情况。 See this archived website for more information.

【讨论】:

  • 为什么 stash 仍然隐藏更改的现有文件,即使这些更改尚未暂存?
  • @alan-christensen 阅读kernel.org/pub/software/scm/git/docs/git-stash.html 的描述。关键是在存储后有一个干净的工作树。
  • @Kelvin 我在评论中的意思是,除非新文件已暂存,否则它不会存储新文件,但是即使它们尚未暂存,它也会存储现有文件。对我来说似乎不一致。
  • @AlanChristensen 的重点是存储可能被不同分支结帐覆盖的东西。
  • 由于您在此处获得最佳答案,因此出于两个原因,我会要求您在答案中将 git stash --include-untracked 列在 git stash --all 之前。首先,它现在在 2019 年更好地回答了 OP 的问题,其次是因为 --all 做了一些大多数用户可能不想要的事情,因为它删除了所有 .gitignored 的文件
【解决方案2】:

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

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

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

【讨论】:

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

将文件添加到索引中:

git add path/to/untracked-file
git stash

索引的全部内容,加上对现有文件的任何未暂存的更改,都会将其放入存储中。

【讨论】:

  • 如果您不想隐藏索引中已经存在的更改怎么办?还可以存储新文件吗?
  • 提交索引,存储新文件,然后恢复提交和/或从提交中签出文件。这是一个笨拙的解决方案,但它应该可以工作。
  • git add . 出于某种原因没有考虑到这一点
  • 更好的答案,因为--include-untracked 将拾取所有内容,尤其是隐藏目录;像node_modules.pytest_cache 以及您周围的任何东西,这些东西不在.gitignore 中。
  • 这对我不起作用,我必须--include-untracked
【解决方案4】:

在 git bash 中,隐藏未跟踪的文件是通过使用命令实现的

git stash --include-untracked
# or
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 中处理同一个项目。 希望这能消除误解。

【讨论】:

  • 为什么不使用全局 gitignore 来处理 IDE 文件? IE。使用~/.gitignore
  • 这很好用,我唯一遇到的问题是git stash show 只列出了修改过的文件,而不是未跟踪的文件......最初,我以为我失去了很多工作......
【解决方案5】:

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

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

git stash save -u

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

git stash save -u <name_of_stash>

您可以稍后使用 popapply,如下所示。

git stash pop

git stash apply stash@{0}

【讨论】:

  • 这并没有从我的计算机中删除未跟踪的文件,尽管它们不再被列为未跟踪。 git stash show 没有显示。当我尝试git stash apply 时,我得到“错误:无法从存储中恢复未跟踪的文件”。但是,这些文件随后再次被列为未跟踪,但未恢复对已跟踪文件的更改。我认为这些文件可以通过从存储中检出来单独恢复,但这个解决方案并不是我所希望的。
  • 你看到这个问题的标题了吗?它是“您如何存储未跟踪的文件?”。我不明白,你想在这里做什么。上面的答案对这个问题非常清楚。您需要使用 git stash show -p stash@{0} 以补丁形式查看最新的存储。
  • user1012513,我认为您的最后一条评论是写给我的。出于上述原因,我支持评论。当我尝试git stash apply 时出现错误。请注意,添加 stash@{0} 只会告诉 git 您正在尝试应用最新的存储,这在省略时是隐含的,因此没有必要。也许自 2018 年以来发生了一些变化,或者我的情况有所不同,但我认为人们应该了解我的经历,因为这对我来说是出乎意料的。这并不意味着您的解决方案对某些人没有用。
【解决方案6】:

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

您当然会在 .zshrc 或等效项中添加哪个以长期存在。

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

【讨论】:

  • git ls-files -o 显示的文件比我感兴趣的文件多得多。从以下git status 我发现添加了 --exclude-standard 作品。 git ls-files -o --exclude-standard。我对此的看法是它仅“包含”您通常不会忽略的未跟踪文件,即仅显示您的 .gitignore 不会过滤掉的未跟踪文件
【解决方案7】:

2020 年更新答案

我很惊讶这个页面上没有提到git stash push的其他答案。

This article 帮助我理解:

命令git stashgit stash push 的简写。在这种模式下,不允许使用非选项参数来防止拼写错误的子命令生成不需要的隐藏条目。此命令还有另一个别名 git stash save,已弃用,取而代之的是 git stash push

默认情况下,git 在进行 stash 时会忽略未跟踪的文件。如果需要将这些文件添加到存储中,您可以使用 -u 选项告诉 git 包含未跟踪的文件。如果指定了-a 选项,也可以添加忽略的文件。 -a 将包括未跟踪和忽略的文件。

我关心命名我的存储,我希望它们包含未跟踪的文件,所以我最常运行的命令是:git stash push -u -m "whatIWantToNameThisStash"

【讨论】:

【解决方案8】:

我能够通过以下方式存储只是未跟踪的文件:

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/…中有一个很好的图表
  • 问题是如何只存储未跟踪的文件。如果你跳过第一个存储,那么你会弹出什么?这个想法是:1)隐藏跟踪。 2) 藏匿未追踪。 3) 流行音乐跟踪。结果:未追踪的遗骸被隐藏起来。
【解决方案9】:

2.35 版中的新功能

git stash 的新 --staged 模式可以轻松地隐藏暂存区域中已有的内容,仅此而已。你可以把它想象成 git commit(它只写入分阶段的更改),但它不是创建一个新的提交,而是向存储写入一个新条目。然后,当您准备好时,您可以恢复您的更改(使用 git stash pop)并继续工作。

git add -A
git stash --staged

【讨论】:

    【解决方案10】:

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

    git stash -u -k
    

    【讨论】:

      【解决方案11】:

      你可以用下面的命令简单地做到这一点

      git stash save --include-untracked
      

      git stash save -u
      

      更多关于 git stash Visit this post (Click Here)

      【讨论】:

        【解决方案12】:

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

        git add views.json
        

        然后:

        git stash
        

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

        更改分支
        git checkout other-nice-branch
        

        【讨论】:

          【解决方案13】:

          在 VS 2019 及更高版本中提供存储功能。

          1. 转到 Git 更改窗口 Ctrl + Alt + F7
          2. 现在按Commit AllCommit staged 按钮附近的下拉键查看存储选项

          如果您想存储未跟踪的文件,例如 Git ignored filesFiles which are not included into project,请选择此选项

          阅读此答案以在 Visual Studio 中充分使用 Git stash: https://stackoverflow.com/a/69905607/4391394

          【讨论】:

            【解决方案14】:

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

            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
            

            【讨论】:

            • 据我所知,前者也不起作用。有关此问题的解决方案,请参阅 my answer
            【解决方案15】:

            这里有几个正确的答案,但我想指出,对于新的整个目录,'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)
            【解决方案16】:

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

            当我第一次选择“全部暂存”,然后将新添加的组件存储在跟踪位置并因此包含在存储中时。

            【讨论】:

              【解决方案17】:

              如何存储未跟踪的文件?

              git stash --include-untracked
              

              【讨论】:

                【解决方案18】:

                我曾经思考和渴望相同的功能。 但随着时间的推移,我注意到它确实不需要。 存储时,可以保留新文件。他们不会发生任何“坏事”(当您检查其他内容时,git 会出错并且不会覆盖现有的未跟踪文件)

                而且由于git stashgit stash pop 之间的时间范围通常很小,因此您将很快再次需要未跟踪的文件。 所以我想说,当您在处理其他事情时(在git stashgit stash pop 之间),文件显示在git status 中的不便比工作造成的不便和需要注意的不便要小,否则尝试将未跟踪的文件添加到您的存储中的成本。

                【讨论】:

                • 这取决于项目。假设未跟踪的文件是(半写的)单元测试,并且测试工具运行目录中的所有单元测试。等等。
                • 另一个例子是,如果您在两台计算机上工作,并且您可以将数据从 A 移动到 B,但不能从 B 移动到 A。如果您创建一段新代码来解决问题首先发生在 B 上,但您希望同时出现在 A 和 B 上,您希望能够将文件存储在 B 上,这样当您在 A 上重新创建该文件然后将其打包时,您可以 git diff 存储的版本以验证您没有犯错。
                • 一个文件没有在一个分支中被跟踪,并不意味着它不会与另一个分支中的跟踪文件冲突。
                • 简单的反例:.conf.d 目录中的配置文件,或任何其他只有在那里才能修改软件行为的文件。
                • 当然需要这个功能。再举一个例子,如果您有本地未跟踪的文件想要存储,则无法从一个分支切换到另一个分支。
                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 2011-05-21
                • 1970-01-01
                • 2016-03-29
                • 2021-10-10
                • 1970-01-01
                • 1970-01-01
                • 2020-03-21
                相关资源
                最近更新 更多