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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3051461/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-10 08:35:01  来源:igfitidea点击:

git rebase, keeping track of 'local' and 'remote'

gitconflictrebase

提问by Benjol

When doing a git rebase, I often have difficulty working out what is happening with the 'local' and 'remote' when resolving conflicts. I sometimes have the impression that they swap sides from one commit to the next.

在进行 git rebase 时,我经常很难弄清楚在解决冲突时“本地”和“远程”发生了什么。有时我的印象是他们从一次提交到下一次提交交换双方。

This is probably (definitely) because I still haven't properly understood.

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

When rebasing, who is 'local' and who is 'remote'?

变基时,谁是“本地”,谁是“远程”?

(I use P4Merge for resolving conflicts)

(我使用 P4Merge 来解决冲突)

回答by VonC

TL;DR;

TL; 博士;

To summarize (As Benubirdcomments), when:

总结一下(正如Benubird评论的那样),当:

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

And:

和:

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

A rebase switches ours(current branch before rebase starts) and theirs(the branch on top of which you want to rebase).

一个 rebase 切换ours(rebase 开始之前的当前分支)和theirs(要在其上 rebase 的分支)。



kutschkempoints out that, in a GUI mergetool context:

kutschkem指出,在 GUI 合并工具上下文中

  • local references the partially rebased commits: "ours" (the upstream branch)
  • remote refers to the incoming changes: "theirs" - the current branch before the rebase.
  • 本地引用部分重新提交的提交:“ ours”(上游分支)
  • 远程指的是传入的更改:“ theirs” - 变基之前的当前分支。

See illustrations in the last part of this answer.

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



Inversion when rebase

变基时反转

The confusion might be related to the inversion of oursand theirsduring a rebase.
(relevant extracts)

混淆可能与rebase反转ourstheirsrebase 期间有关。
(相关摘录)

git rebaseman page:

git rebase手册页

Note that a rebase merge works by replaying each commit from the working branch on top of the <upstream>branch.

请注意,rebase 合并通过在分支顶部重放来自工作分支的每个提交来工作<upstream>

Because of this, when a merge conflict happens:

因此,当发生合并冲突时:

  • the side reported as 'ours' is the so-far rebased series, starting with <upstream>,
  • and 'theirs' is the working branch. In other words, the sides are swapped.
  • 报告为“ ours”的一方是迄今为止重新调整的系列,以<upstream>
  • ' theirs' 是工作分支。换句话说,双方互换。


Inversion illustrated

反转图示

On a merge

合并时

x--x--x--x--x(*) <- current branch B ('*'=HEAD)
    \
     \
      \--y--y--y <- other branch to merge

, we don't change the current branch 'B', so what we have is still what we were working on (and we merge from another branch)

,我们不改变当前分支'B',所以我们所拥有的仍然是我们正在处理的(并且我们从另一个分支合并)

x--x--x--x--x---------o(*)  MERGE, still on branch B
    \       ^        /
     \     ours     /
      \            /
       --y--y--y--/  
               ^
              their


On a rebase:

在变基上:

But on a rebase, we switch side because the first thing a rebase does is to checkout the upstream branch! (to replay the current commits on top of it)

但是在 rebase 上,我们换边了,因为 rebase 做的第一件事就是检出上游分支!(在其上重放当前提交)

x--x--x--x--x(*) <- current branch B
    \
     \
      \--y--y--y <- upstream branch

A git rebase upstreamwill first change HEADof B to the upstream branch HEAD(hence the switch of 'ours' and 'theirs' compared to the previous "current" working branch.)

Agit 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

, and then the rebase will replay 'their' commits on the new 'our' B branch:

,然后 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


Note: the "upstream" notionis the referential set of data (a all repo or, like here, a branch, which can be a localbranch) from which data are read or to which new data are added/created.

注意:“上游”概念是从中读取数据或向其中添加/创建新数据的参考数据集(一个所有的存储库,或者像这里一样的一个分支,它可以是一个本地分支)。



'local' and 'remote' vs. 'mine' and 'theirs'

' local' 和 ' remote' vs. ' mine' 和 ' theirs'

Pandawoodadds in the comments:

Pandawood评论中补充道:

For me, the question still remains, which is "local" and who is "remote" (since the terms "ours" and "theirs" are not used when rebasing in git, referring to them just seems to make an answer more confusing).

对我来说,问题仍然存在,哪个是“本地”,谁是“远程”(因为在 git 中变基时不使用术语“我们的”和“他们的”,提及它们似乎会使答案更加混乱) .

GUI git mergetool

GUI git合并工具

