使用交互模式'git stash apply'

Kam*_*her 29 git git-stash chunks interactive-mode

我有一系列文件到stash(stash{0}),我想git apply 只是这些文件的一些部分/帅气(通常称为交互模式).

可能吗?

我已经看到有可能执行一个

git stash save -p 'Stash name'
Run Code Online (Sandbox Code Playgroud)

但似乎不可能做到

git stash apply -p 'Stash name'
Run Code Online (Sandbox Code Playgroud)

你知道实现它的方法吗?

Leo*_*ael 47

可能吗?

是的!

git checkout -p stash@{0}
Run Code Online (Sandbox Code Playgroud)

您可以将0in 替换为stash@{0}要应用的存储的索引.

使用git stash list并且git show -p stash@{n}如果不确定哪个n是您要申请的藏匿处.

不要忘记git stash drop stash@{n}当你知道不再需要那个藏匿处时,因为git checkout显然不会为你丢下藏匿物.

它为什么有效?

关键是要意识到,stas实际上就像标签和分支一样引用提交.

实际上,它们存储在.git/refs/stash每个存储哈希的一行中.

注意事项

正如下面的评论中提到的@mgadda,git checkout -p尝试应用提交和当前工作空间之间的整个差异.

在git stash的情况下,如果您尝试应用的存储是针对不同的提交完成的,那么git checkout -p stash@{n}将尝试以交互方式应用提交stash@{n}和当前工作空间的提交之间的所有差异,包括其所有父提交是不同的.

例如,如果您尝试将"多次提交之前"保存的存储应用到当前工作空间中,git checkout -p stash@{n}则不仅会尝试应用存储库中的更改,还会尝试还原之间发生的所有更改.存储基于的提交和当前提交.

相反,如果您尝试应用"从未来"存储,即进入一个分支,该分支是从存储所基于的提交之前的许多提交,那么git checkout -p stash@{n}将尝试应用所发生的所有其他更改在当前提交和未来提交之间,除了存储本身的更改之外.

(如果您想知道,git checkout -p stash@{n}来自并行分支的存储将尝试还原当前提交和原始分支点之间的所有更改,并且还应用分支点和其他分支之间的所有更改,除了存储的更改) .

解决方法

有一些解决方法,它们都不适用于所有情况:

    1. 当你这么做时,要非常小心你接受的补丁 git checkout -p stash@{n}
    1. 做一个git stash pop,然后git stash做前再次git checkout -p ....但是如果你想部分应用你的藏匿来避免冲突,这将无济于事.在这种情况下,见下面的解决方案4.
    1. 如果你有一个git支持的图形差异工具(比如meld),你只能使用git difftool和"向左应用"你感兴趣的变化:

      • git difftool -d stash@{n} 比较整个存储及其所有文件

      • git difftool stash@{n} -- path/to/file 比较单个文件

    1. (根据@ andrew的回答)在一个独立的头上,回到你感兴趣的藏匿的"父"提交,应用藏匿,只交互地重新存储你感兴趣的部分,返回并重新申请较小的藏匿处.

一步步:

git checkout stash@{n}^  # notice the "^". 

# Now you're in a detached head in the parent commit of the stash.
# It can be applied cleanly:
git stash apply stash@{n}

# Now save only the diffs you're interested in:
git stash -p

# remove the rest of the old stash
git checkout -- .  # be careful or you could remove unrelated changes

# go back to the branch where you want to apply the smaller stash
git checkout <my previous branch>

# apply the smaller stash
git stash pop
Run Code Online (Sandbox Code Playgroud)

  • 这里有一个需要提及的警告:因为存储只是提交,这意味着它们还有父提交,这些父提交不能保证与您想要交互式应用更改的父提交相同。经验法则:如果您从当前签出的提交之外的其他提交中隐藏,则此技术将不会达到您的预期。解决方法:应用存储中的整套更改(使用 git stash pop),然后再次存储(git stash)。现在您可以根据需要 git checkout -p 。 (2认同)

use*_*755 7

我经常做的(在 git bash 中)是

git stash show -p 'stash@{0}' >tmp.patch
Run Code Online (Sandbox Code Playgroud)

然后我编辑文件并删除我不想要的部分。最后我说

<tmp.patch git apply
Run Code Online (Sandbox Code Playgroud)

或者

<tmp.patch patch -p1
Run Code Online (Sandbox Code Playgroud)

但是,它不适用于二进制文件,但接受的答案(使用 checkout -p)也不适用于它们。