我将如何从一个git存储提取单个文件(或更改为一个文件)?

我想知道是否有可能提取一个单一的文件或从GIT存储文件的差异,而不popup储藏变更closures。

任何人都可以提供一些关于这方面的build议/想法?

在git的藏书页你可以阅读(在“讨论”部分,在“选项”说明之后):

一个存储被表示为一个提交,它的树logging了工作目录的状态,而它的第一个父项是在创build存储时在HEAD处的提交。

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

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

说明: stash@{0}^1快捷方式表示给定存储的第一个父项,如上面解释的那样是提交时所作的更改被隐藏。 我们使用这种forms的“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> 

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


您可能需要从shell扩展中保护stash@{0} ,即使用"stash@{0}"'stash@{0}'

如果你使用git stash apply而不是git stash pop ,它会把stash应用到你的工作树上,但是仍然保持藏起来。

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

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

简短的回答

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

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

要理解的最简单的概念,虽然可能不是最好的,但是你有三个文件改变了,你想存储一个文件。

如果你把git stash ,把它们全部git stash apply ,把git stash apply再把它们带回来,然后在有问题的文件上用git checkout fc来有效地重置它。

当你想取消这个文件的运行时,请执行git reset --hard然后再运行git stash apply ,利用git stash apply事实不会清除存储栈中的diff。

有一个简单的方法可以从任何分支进行更改,其中包括:

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

如果你想在许多部分打补丁,你可以省略文件规范。 或者省略修补程序(而不是path)以获取对单个文件的所有更改。 如果你有多个,用git stash list的存储号代替0 。 请注意,这就像diff ,并提供应用分支之间的所有差异。 为了只从一个提交/隐藏中获得更改,请查看git cherry-pick --no-commit

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

注意:1)确保在“ – ”和文件名参数2)后用你指定的存储号replace零(0)。 得到存储列表使用

  git stash list 

基于@JakubNarębski答案 – 较短的版本

如果隐藏的文件需要与当前版本合并,则使用以前使用diff的方法。 否则,你可能会使用git pop去除它们, git add fileWantToKeep来暂存你的文件,并且做一个git stash save --keep-index ,用于git stash save --keep-index除了舞台上的所有内容。 请记住,这种方式与以前的方式不同的是,它从存储“popup”文件。 以前的答案保持它的git checkout stash@{0} -- <filename>所以它根据您的需要。