x--x--x--x--x(*) <- current branch B
\
\
\--y--y--y <- upstream branch
A**git rebase upstream**将首先将B的HEAD更改为上游分支HEAD(因此与先前的“当前”工作分支相比,“我们的”和“他们的”的交换机)。
x--x--x--x--x <- former "current" branch, new "theirs"
\
\
\--y--y--y(*) <- upstream branch with B reset on it,
new "ours", to replay x's on it
,然后rebase将在新的'our' B分支上重放'their' commit:
x--x..x..x..x <- old "theirs" commits, now "ghosts", available through reflogs
\
\
\--y--y--y--x'--x'--x'(*) <- branch B with HEAD updated ("ours")
^
|
upstream branch
4条答案
按热度按时间gr8qqesn1#
TL;DR;
总结(作为Benubird注解),当:
local
是B
(rebaseonto),remote
是A
以及:
local
是A
(合并到),remote
是B
一个rebase切换
ours
(rebase开始前的当前分支)和theirs
(要在其上进行rebase的分支)。kutschkem指出,在GUI mergetool上下文中:
*本地引用部分重基的提交:“
ours
”(上游分支)*remote是指传入的更改:“
theirs
“-变基之前的当前分支。见本答案最后一部分的插图。
rebase时的反转
这种混淆可能与在变基过程中
ours
和theirs
的反转有关。(相关摘录)
git rebase
man page:请注意,一个rebase merge的工作原理是在
<upstream>
分支的顶部重放每个来自工作分支的提交。因此,当合并冲突发生时:
ours
”的一侧是迄今为止的重定基系列,从<upstream>
开始,theirs
'是工作分支。换句话说,两侧是交换的。反转图解
合并时
,我们不改变当前分支'B',所以我们拥有的仍然是我们正在做的(我们从另一个分支合并)
在变基时:
但是在一个rebase上,我们切换到另一边,因为rebase做的第一件事就是 checkout 上游分支!(在其上重放当前提交)
A**
git rebase upstream
**将首先将B的HEAD
更改为上游分支HEAD
(因此与先前的“当前”工作分支相比,“我们的”和“他们的”的交换机)。,然后rebase将在新的'our' B分支上重放'their' commit:
注意:“上游”概念是数据的引用集(所有存储库,或者像这里一样,分支,可以是 * 本地 * 分支),从中读取数据或添加/创建新数据。
“
local
”和“remote
”与'mine
'和'theirs
'Pandawood在评论中添加:
对我来说,问题仍然存在,谁是“本地”,谁是“远程”(因为在git中进行重新定基时不会使用术语“我们的”和“他们的”,提到它们似乎会使答案更加混乱)。
GUI git mergetool
kutschkem补充说,这是正确的:
在解决冲突时,git会说:
我很肯定这个问题的目的是在这一点上的本地和远程的定义。在这一点上,根据我的经验,我认为:
*本地引用部分重基的提交:“
ours
”(上游分支)*remote是指传入的更改:“
theirs
“-变基之前的当前分支。git mergetool
确实提到了'local'和'remote':例如,KDiff3将display the merge resolution like so:
而meld则为display it too:
VimDiff、which displays也是如此:
使用git mergetool -t gvimdiff调用Vimdiff作为mergetool。最新版本的Git使用以下窗口布局调用Vimdiff:
*
LOCAL
:包含当前分支上文件内容的临时文件。
*
BASE
:一个临时文件,包含用于合并的公共基。
*
REMOTE
:包含要合并的文件内容的临时文件。
*
MERGED
:包含冲突标记的文件。
Git已经尽可能多地执行了自动冲突解决,并且该文件的状态是
LOCAL
和REMOTE
的组合,并且在Git无法自行解决的任何内容周围都有冲突标记。mergetool
应将解析结果写入此文件。sqserrrh2#
底线
git rebase
git merge
换句话说,LOCAL总是原始的,而REMOTE总是那些提交之前不存在的家伙,因为它们正在被合并或重新基于顶部
证明给我看
当然可以。不要相信我的话!这里有一个简单的实验,你可以自己看看。
首先,确保正确配置了git mergetool。(如果你没有,你可能不会阅读这个问题无论如何。)然后找到一个目录工作。
设置存储库:
创建初始提交(使用空文件):
在不是master的分支上创建提交:
在master分支上创建一个提交:
此时,您的存储库应该如下所示:
下面是rebase测试:
现在是合并测试。关闭mergetool而不保存任何更改,然后取消变基:
然后又道:
你的结果应该和上面显示的一样。
pgccezyw3#
我也是,困惑了很长一段时间,经常做出错误的决定,不得不重新开始。
免责声明:我不是gitMaven,所以如果这里有任何错误,请纠正我!
我想我已经意识到,我的困惑是因为我描绘了一个变基不同于许多画它。下面是两个通常用于描述变基的图形:
然后
当然,这是绘制它的一种方法,但我对rebase发生的事情的感觉是这样的:
这当然是完全相同的。但从“我们/他们”的Angular 来看,情况就不同了。在第二种情况下,感觉好像“我们”仍然“在”分支(“6--7--8”)上,我们想从“主”那里获得更改。所以在这个世界上“我们的”仍然是“分支”。这就是让我困惑的地方。
但是在第一个“世界视图”中,我认为这是Git的视图,我们移动到master(我们想要将 * 转换到 * 的提交),从那里我们依次选择分支上的每个提交并应用它们。所以“我们的”变成了“主”,最初是
5
。在6
成功应用后,“我们的”是6
,但实际上是“在”主机上的6'
:然后我们继续用“7”来做同样的事情。
所以在merge中,你“在”
8
上,并将两者组合成一个新的提交,但在rebase中,你移动到5
,并尝试将提交中的差异应用于分支上的新提交。因此,变基的最终结果的“真实”画面应该是:
在重定基之后,你就在
8'
上了。你的分支也是如此(我想!)。(在我的脑海中)这可以想象为:f45qwnt84#
我没有完全理解你的问题,但我认为下面的图表解决了你的问题。(Rebase:Remote Repository -> Workspace)
来源:My Git Workflow