我如何从 git stash 中提取单个文件(或对文件的更改)?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1105253/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-10 06:42:21  来源:igfitidea点击:

How would I extract a single file (or changes to a file) from a git stash?

gitgit-stash

提问by Danny

I'd like to know if it is possible to extract a single file or diff of a file from a git stash without popping the stash changeset off.

我想知道是否可以在不弹出存储变更集的情况下从 git stash 中提取单个文件或文件的差异。

Might anyone be able to provide some suggestions/ideas about this?

有人可以就此提供一些建议/想法吗?

回答by Jakub Nar?bski

On the git stashmanpage you can read (in the "Discussion" section, just after "Options" description) that:

git stash联机帮助页上,您可以阅读(在“讨论”部分,就在“选项”描述之后):

A stash is represented as a commit whose tree records the state of the working directory, and its first parent is the commit at HEAD when the stash was created.

stash 表示为一个提交,其树记录了工作目录的状态,它的第一个父级是创建 stash 时在 HEAD 处的提交。

So you can treat stash (e.g. stash@{0}is first / topmost stash) as a merge commit, and use:

因此,您可以将 stash(例如stash@{0},第一个/最顶层的 stash)视为合并提交,并使用:

$ git diff stash@{0}^1 stash@{0} -- <filename>

Explanation: stash@{0}^1means the first parent of the given stash, which as stated in the explanation above is the commit at which changes were stashed away. We use this form of "git diff" (with two commits) because stash@{0}/ refs/stashis a merge commit, and we have to tell git which parent we want to diff against. More cryptic:

说明:stash@{0}^1表示给定 stash 的第一个父级,如上面的解释中所述,它是更改被隐藏的提交。我们使用这种形式的“git diff”(有两次提交),因为stash@{0}/refs/stash是一个合并提交,我们必须告诉 git 我们要针对哪个父级进行 diff。更神秘:

$ git diff stash@{0}^! -- <filename>

should also work (see git rev-parsemanpage for explanation of rev^!syntax, in "Specifying ranges" section).

也应该工作(参见git rev-parse联机帮助页以了解rev^!语法,在“指定范围”部分)。

Likewise, you can use git checkoutto check a single file out of the stash:

同样,您可以使用git checkout从存储中检查单个文件:

$ git checkout stash@{0} -- <filename>

or to save it under another filename:

或将其保存在另一个文件名下:

$ git show stash@{0}:<full filename>  >  <newfile>

or

或者

$ git show stash@{0}:./<relative filename> > <newfile>

(notethat here <full filename> is full pathname of a file relative to top directory of a project (think: relative to stash@{0})).

请注意,这里的 <full filename> 是相对于项目顶级目录的文件的完整路径名(想想:相对于stash@{0}))。



You might need to protect stash@{0}from shell expansion, i.e. use "stash@{0}"or 'stash@{0}'.

您可能需要防止stash@{0}外壳扩展,即使用"stash@{0}"'stash@{0}'

回答by Tim Henigan

If you use git stash applyrather than git stash pop, it will apply the stash to your working tree but still keep the stash.

如果您使用git stash apply而不是git stash pop,它会将存储应用到您的工作树,但仍保留存储。

With this done, you can add/committhe file that you want and then reset the remaining changes.

完成此操作后,您可以add/commit所需的文件,然后重置剩余的更改。

回答by Walf

There is an easy way to get changes from any branch, including stashes:

有一种简单的方法可以从任何分支获取更改,包括 stashes:

$ git checkout --patch stash@{0} path/to/file

You may omit the file spec if you want to patch in many parts. Or omit patch (but not the path) to get all changes to a single file. Replace 0with the stash number from git stash list, if you have more than one. Note that this is like diff, and offers to apply alldifferences between the branches. To get changes from only a single commit/stash, have a look at git cherry-pick --no-commit.

如果您想在多个部分打补丁,您可以省略文件规范。或者省略补丁(但不是路径)以获取对单个文件的所有更改。如果您有多个,请替换0为 中的 stash 编号git stash list。请注意,这类似于diff,并提供应用分支之间的所有差异。要仅从单个提交/存储中获取更改,请查看git cherry-pick --no-commit.

回答by Lubo? Turek

Short answer

简答

To see the whole file: git show stash@{0}:<filename>

要查看整个文件: git show stash@{0}:<filename>

To see the diff: git diff stash@{0}^1 stash@{0} -- <filename>

要查看差异: git diff stash@{0}^1 stash@{0} -- <filename>

回答by Ram

$ git checkout stash@{0} -- <filename>

Notes:

笔记:

  1. Make sure you put space after the "--"and the file name parameter

  2. Replace zero(0) with your specific stash number. To get stash list, use:

    git stash list
    
  1. 确保在“--”和文件名参数后面加上空格

  2. 将零(0) 替换为您的特定存储编号。要获取存储列表,请使用:

    git stash list
    

Based on Jakub Nar?bski's answer-- Shorter version

基于Jakub Nar?bski 的回答——更短的版本

回答by Nathan Kitchen

You can get the diff for a stash with "git show stash@{0}" (or whatever the number of the stash is; see "git stash list"). It's easy to extract the section of the diff for a single file.

您可以使用“ git show stash@{0}”获取存储的差异(或存储的任何数量;请参阅“git stash list”)。提取单个文件的差异部分很容易。

回答by Philluminati

The simplest concept to understand, although maybe not the best, is you have three files changed and you want to stash one file.

最容易理解的概念(虽然可能不是最好的)是您更改了三个文件,并且想要存储一个文件。

If you do git stashto stash them all, git stash applyto bring them back again and then git checkout f.con the file in question to effectively reset it.

如果你git stash把它们全部藏起来,git stash apply把它们带回来,然后git checkout f.c在有问题的文件上有效地重置它。

When you want to unstash that file run do a git reset --hardand then run git stash applyagain, taking advantage ofthe fact that git stash applydoesn't clear the diff from the stash stack.

当您想取消存储该文件时,请执行 agit reset --hard然后git stash apply再次运行,利用git stash apply不会从存储堆栈中清除差异的事实。

回答by Hola Soy Edu Feliz Navidad

If the stashed files need to merge with the current version so use the previous ways using diff. Otherwise you might use git popfor unstashing them, git add fileWantToKeepfor staging your file, and do a git stash save --keep-index, for stashing everything except what is on stage. Remember that the difference of this way with the previous ones is that it "pops" the file from stash. The previous answers keep it git checkout stash@{0} -- <filename>so it goes according to your needs.

如果隐藏的文件需要与当前版本合并,请使用以前的方法使用 diff。否则,您可能会使用git pop来取消隐藏它们,git add fileWantToKeep用于暂存您的文件,并执行git stash save --keep-index, 以隐藏除舞台上的内容之外的所有内容。请记住,这种方式与以前的方式的不同之处在于它从 stash 中“弹出”了文件。以前的答案保留它,git checkout stash@{0} -- <filename>因此它会根据您的需要进行。

回答by cambunctious

Use the following to apply the changes to a file in a stash to your working tree.

使用以下内容将更改应用于存储中的文件到您的工作树。

git diff stash^! -- <filename> | git apply

This is generally better than using git checkoutbecause you won't lose any changes you made to file since you created the stash.

这通常比使用更好,git checkout因为您不会丢失自创建存储以来对文件所做的任何更改。

回答by jciloa