'git stash apply' 交互模式
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/28195778/
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
'git stash apply' with Interactive Mode
提问by Kamafeather
I have a serie of files into a stash (stash{0}
) and I would like to git apply
justsome parts/hunks of these files (usually known as Interactive mode).
我有文件的意甲成藏(stash{0}
),我想git apply
只是一些零件/这些文件(通常被称为帅哥交互模式)。
Is it possible?
是否可以?
I've seen that is possible to perform a
我已经看到可以执行
git stash save -p 'Stash name'
but it seems not possible to do
但似乎不可能做到
git stash apply -p 'Stash name'
Do you know a way to achieve it?
你知道实现它的方法吗?
回答by LeoRochael
Is it possible?
是否可以?
Yes it is!
是的!
git checkout -p stash@{0}
Where you can replace the 0
in stash@{0}
with the index of the stash you want to apply.
您可以将0
in替换为stash@{0}
您要应用的存储的索引。
Use git stash list
and git show -p stash@{n}
if unsure which n
is the stash you want to apply.
使用git stash list
,git show -p stash@{n}
如果不确定哪个n
是您要应用的存储。
Don't forget to git stash drop stash@{n}
when you know don't need that stash anymore, since git checkout
obviously will not drop the stash for you.
不要忘记git stash drop stash@{n}
当你知道不再需要那个藏匿处时,因为git checkout
显然不会为你放弃藏匿处。
Why does it work?
为什么有效?
The key is to realize that stashes are, in essence, referencesto commitsjust like tags and branches.
关键是要意识到 stash 本质上是对提交的引用,就像标签和分支一样。
Indeed, they're stored in .git/refs/stash
, one line per stash hash.
事实上,它们存储在.git/refs/stash
, 每个存储哈希一行。
Caveats
注意事项
As @mgaddamentioned in the comments below, git checkout -p
tries to apply the whole difference between a commit and the current workspace.
正如@mgadda在下面的评论中提到的,git checkout -p
尝试应用提交和当前工作区之间的全部差异。
In the case of a git stash, if the stash you're trying to apply was done against a different commit, then git checkout -p stash@{n}
will try to apply interactively all the differences between the commit stash@{n}
and the commit of the current workspace, including all their parent commits that are different.
在 git stash 的情况下,如果您尝试应用的 stash 是针对不同的提交完成的,那么git checkout -p stash@{n}
将尝试以交互方式应用stash@{n}
当前工作区的提交和提交之间的所有差异,包括它们的所有父提交是不同的。
For example, if you're trying to apply a stash that was saved "many commits ago" into the current workspace, git checkout -p stash@{n}
will try to apply not only the changes in the stash proper, but will also try to revertall changes that happened between the commit on which the stash is based and the current commit.
例如,如果您尝试将在“多次提交前”保存的存储应用到当前工作区,git checkout -p stash@{n}
则不仅会尝试应用存储中的更改,还会尝试还原在两次提交之间发生的所有更改存储所基于的提交和当前提交。
Conversely, if you're trying to apply a stash "from the future", i.e. into a branch that is a number of commits from before the commit on which the stash is based, then git checkout -p stash@{n}
will try to also apply all the other changes that happened between the current commit and the commit from the future, besides the changes from the stash itself.
相反,如果您尝试应用“来自未来”的存储,即应用到一个分支,该分支是存储所基于的提交之前的多次提交,那么git checkout -p stash@{n}
将尝试也应用发生的所有其他更改在当前提交和未来提交之间,除了存储本身的更改。
(In case you're wondering, git checkout -p stash@{n}
a stash from a parallel branch will try to revert all changes between the current commit and the original branching point andalso apply all changes between the branching point and the other branch, besides the change in the stash).
(如果您想知道,git checkout -p stash@{n}
并行分支中的存储将尝试恢复当前提交和原始分支点之间的所有更改,并且除了存储中的更改之外,还会应用分支点和另一个分支之间的所有更改) .
Workarounds
解决方法
There are a few workarounds, none of them are perfect for every situation:
有一些解决方法,但没有一种方法适用于所有情况:
- Be really careful with the patches you accept when you do
git checkout -p stash@{n}
- Be really careful with the patches you accept when you do
- Do a
git stash pop
, thengit stash
again before doinggit checkout -p ...
. But if you wanted to do a partial apply of your stash to avoid conflicts, this won't really help. In that case, see solution 4 below.
- Do a
If you have a graphical diff tool supported by git (like meld), you can use
git difftool
and "apply left" only the changes you're interested in:git difftool -d stash@{n}
to compare a whole stash and all its filesgit difftool stash@{n} -- path/to/file
to compare a single file
- (Based on @andrew's answer)On a detached head, go back to the "parent" commit of the stash you're interested in, apply the stash, re-stash interactively only the parts you're interested in, go back and reapply the smaller stash.
- 在接受补丁时要非常小心
git checkout -p stash@{n}
- 在接受补丁时要非常小心
- 做一个
git stash pop
,然后git stash
再做git checkout -p ...
。但是,如果您想部分应用您的存储以避免冲突,这将无济于事。在这种情况下,请参阅下面的解决方案 4。
- 做一个
如果您有 git 支持的图形差异工具(如meld),您可以仅使用
git difftool
和“左应用”您感兴趣的更改:git difftool -d stash@{n}
比较整个存储及其所有文件git difftool stash@{n} -- path/to/file
比较单个文件
- (基于@andrew 的回答)在一个分离的头上,返回到您感兴趣的存储的“父”提交,应用存储,仅交互地重新存储您感兴趣的部分,返回并重新应用较小的藏匿处。
Step by step:
一步步:
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
回答by user829755
What I often do (in git bash) is
我经常做的(在 git bash 中)是
git stash show -p 'stash@{0}' >tmp.patch
Then I edit the file and remove the parts I don't want. Finally I say
然后我编辑文件并删除我不想要的部分。最后我说
<tmp.patch git apply
or
或者
<tmp.patch patch -p1
It doesn't work for binary files, though, but neither does the accepted answer (using checkout -p) for them.
但是,它不适用于二进制文件,但接受的答案(使用 checkout -p)也不适用于它们。
回答by Andrew
I don't think there's a way to apply changes by hunks (or even by file). You will have to apply the stash, then stash the changes you don't want interactively (with git stash save -p
). If you're worried about conflicts, you can stash any uncommitted changes first, apply your stash, stash any conflicting hunks and then apply the other stash.
我认为没有办法通过大块头(甚至通过文件)应用更改。您必须应用存储,然后以交互方式存储您不想要的更改(使用git stash save -p
)。如果您担心冲突,您可以先存储任何未提交的更改,应用您的存储,存储任何冲突的大块,然后应用其他存储。
回答by ruvim
One possible way is to reset the index and then use interactive add
一种可能的方法是重置索引,然后使用交互式添加
# 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"
Another way is to use interactive resetin place of interactive add.
另一种方法是使用交互式重置代替交互式添加。
# 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"