使用交互模式'git stash apply'

时间:2015-01-28 15:16:22

标签: git git-stash chunks interactive-mode

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

有可能吗?

我见过可以执行

git stash save -p 'Stash name'

但似乎无法做到

git stash apply -p 'Stash name'

你知道实现它的方法吗?

4 个答案:

答案 0 :(得分:42)

  

有可能吗?

是的!

git checkout -p stash@{0}

您可以将0中的stash@{0}替换为您要应用的藏匿处的索引。

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

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

为什么会这样?

关键是要认识到,就像标签和分支一样,stas实际上是referencescommits

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

注意事项

如下面的评论中提到的@mgaddagit checkout -p尝试应用提交和当前工作区之间的全部差异。

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

例如,如果您正在尝试应用已保存的存储空间,那么很多提交的存储空间会很快。在当前工作空间中,stash@{n}将尝试不仅应用存储库中的更改,而且还会尝试还原在存储所基于的提交之间发生的所有更改当前的提交。

相反,如果您尝试从未来"中应用存储",即从存储所基于的提交之前进行多次提交的分支,则{除了来自存储本身的更改之外,{1}}还将尝试应用当前提交和将来提交之间发生的所有其他更改。

(如果你想知道,git checkout -p stash@{n}来自并行分支的存储将尝试恢复当前提交与原始分支点之间的所有更改也适用于所有除了存储的变化之外,分支点和另一个分支之间的变化。)

的变通方法

有一些解决方法,其中没有一种适用于所有情况:

    1. 在执行git checkout -p stash@{n}
    2. 时,请务必小心接受的修补程序
    1. 在执行git checkout -p stash@{n}之前再次执行git checkout -p stash@{n},然后再git stash pop。但是如果你想部分应用你的存储以避免冲突,这真的没有帮助。在这种情况下,请参见下面的解决方案4.
    1. 如果您有git支持的图形差异工具(例如meld),则可以使用git stash和"应用左"只有您感兴趣的更改:

      • git checkout -p ...比较整个存储及其所有文件

      • git difftool来比较单个文件

    1. (Based on @andrew's answer)在一个独立的头上,回到父母"提交您感兴趣的存储,应用存储,仅以交互方式重新存储您感兴趣的部分,返回并重新应用较小的存储。

一步一步:

git difftool -d stash@{n}

答案 1 :(得分:2)

我认为没有办法通过帅哥(甚至是档案)来应用变更。您必须应用存储,然后以交互方式存储您不想要的更改(使用git stash save -p)。如果您担心冲突,可以先隐藏任何未提交的更改,应用您的存储,存储任何冲突的存储,然后应用其他存储。

答案 2 :(得分:2)

一种可能的方法是重置索引,然后使用交互式添加

# 0. ensure there are no uncommitted changes
git status

# 1. apply a changeset as is
git stash apply stash@{n}
# ... fix or discard conflicts if any

# 2. reset the index 
git reset

# 3. interactively add the required chunks (except new files)
git add -p

# 4. stash all other changes
git stash save --keep-index "comment"
# 4. or just discards all other changes in the working tree
git checkout-index -f -a

# 5. commit
git commit -m "comment"

另一种方法是使用交互式重置代替交互式添加。

# 0. ensure the working tree does not have unstaged changes
git status

# 1. apply a changeset as is
git stash apply stash@{n}
# ... fix or discard conflicts if any

# 2. interactively exclude the unneeded chunks from the index 
git reset -p

# 3. stash all other changes
git stash save --keep-index "comment"
# 3. or just discards all other changes in the working tree
git checkout-index -f -a

# 4. commit
git commit -m "comment"

答案 3 :(得分:1)

我经常(在git bash中)是

git stash show -p 'stash@{0}' >tmp.patch

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

<tmp.patch git apply

<tmp.patch patch -p1

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