gpt4 book ai didi

git - 应用 stash 是否涉及三路 merge ,或者只是将 stash 修补到当前工作树?

转载 作者:太空狗 更新时间:2023-10-29 14:35:18 28 4
gpt4 key购买 nike

git stash 的联机帮助页说

pop [--index] [-q|--quiet] [<stash>]

Remove a single stashed state from the stash list and apply it on top of the current working tree state, i.e., do the inverse operation of git stash push . The working directory must match the index.

Applying the state can fail with conflicts; in this case, it is not removed from the stash list. You need to resolve the conflicts by hand and call git stash drop manually afterwards.



“应用状态”是否涉及三路 merge ,或者只是将存储修补到当前工作树?

这是一种什么样的“冲突”?我只知道三路 merge 的冲突。

谢谢。

最佳答案

“应用状态”确实是三路归并。

您在问题 How is a stash entry a child commit of HEAD commit and index's commit? 中注意到(来自文档)那:

The ancestry graph looks like this:

       .----W
/ /
-----H----I

where H is the HEAD commit, I is a commit that records the state of the index, and W is a commit that records the state of the working tree.



我要断了 git stash pop分为两个组成部分,即 git stash apply其次是 git stash drop .如果应用步骤成功, pop执行 drop步骤。如果不是 - 例如,如果它因冲突而停止 - pop跳过 drop . git stash当前代码为 literally a shell script — 我会说“只是”一个 shell 脚本,但它是一个相当大且复杂的脚本,超过 700 行 — 和 the pop code字面意思是这样读的:
pop_stash() {
assert_stash_ref "$@"

if apply_stash "$@"
then
drop_stash "$@"
else
status=$?
say "$(gettext "The stash entry is kept in case you need it again.")"
exit $status
fi
}

正如你所看到的,它说适用,如果有效,请放弃;如果它不起作用,请打印一条信息行并使用与 apply 将退出的相同状态代码退出。

应用索引 ( I ) 提交

因为每个 stash 至少有两次提交—— I索引状态和 W工作树状态——应用步骤可以同时应用它们,也可以不应用它们。在您运行时 git stash applygit stash pop ,您可以选择是同时应用两者,还是仅应用 W状态。如果您选择同时应用, I state 应用于以下内容:
git diff <hash-of-H> <hash-of-I> | git apply --cached

(尽管 actual line of code 略有不同,以允许索引中的二进制文件,并且前后都有一些相当棘手的魔法来处理各种角落和困难情况)。

因为这只是 diff | patch这不是真正的三向 merge 。有关这意味着什么的详细信息,请参阅 What is the difference between git cherry-pick and git format-patch | git am? ( Mark Adelsberger's accepted answermy own )。在任何情况下,补丁都可能失败。如果失败,您可以选择使用 git stash branch而不是 git stash apply --index ,这是保证工作。

应用工作树 ( W ) 提交

无论如何,假设您选择忽略 I提交,或者已经成功应用它并且 Git 已经将结果保存在应用过程的后面,Git 现在转移到你正在询问的三向 merge 。

这部分相当棘手。不过,它的核心是 this line :
if git merge-recursive $b_tree -- $c_tree $w_tree

它运行三路 merge , merge 基础是提交 H , --ours commit 是您开始 merge 时索引中的任何内容,以及 --theirs commit 是 W 的内容犯罪。

注:git merge-recursive尝试在您开始 merge 时容纳工作树中的任何内容,即使它与充当 ours 的索引内容不匹配树。这并不总是成功的,这就是为什么 git stash pop 通常是个坏主意的原因。进入一个肮脏的工作树。

如果有 merge 冲突,这三棵树— $b_tree来自 H提交, $c_tree来自 a tree that git stash made from your index before running git merge-recursive , 和 $w_tree来自提交 W — 是进入 merge 冲突暂存槽中索引的文件的三个来源,如我在 my answer 中所述至 Git Stash Pop - Resolve Conflicts with mergetool .

请注意,如果您确实使用了 git mergetool要 merge 它们,这通常会丢弃您在开始 merge 时在工作树中所做的任何未暂存的更改。这也是启动 git stash pop 通常不明智的原因。用脏的工作树。 如果您的工作树与您开始时的索引匹配 git stash pop ,如果发生 merge 冲突,您将处于更好的状态。

关于git - 应用 stash 是否涉及三路 merge ,或者只是将 stash 修补到当前工作树?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54319661/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com