这可能(肯定)是因为我还没有完全理解这个范式。
在进行rebase时,谁是“本地”,谁是“远程”?
(我使用P4Merge来解决冲突。)
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
重新定义基础会切换 ours
(重新定义开始之前的当前分支)和 theirs
(您想要重新定义的顶部分支)。
kutschkem 指出,在 GUI 合并工具的上下文中:
ours
”(上游分支)theirs
” - 变基之前的当前分支。请参见本答案最后部分的插图。
混淆可能与在变基过程中ours
和theirs
的反转有关。
(相关摘录)
请注意,变基合并通过将工作分支中的每个提交记录重播到
<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
但是在变基操作中,我们会切换方向,因为变基的第一步是检出上游分支!(以重放当前提交并将其放在其之上)
x--x--x--x--x(*) <- current branch B
\
\
\--y--y--y <- upstream branch
git rebase upstream
会首先将B的HEAD
更改为上游分支的HEAD
(因此与之前的“当前”工作分支相比,'ours'和'theirs'的交换)。
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
然后重新定位将在新的“我们”的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
local
'和'remote
'与'mine
'和'theirs
'的区别对我来说,问题仍然存在,即“local”是谁,“remote”是谁(因为在git中重新定位时不使用“ours”和“theirs”这些术语,只是提到它们会使答案更加混乱)。
kutschkem补充道,而且说得很对:
解决冲突时,git会显示类似于:
local: modified file and remote: modified file.
Merging:
f.txt
Normal merge conflict for 'f.txt':
{local}: modified file
{remote}: modified file
Hit return to start merge resolution tool (kdiff3):
使用git mergetool -t gvimdiff将Vimdiff作为合并工具调用。Git的最新版本使用以下窗口布局调用Vimdiff:
+--------------------------------+
| LOCAL | BASE | REMOTE |
+--------------------------------+
| MERGED |
+--------------------------------+
LOCAL
:BASE
:REMOTE
:MERGED
:LOCAL
和REMOTE
的组合,并用冲突标记围绕着Git无法自行解决的部分。mergetool
应将解决结果写入此文件。git checkout A; git rebase B
命令时,本地分支为 B,远程分支为 A。这就是我需要知道的全部内容。 - Benubirdgit checkout A; git rebase B
时,本地是B,远程是A。如果我checkout A
,那么我当前正在查看文件在A
上的存在方式,这怎么可能是_remote_?(我不是说Benubird错了;我是说Git的用户体验很愚蠢) - Rafa最重要的是
git rebase
git merge
换句话说,LOCAL总是原始分支,而REMOTE总是那些提交之前不存在的人,因为它们正在被合并或在其之上进行rebase。
验证一下!
当然。不要相信我的话!这里有一个简单的实验,可以让你自己看到结果。
首先,确保你已经正确地配置了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
现在是合并测试。关闭您的合并工具而不保存任何更改,然后取消变基:
git rebase --abort
那么:
git checkout master
git merge notmaster
git mergetool
LOCAL: master
REMOTE: notmaster
git reset --hard (cancels the merge)
你的结果应该与顶部显示的相同。
git rebase origin/master
(假设这里是“master”)。如果在origin/master
中有任何新提交,那么rebase就不会有任何快进,因为每个本地提交都会在origin/master
之上重放(新父级)。如果没有新提交...那么rebase就是一个无操作(它什么也不做,甚至不是快进)。 - VonC