据我所知,git stash
保存了一个
工作树和HEAD
之间的差异,它不保存索引
,工作树的状态,以及索引。您可以在创建存储后运行git log --graph stash@{0}
来查看此信息。
git stash pop
有一个选项--index
,有这个文件:
如果使用--index选项,则尝试不仅恢复工作树的更改,还尝试恢复索引的更改。但是,如果存在冲突(存储在索引中,因此您无法再像以前那样应用更改),则可能会失败。
我不明白这个文档。引用文献中的第二句让我感到困惑。
为什么合并冲突意外发生?例如:
$ git init test
$ cd test
$ echo initial > file
$ git add file
$ git commit -m initial
$ echo a >> file
$ git add file
$ echo b >> file
$ git stash save --keep-index
$ git stash pop --index
Auto-merging file
CONFLICT (content): Merge conflict in file
我不明白为什么在最后一步发生合并冲突。我想要发生的是git stash pop --index
识别索引已经处于正确状态,并更改工作树文件以匹配存储文件。
'git stash'确实保存了索引 - 即使使用--keep-index也会保留你的分阶段更改(但同时保存它们)。
如果不添加行'b',git stash pop应该将'a'添加到'a'(仍然存在因为-keep-index),但是足够智能以实现它是相同的修改,并且不做任何事情而且不会引发混乱。
当在舞台之后添加第'b'行时,git stash pop认为修改是不同的,并且直接尝试在'a'之上添加'a'+'b'(因为'a'仍在你的树上),一个混乱。 注意:如果'b'在代码中更远,那就没关系。
因此,为了避免在恢复存储时发生冲突,您可以先重置当前树(从而删除分阶段修改),然后弹出您的存储(这将使您回到初始状态,因为索引已保存)
git stash push --keep-index --include-untracked -m "cleaning_before_git_hook"
# here you can for example check your commit with git hooks, run tests, etc.
git reset --hard # to avoid any conflict when popping
git stash pop --index # without --index you will find back your initial code, but it will forget about the staged modifications you had