gpt4 book ai didi

git - rebase 结果与 merge 结果有何不同?

转载 作者:太空狗 更新时间:2023-10-29 13:22:57 27 4
gpt4 key购买 nike

在 GitHub 的一篇文章中,我阅读了以下内容:

You aren't able to automatically rebase and merge on GitHub when: Rebasing the commits is considered "unsafe", such as when a rebase is possible without merge conflicts but would produce a different result than a merge would.

我不清楚 rebase 如何产生与 merge 不同的结果。

谁能解释一下这怎么可能?


原文链接: https://help.github.com/articles/about-pull-request-merges/

最佳答案

这是 rebase 和 merge 产生不同结果的情况的构造证明。我想这就是他们正在谈论的情况。 编辑:还有另一种情况可能发生,当 merge 分支时,要 rebase 的侧分支已经或 merge 包含一个在 rebase 期间将被跳过的提交(由于补丁 ID 匹配) ,然后是该提交的还原(不会被跳过)。参见 Changes to a file are not retained by merge, why?如果以后有时间,我也会尝试为该示例添加构造证明。

诀窍在于,由于 rebase 复制提交但忽略 merge ,我们需要删除一个 merge ,其解决方案不是其前任的简单组合。要使此 merge 没有冲突,我认为它必须是 "evil merge" ,所以这就是我放入脚本中的内容。

我们构建的图表如下所示:

  B   <-- master
/
A--C--E <-- branch
\ /
\ /
D <-- br2

如果你在 master 上(你的 tip commit 是 B)并且你是 git merge branch,这结合了 diffing 的变化 A-vs-B 与来自 d​​iffing A-vs-E 的那些。生成的是:

  B-----F   <-- master
/ /
A--C--E <-- branch
\ /
\ /
D <-- br2

提交F的内容由ABE决定。

如果你在 branch(你的提示提交是 E)并且你是 git rebase master,这会复制提交 CD,以某种顺序排列(不清楚是哪个)。它完全省略了提交 E。生成的是:

  B   <-- master
/ \
A C'-D' <-- branch
\
D <-- br2

(原始的 CE 只能通过 reflogs 和 ORIG_HEAD 获得)。以快进方式移动 mastermaster 的尖端变为提交 D'。提交 D' 的内容是通过将从 CD 中提取的更改添加到 B 来确定的。

由于我们使用了 "evil merge"E 中进行既不出现在 C 也不出现在 D 中的更改,这些更改将消失。

这是造成问题的脚本(注意,它创建了一个临时目录 tt,它留在当前目录中)。

#! /bin/sh

fatal() {
echo fatal: "$@" 1>&2; exit 1
}

[ -e tt ] && fatal tt already exists

mkdir tt && cd tt && git init -q || fatal failed to create tt repo

echo README > README && git add README && git commit -q -m A || fatal A
git branch branch || fatal unable to make branch
echo for master > bfile && git add bfile && git commit -q -m B || fatal B

git checkout -q -b br2 branch || fatal checkout -b br2 branch
echo file for C > cfile && git add cfile && git commit -q -m C || fatal C
git checkout -q branch || fatal checkout branch
echo file for D > dfile && git add dfile && git commit -q -m D || fatal D
git merge -q --no-commit br2 && git rm -q -f cfile && git commit -q -m E ||
fatal E
git branch -D br2
git checkout -q master || fatal checkout master

echo merging branch
git merge --no-edit branch || fatal merge failed
echo result is: *

echo removing merge, replacing with rebase of branch onto master
git reset -q --hard HEAD^ || fatal reset failed
git checkout -q branch || fatal switch back to master failed
git rebase master || fatal rebase failed
echo result is: *

echo removing rebase as well so you can poke around
git reset --hard ORIG_HEAD

关于git - rebase 结果与 merge 结果有何不同?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44546974/

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