kutschkemadds, and rightly so:

kutschkem补充说,这是正确的:

When resolving conflicts, git will say something like:

解决冲突时,git 会说:

local: modified file and remote: modified file. 

I am quite sure the question aims at the definition of local and remote at this point. At that point, it seems to me from my experience that:

我很确定这个问题目前针对本地和远程的定义。那时,根据我的经验,在我看来:

  • local references the partially rebased commits: "ours" (the upstream branch)
  • remote refers to the incoming changes: "theirs" - the current branch before the rebase.
  • 本地引用部分重新提交的提交:“ ours”(上游分支)
  • 远程指的是传入的更改:“ theirs” - 变基之前的当前分支。

git mergetooldoes indeed mention 'local' and 'remote':

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):

For instance, KDiff3would display the merge resolution like so:

例如,KDiff3像这样显示合并分辨率

kdiff3

kdiff3

And meldwould display it too:

并且meld也会显示它

Meld diff

融合差异

Same for VimDiff, which displays:

VimDiff相同,它显示

Invoke Vimdiff as a mergetool with git mergetool -t gvimdiff. Recent versions of Git invoke Vimdiff with the following window layout:

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

+--------------------------------+
| LOCAL  |     BASE     | REMOTE |
+--------------------------------+
|             MERGED             |
+--------------------------------+
  • LOCAL:
    A temporary file containing the contents of the file on the current branch.
  • BASE:
    A temporary file containing the common base for the merge.
  • REMOTE:
    A temporary file containing the contents of the file to be merged.
  • MERGED:
    The file containing the conflict markers.

Git has performed as much automatic conflict resolution as possible and the state of this file is a combination of both LOCALand REMOTEwith conflict markers surrounding anything that Git could not resolve itself.
The mergetoolshould write the result of the resolution to this file.

  • LOCAL:
    包含当前分支上文件内容的临时文件。
  • BASE
    包含合并公共基础的临时文件。
  • REMOTE
    包含要合并的文件内容的临时文件。
  • MERGED
    包含冲突标记的文件。

Git 执行了尽可能多的自动冲突解决,并且这个文件的状态是两者的结合,LOCAL并且REMOTE包含围绕 Git 无法自行解决的任何内容的冲突标记。
mergetool应写入解决这一文件的结果。

回答by Ryan Lundy

The bottom line

底线

git rebase

git rebase

  • LOCAL = the base you're rebasing onto
  • REMOTE = the commits you're moving up on top
  • LOCAL =你在基础重建的基础
  • REMOTE = 您在顶部移动的提交

git merge

合并

  • LOCAL = the original branch you're merging into
  • REMOTE = the other branch whose commits you're merging in
  • LOCAL = 您要合并到的原始分支
  • REMOTE = 您要合并其提交的另一个分支

In other words, LOCALis always the original, and REMOTEis always the guy whose commits weren't there before, because they're being merged in or rebased on top

换句话说,LOCAL始终是原始的,而REMOTE始终是之前没有提交的那个人,因为它们正在被合并或重新基于顶部

Prove it!

证明给我看!

Certainly. Don't take my word for it! Here's an easy experiment you can do to see for yourself.

当然。不要相信我的话!这是一个简单的实验,你可以自己做一下。

First, make sure you have git mergetool configured properly. (If you didn't, you probably wouldn't be reading this question anyway.) Then find a directory to work in.

首先,确保正确配置了 git mergetool。(如果没有,您可能无论如何也不会阅读这个问题。)然后找到一个目录进行工作。

Set up your repository:

设置您的存储库:

md LocalRemoteTest
cd LocalRemoteTest

Create an initial commit (with an empty file):

创建初始提交(使用空文件):

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."

Create a commit on a branch that isn't master:

在不是 master 的分支上创建提交:

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

Create a commit on the master branch:

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

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

gitk --all

At this point your repository should look like this:

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

Repository with a base commit and two one-commit branches

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

Now for the rebase test:

现在进行变基测试:

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

Now the merge test. Close your mergetool without saving any changes, and then cancel the rebase:

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

git rebase --abort

Then:

然后:

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

Your results should be the same as what's shown up top.

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

回答by Chathuranga Chandrasekara

I didn't get your problem exactly but I think the following diagram resolves your issue. (Rebase : Remote Repository ---> Workspace)

我没有完全理解您的问题,但我认为下图可以解决您的问题。(变基:远程存储库 ---> 工作区)

http://assets.osteele.com/images/2008/git-transport.png

http://assets.osteele.com/images/2008/git-transport.png

Source: My Git Workflow

来源:我的 Git 工作流程