在进行git rebase时,我常常难以解决在解决冲突时“本地”和“远程”发生的事情。我有时会觉得他们将一方提交交换到另一方提交。
这可能(肯定)因为我还没有正确理解。
当变基,谁是'本地'而谁是'偏远'?
(我使用P4Merge解决冲突)
答案 0 :(得分:211)
git checkout A
git rebase B # rebase A on top of B
local
为B
(将改为),remote
是A
和
git checkout A
git merge B # merge B into A
local
为A
(将合并为),remote
是B
rebase切换ours
(在rebase启动之前的当前分支)和theirs
(您要在其上重新绑定的分支)。
kutschkem指出,GUI合并工具上下文中的 :
ours
”(上游分支)theirs
” - rebase之前的当前分支。请参阅本答案最后部分的插图。
混淆可能与inversion of ours
and theirs
during a rebase有关
(相关摘录)
请注意,rebase合并的工作原理是从
<upstream>
分支顶部的工作分支重放每个提交。
因此,当发生合并冲突时:
ours
”的那一方是迄今为止重新定位的系列,从<upstream>
开始,theirs
'是工作分支。
换句话说,双方交换。x--x--x--x--x(*) <- current branch B ('*'=HEAD)
\
\
\--y--y--y <- other branch to merge
,我们不会更改当前分支'B',所以我们所拥有的仍然是我们正在处理的(并且我们从另一个分支合并)
x--x--x--x--x---------o(*) MERGE, still on branch B
\ ^ /
\ ours /
\ /
--y--y--y--/
^
their
但在rebase 上,我们切换侧面,因为rebase的第一件事就是结帐上游分支! (重播当前提交的内容)
x--x--x--x--x(*) <- current branch B
\
\
\--y--y--y <- upstream branch
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将重播“我们的”B分支上的“他们的”提交:
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
注意:"upstream" notion是数据的引用数据集(一个全部存储库,或者像这里一样,一个分支,可以是本地分支),从中读取数据或者添加/创建了哪些新数据。
local
'和'remote
'与'mine
'和'theirs
'对我来说,问题仍然存在,那就是“本地”,谁是“偏远的”(因为在git中重新定位时不使用“我们的”和“他们的”这些术语,指的是它们似乎只是回答更令人困惑的)。
kutschkem补充说,这是正确的:
在解决冲突时,git会说:
local: modified file and remote: modified file.
我很确定这个问题的目的是定义本地和远程。那时,根据我的经验,在我看来:
ours
”(上游分支)theirs
” - rebase之前的当前分支。 git mergetool
确实提到'本地'和'偏远':
Merging:
f.txt
Normal merge conflict for 'f.txt':
{local}: modified file
{remote}: modified file
Hit return to start merge resolution tool (kdiff3):
例如,KDiff3会display the merge resolution like so:
相同
使用git mergetool -t gvimdiff将Vimdiff作为mergetool调用。最新版本的Git使用以下窗口布局调用Vimdiff:
+--------------------------------+
| LOCAL | BASE | REMOTE |
+--------------------------------+
| MERGED |
+--------------------------------+
- 的
LOCAL
强>:
包含当前分支上文件内容的临时文件。- 的
BASE
强>:
包含合并公共基础的临时文件。- 的
REMOTE
强>:
包含要合并的文件内容的临时文件。- 的
MERGED
强>:
包含冲突标记的文件。Git已尽可能多地执行自动冲突解决,此文件的状态是
LOCAL
和REMOTE
的组合,其中包含Git无法自行解决的任何问题的冲突标记。
mergetool
应将解析结果写入此文件。
答案 1 :(得分:40)
底线
git rebase
git merge
换句话说, LOCAL 始终是原作,而 REMOTE 总是那些之前没有提交过的人,因为他们正在在顶部合并或重新定位
证明它!
当然可以。不要相信我的话!这是一个简单的实验,您可以自己查看。
首先,确保正确配置了git mergetool。 (如果你没有,你可能无论如何都不会读这个问题。)然后找一个可以使用的目录。
设置存储库:
md LocalRemoteTest
cd LocalRemoteTest
创建初始提交(使用空文件):
git init
notepad file.txt (use the text editor of your choice)
(save the file as an empty file)
git add -A
git commit -m "Initial commit."
在不是主人的分支上创建提交:
git checkout -b notmaster
notepad file.txt
(add the text: notmaster)
(save and exit)
git commit -a -m "Add notmaster text."
在主分支上创建提交:
git checkout master
notepad file.txt
(add the text: master)
(save and exit)
git commit -a -m "Add master text."
gitk --all
此时您的存储库应如下所示:
现在进行rebase测试:
git checkout notmaster
git rebase master
(you'll get a conflict message)
git mergetool
LOCAL: master
REMOTE: notmaster
现在进行合并测试。关闭mergetool而不保存任何更改,然后取消rebase:
git rebase --abort
然后:
git checkout master
git merge notmaster
git mergetool
LOCAL: master
REMOTE: notmaster
git reset --hard (cancels the merge)
您的搜索结果应与最常显示的内容相同。
答案 2 :(得分:3)
答案 3 :(得分:0)
我也很困惑很长时间,常常会做出错误的决定,必须重新开始。
免责声明:我不是git专家,所以如果这里有什么问题,请纠正我!
我想我已经意识到我的困惑是因为我对重新基准的描绘与许多绘制它的方式不同。这是两个通常用来描述变基的图:
--1--2--3--4--5 \ 6--7--8
然后
--1--2--3--4--5--6--7--8
当然,这是绘制它的一种方法,但是我对rebase发生的事情的感觉是:
--1--2--3--4--5 \ 6--7--8
当然是完全一样的。但是从“我们/他们”的角度来看,情况有所不同。在第二种情况下,感觉“我们”仍在分支上(“ 6--7--8”),我们想从“主”那里接取更改。因此,在这个世界上,“我们的”仍然是“分支”。这就是让我感到困惑的地方。
但是在第一个“世界视图”(我想是Git的视图)中,我们移至主控(我们希望将作为基础的提交),然后从中选择每个提交依次分支并应用它们。因此,“我们的”最初是5
成为“主人”。成功应用6
之后,“我们的”是6
,但实际上是“在”母版上的6'
:
--1--2--3--4--5--6' \ 6--7--8
然后我们继续使用“ 7”。
因此,在合并中,您“在” 8
上,并将两者合并到一个新的提交中,但是在重新设置基准时,您移至5
并尝试将差异应用于分支作为新的提交在那里。
因此,变基最终结果的“真实”图景应该确实是:
--1--2--3--4--5--6'--7'--8' \ 6--7--8
在重新设置基准之后,您将进入8'
。您的分支机构也是如此(我想!)。可以(在我看来)可视化为:
--1--2--3--4--5 \ \ 6--7--8 6'--7'--8'