据我所知,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
识别索引已处于正确状态,并更改工作树文件以匹配隐藏文件。
答案 0 :(得分:2)
'git stash'确实可以保存索引-即使使用--keep-index也会保留分阶段的更改(但同时保存它们)。
如果不添加行“ b”,则git stash pop应该将“ a”添加到“ a”(由于--keep-index仍然存在),但是足够聪明地意识到它是相同的修改,并且什么也不做,也不会引发冲突。
在阶段之后添加行“ b”时,git stash pop认为修改是不同的,并直截了当地尝试在“ a”之上添加“ a” +“ b”(因为“ a”仍在树上) ),引发冲突。
注意:如果代码中的'b'更远,那就可以了。
因此,为了避免在还原存储库时发生冲突,您可以先重置当前树(从而删除分阶段的修改),然后弹出存储库(由于保存了索引,这将使您回到初始状态)< / p>
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