仅存储单个文件

515

我希望能够仅存储单个文件的更改:

git stash save -- just_my_file.txt

然而上述方法并不奏效。有其他替代方案吗?


1
对于单个文件,而不是繁琐地使用存储命令,更简单的方法是复制单个文件,当您想要将其带回原处时,只需复制原始文件即可。例如:cp just_my_file.txt just_my_file.txt.manualstash,现在您可以执行所有检出操作等等,由于该副本是“未跟踪的文件”,因此您可以在分支和提交之间移动而不会遇到任何问题。当您在正确的分支/提交上想要“合并单个文件”时,只需执行mv just_my_file.txt.manualstash just_my_file.txt,现在您可以查看更改并在必要时提交它。 - Dimitry K
@DimitryK 在此期间不要执行 git clean -f -d 命令,因为它会删除未被跟踪的文件。 :-) - Danijel
5个回答

553

如果您不想为隐藏的更改指定消息,请在双破折号后传递文件名。

$ git stash -- filename.ext
如果这是一个未跟踪/新文件,你需要先将其加入暂存区(stage)。
但是,如果你确实想指定一条消息,请使用“push”。
git stash push -m "describe changes to filename.ext" filename.ext

这两种方法在git 2.13+版本中均可使用。


3
在进行修改时,这个答案对我来说似乎是最直接的方法:`git stash -- filename.ext`, `git commit --amend`, `git stash pop` - Brandon Dewey
1
适用于 2.24.3 (Apple Git-128) - Trevor
2
git stash push 不存在。 - Alexander Hartmaier
3
$ git stash -m "message" -- filename.ext 也可以使用(git v2.31.1)。 - Niklas
3
无法工作 2.7.1 - Anthony
显示剩余3条评论

263

我认为stash -p可能是你想要的选择,但以防将来遇到其他更棘手的问题,请记住:

Stash实际上只是稍微复杂一点的branch集合的一个非常简单的替代品。 Stash非常适用于快速移动东西,但是你可以通过分支完成更复杂的任务而不需要太多麻烦和工作。

# git checkout -b tmpbranch
# git add the_file
# git commit -m "stashing the_file"
# git checkout main

可以随意进行所需操作,然后稍后只需使用rebase和/或merge tmpbranch即可。 如果需要比stash允许的更加细致的跟踪,则这实际上并不需要太多额外的工作。


6
好的一面是,你可以将存储库转换为真正的分支而不会遇到太大的麻烦。 - Wes Hardaker
将此与从主分支检出tmpbranch the_file的git checkout tmpbranch the_file混合使用,使得将单个文件更改拉回主分支变得非常有用。请参见https://dev59.com/S3VC5IYBdhLWcg3wZwNT#307872。 - Matthew Davis
2
感谢您使用注释前缀。我希望更多的人在发布命令时也能这样做。 - pdoherty926
2
放置注释前缀有什么好处? - Sterling
3
更明确地说:它们不是注释,而是命令提示符(就像下面答案中的 $)。两者都经常使用,尽管有时 $ 暗示普通用户,而 # 暗示 root/admin。 - Wes Hardaker
显示剩余2条评论

68
你可以使用 git stash -p 交互式地保存单行代码(类似于 git add -p)。
它不需要文件名,但你可以使用 d 跳过其他文件,直到找到要保存的文件,然后使用 a 将所有更改都保存在那个文件中。

4
如果有很多你不想暂存的文件,这将花费很长时间。 - jjj
39
git 2.14.1 开始,你可以使用命令 git stash -p <文件名> 来指定特定的文件名进行存储。不清楚具体是何时发生了这个变化。 - muon
不工作 2.7.1 - Anthony
git stash -p(以及git add -p)会跳过新文件。 - B Seven
1
git stash -p <filename> 对我不起作用。相反,git stash -- <filename> 起了作用。 - alelom

28

最好的选项是将除此文件以外的所有内容进行暂存,并使用git stash save --keep-index命令来保留索引,从而暂存您的未暂存文件:

$ git add .
$ git reset thefiletostash
$ git stash save --keep-index

正如Dan指出的那样,thefiletostash是唯一会被存储的文件,但它也会将其他文件存储,所以它并不完全符合您的要求。


4
这样做虽然可以保持索引(index)的状态不变,但是这也会把在索引中的文件藏起来,换句话说,如果在执行完该操作后,你将索引提交到当前分支,然后切换到另一个分支并执行 git stash pop,那么它不仅会应用我们想要暂存的文件,还会应用所有的文件。 - Dan Moulding
@DanMoulding:你说得完全正确,我没有考虑到这一点。 - CharlesB

14

如果你在使用'git stash'时实际上是想要"放弃更改"(discard changes),而不是暂存它们,那么可以使用以下命令:

git stash save --keep-index
git checkout -- <file>

请注意,git stash只是分支和操作的快速简单替代方法。


如果您想要将所有修改过的更改还原到单个文件中,我认为这是最佳答案。 - Mohamed Haseel
我认为这是针对该特定任务的最佳答案。 - Zakir hussain
28
问题已经足够清晰,没有询问如何撤销一个文件的更改。被点踩了。 - Richard Smith
@MukulJain 我实际上需要以非常临时的方式使用stash-per-file(基本上将影响同一行的两个提交中的某些更改分开,针对一个文件)。我不会真的投反对票,只是声明它对我没用。 - Paul Stelian
4
放弃更改和存储更改是完全不同的概念。这并不是对问题的回答。 - B Seven
1
只是提醒那些认为问题已经足够清晰的多个git“专家”注意一下——8-10年前,当我还是一个git初学者并以自学的方式掌握git时,我只知道git stash命令可以快速丢弃更改。事实上,我谷歌搜索了这篇文章的确切标题,但不知道我在错误地搜索。看起来有多个人也遇到了类似的情况,并发现我的答案很有用。把我的答案看作是一个提示,就像“你是否想要X”。即使我现在更加了解git-stash,8年后,我仍然坚持在此页面上添加此提示的观点。 - Devesh

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接