git rebase,跟踪“本地”和“远程”


174

在进行git rebase时,解决冲突时,我经常很难弄清“ local”和“ remote”的情况。有时我给人的印象是,他们从一次提交交换到下一次提交。

这可能(肯定)是因为我仍然没有正确理解。

重新定基时,谁是“本地”,谁是“远程”?

(我使用P4Merge解决冲突)


阅读本文是否有可能对您有所帮助?本教程的其余部分是以及乐于助人....
伊万

另一个优秀的git 资源
未知2010年

stackoverflow.com/questions/2959443/...帮助吗?(不用于' git svn'部分,仅用于' git rebase'部分)
VonC

@VonC,是的,就是这样。如果您想在此处复制答案的相关部分,请在上面打勾(我保证这次我会的!)
Benjol 2010年

好吧...我会咬;)相关摘录发布。
VonC

Answers:


244

TL; DR;

总结(如Benubird所 评论),当:

git checkout A
git rebase   B    # rebase A on top of B
  • localB(变基),
  • remoteA

和:

git checkout A
git merge    B    # merge B into A
  • localA(合并),
  • remoteB

重新设置切换ours(开始重新设置之前的当前分支)和theirs(您要重新设置其基础的分支)。


kutschkem指出,在GUI mergetool上下文中

  • 本地引用部分基于基础的提交:“ ours”(上游分支)
  • remote是指传入的更改:“ theirs”-变基之前的当前分支。

请参阅此答案最后一部分中的插图。


变基时反转

这种混乱可能涉及到的反转ourstheirs一个重订期间
(相关摘录)

git 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

A git rebase upstream将首先将HEADB 更改为上游分支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

,然后重新部署将在新的“我们的” 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'vs.' mine'和' theirs'

Pandawood评论中添加:

对我来说,问题仍然存在,它是“本地的”而谁是“远程的”(由于在git中重新使用基准时未使用术语“我们的”和“他们的”,提及它们似乎使答案更加混乱) 。

GUI git mergetool

kutschkem添加,并且正确的是:

解决冲突时,git会说类似以下内容:

local: modified file and remote: modified file. 

我非常确定,这个问题目前针对的是本地和远程的定义。从我的经验来看,到那时:

  • 本地引用部分基于基础的提交:“ ours”(上游分支)
  • remote是指传入的更改:“ theirs”-变基之前的当前分支。

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显示合并分辨率,如下所示

kdiff3

而且,meld也会显示它

差异化

VimDiff相同,显示

使用git mergetool -t gvimdiff调用Vimdiff作为mergetool。Git的最新版本使用以下窗口布局调用Vimdiff:

+--------------------------------+
| LOCAL  |     BASE     | REMOTE |
+--------------------------------+
|             MERGED             |
+--------------------------------+
  • LOCAL
    包含当前分支上文件内容的临时文件。
  • BASE
    包含合并通用基础的临时文件。
  • REMOTE
    一个临时文件,其中包含要合并的文件的内容。
  • MERGED
    包含冲突标记的文件。

Git会执行尽可能多的自动冲突解决方案,并且此文件的状态是两者的结合,LOCAL并且REMOTE带有围绕Git无法解决的任何问题的冲突标记。
mergetool应写入解决这一文件的结果。


13
对我来说,问题仍然存在,它是“本地的”而谁是“远程的”(由于在git中重新使用基准时未使用术语“我们的”和“他们的”,提及它们似乎使答案更加混乱) 。问题是“谁是本地人,谁是偏远地区”-因此,答案肯定是需要提及“本地”和“远程”两个词
PandaWood 2011年

@PandaWood:“本地”是“当前分支”(变为“他们的”),“远程”是“上游分支”(变为“我们的”)。
VonC

3
因此,总结一下:当git checkout A; git rebase B本地人是B时,远程人是A。我所需要知道的...
Benubird

1
git就是这样的可用性集群。这是没有意义的:当你git checkout A; git rebase B当地是B,遥控器是一个。如果我checkout A那么我目前正在研究这些文件,因为它们存在于A,如何以任何方式的远程?(我不是说Benubird是错的;我是说git有一个愚蠢的UX)
拉法

1
@VonC确定; 我的观点是不应阅读文档,查看图表以及浏览StackOverflow。如果仅该命令给出了清晰,明确的反馈。例如,仅显示{branch A}和,而不是本地/远程/他们/我们的/我的/您的{branch B}
拉法

45

底线

git rebase

  • LOCAL =你在基础重建的基础
  • REMOTE =您正在上移的提交

git合并

  • LOCAL =您要合并到的原始分支
  • REMOTE =您要合并其提交的另一个分支

换句话说,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."

在master分支上创建一个提交:

git checkout master
notepad file.txt
  (add the text: master)
  (save and exit)
git commit -a -m "Add master text."

gitk --all

此时,您的存储库应如下所示:

具有基本提交和两个单提交分支的存储库

现在进行基准测试:

git checkout notmaster
git rebase master
  (you'll get a conflict message)
git mergetool
  LOCAL: master
  REMOTE: notmaster

现在进行合并测试。关闭您的mergetool而不保存任何更改,然后取消变基:

git rebase --abort

然后:

git checkout master
git merge notmaster
git mergetool
  LOCAL: master
  REMOTE: notmaster
git reset --hard  (cancels the merge)

您的结果应与顶部显示的结果相同。


1
+1。这阐明了local/ remote方面我挣扎在我自己的答案以上(这是更多的反转oursVS theirs反正)
VonC

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.