协慌网

登录 贡献 社区

如何从 git 存放区中提取单个文件(或更改文件)?

我想知道是否有可能从 git 存储中提取单个文件或文件的差异而不弹出存储变更集。

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

答案

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

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

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

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

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

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

应该也可以工作(请参阅git rev-parse联机帮助页以获取rev^!语法的解释,在 “指定范围” 部分)。

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

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

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

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

要么

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

请注意 ,这里 是相对于项目顶层目录的文件的完整路径名(请考虑:相对于stash@{0} ))。


您可能需要保护stash@{0}免受 shell 扩展的影响,即使用"stash@{0}"'stash@{0}'

如果您使用git stash apply而不是git stash pop ,它将把该 stash 应用于您的工作树,但仍保留该 stash。

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

有一个简单的方法可以从任何分支(包括存储)获取更改:

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

如果要在许多部分进行修补,则可以省略文件规范。或省略补丁(但不删除路径)以将所有更改更改为单个文件。如果您有多个,请用git stash list的存储号替换0 。请注意,这就像diff ,并提供了应用分支之间所有差异的功能。要仅通过一次提交 / 存储获取更改,请查看git cherry-pick --no-commit