草庐IT

Git Rebase 冲突 : Who is HEAD?

coder 2023-06-23 原文

我有这个项目,其中远程仓库有主要的开发分支,我有一个包含实验分支的分支。我需要rebase在我推送到我的分支之前,从开发分支更改为我的实验分支。所以它是这样的:

git checkout experimentalbranch
git fetch remoterepo
git rebase remoterepo/developmentbranch

这时,我遇到了冲突。但是,我对这些更改中的任何一个都不熟悉(我正在重新调整数周的更改,因为它们没有立即 merge 我的更改)。另外,这是我第一次做 rebase .我比较习惯merge .

在融合中,它通常是这样的 <<LOCAL||REMOTE>>merge ,这听起来很直观。但在 rebase ,它是 <<HEAD||COMMIT MESSAGE>> .谁是HEAD ?是不是HEAD开发分支?它是开发分支或其他地方的最新代码吗?

最佳答案

TL;DR(2018 年 5 月添加)

整个事情从根本上说至少有点令人困惑,因为 Git 让其内部工作直接向您展示。

请注意,当您运行时,我们在这里关注的情况会发生:

git checkout somebranch; git rebase origin/their-branch

或类似。 rebase 暂时停止以强制您解决 merge 冲突,之后您应该git add解决冲突并运行 git rebase --continue . (如果你使用一些带有 git mergetool 的 merge 工具,或者一个花哨的 GUI 界面,该界面可能会以其他方式为你做一些或全部,但在下面,它是 git add 解析文件并运行 git rebase --continue 。 )

一开始,HEAD commit 是他们的分支,所以如果你使用 git checkout --oursgit checkout --theirs , --ours意味着他们的——最后一次提交 origin/their-branch ——同时 --theirs意味着你的,你正在 rebase 的第一个提交。这是正常的日常 Git 混淆(请参阅 What is the precise meaning of "ours" and "theirs" in git? ),而不是导致原始问题的原因。

然而后来,HEAD commit 实际上是一种混合物。这是在最新提交上复制一些提交的结果。你现在在你自己部分构建的新提交系列和你自己的原始提交之间发生冲突。这种冲突的根源通常是“他们”所做的事情(在 origin/their-branch 中发生了变化)。您仍然必须解决此冲突。当您这样做时,您可能会在以后的提交中看到完全相同的冲突。

再次,HEADlocal--ours是 rebase 通过组合您的更改及其更改构建的提交,另一个提交( remote>>>>>>>--theirs )是您自己的提交,rebase 试图复制 HEAD .

更长

merge 时(包括 rebase ,这是内部重复“merge ”的一种特殊情况),涉及两个“头”(两个特定的分支提示)。让我们称这些 your-branchorigin/their-branch :
              G - H --------      <-- HEAD=your-branch
            /               \
... - E - F                   M   <-- desired merge commit [requires manual merge]
            \               /
              I - J - K - L       <-- origin/their-branch

这一点通常(并且不出所料)令人困惑,尽管这样标记时就足够清楚了。

更糟的是,git 使用 --ours--theirs引用 merge 期间的两个主要提交,“我们的”是您运行时所在的提交(提交 H ) git merge ,而“他们的”是他们的(提交 L)。但是当你在做 rebase 时,两个 head 是颠倒的,所以“ours”是你正在 rebase 的 head——即他们更新的代码——而“theirs”是你当前正在 rebase 的提交,即,您自己的代码。

这是因为 rebase 实际上使用了一系列挑选操作。你从几乎相同的图片开始:
              G - H           <-- HEAD=your-branch
            /
... - E - F
            \
              I - J - K - L   <-- origin/their-branch

这里git需要做的就是复制commits的效果GH ,即 git cherry-pick提交 G ,然后再次提交 H .但要做到这一点,git 必须切换到提交 L首先,内部(使用“分离头”模式):
              G - H           <-- your-branch
            /
... - E - F
            \
              I - J - K - L   <-- HEAD, origin/their-branch

现在它可以通过比较提交的树来启动 rebase 操作 FG (看看你改变了什么),然后比较 F对比 L (查看您的某些工作是否已经在 L 中)并进行任何尚未在 L 中的更改并添加它。这是内部的“merge ”操作。
              G - H           <-- your-branch
            /
... - E - F                   G'   <-- HEAD
            \               /
              I - J - K - L   <-- origin/their-branch

如果 merge 不顺利,HEAD仍然留在提交 L (因为提交 G' 尚不存在)。因此,是的,HEAD是他们开发部门的负责人——至少,现在是。

曾经的副本G虽然存在,HEAD移至 G'并且 git 尝试从 H 复制更改,以同样的方式(diff G vs H ,然后 diff F vs G' ,并 merge 结果):
              G - H           <-- your-branch
            /
... - E - F                   G' - H'   <-- HEAD
            \               /
              I - J - K - L   <-- origin/their-branch

同样,如果 merge 失败并需要帮助,您将剩下 HEAD指向 G'而不是 H'H'还不存在。

一旦 merge 成功并提交 G'H'确实存在,git 删除标签 your-branch来自提交 H ,并使其指向提交 H'相反:
              G - H
            /
... - E - F                   G' - H'   <-- HEAD=your-branch
            \               /
              I - J - K - L   <-- origin/their-branch

你现在重新定位和HEAD再次是您所期望的。但是在rebase期间,HEAD要么是他们的分支提示(commit L),要么是复制并附加到他们的分支提示之后的新提交之一;和 --ours表示在 L 末尾生长的分支而 --theirs表示被复制的提交(上面的 GH)。

(这基本上是 git 公开了它如何做的原始机制,这在 git 中发生得相当多。)

关于Git Rebase 冲突 : Who is HEAD?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23207791/

有关Git Rebase 冲突 : Who is HEAD?的更多相关文章

  1. git使用常见问题(提交代码,合并冲突) - 2

    文章目录git常用命令(简介,详细参数往下看)Git提交代码步骤gitpullgitstatusgitaddgitcommitgitpushgit代码冲突合并问题方法一:放弃本地代码方法二:合并代码常用命令以及详细参数gitadd将文件添加到仓库:gitdiff比较文件异同gitlog查看历史记录gitreset代码回滚版本库相关操作远程仓库相关操作分支相关操作创建分支查看分支:gitbranch合并分支:gitmerge删除分支:gitbranch-ddev查看分支合并图:gitlog–graph–pretty=oneline–abbrev-commit撤消某次提交git用户名密码相关配置g

  2. ruby - mixin方法名冲突时如何选择调用方法? - 2

    当你在类中包含方法名冲突的模块时,它会使用类定义的方法。有没有办法选择我想运行的?moduleBdefself.hello"helloB"endendclassAincludeBdefself.hello"helloA"endendA.hello#=>thisprints"helloA",whatifIwant"helloB"? 最佳答案 Ben,当你在Ruby中调用一个方法(比如hello)时,会发生以下情况:如果接收者的特征类有一个名为hello的方法,它将被调用。如果不是:如果接收者的类有一个名为hello的实例方法,它将被调

  3. ruby - 无法激活 susy-2.1.1,因为 sass-3.2.17 与 sass 冲突 (~> 3.3.0) - 2

    我已经安装了最新版本的compass、sass和susy。但我仍然收到此错误:Unabletoactivatesusy-2.1.1,becausesass-3.2.17conflictswithsass(~>3.3.0)有人知道这个Ruby是如何工作的吗?这是我安装的gem的列表:***LOCALGEMS***CFPropertyList(2.2.0)chunky_png(1.3.0)compass(0.12.4)compass-core(1.0.0.alpha.19)compass-import-once(1.0.4)compass-rails(1.1.3)fssm(0.2.10)l

  4. ruby-on-rails - rb_gc() 上的跨线程冲突 - 2

    我正在处理的代码库最近从Ruby1.9.2升级到Ruby1.9.3,从Rails3.1升级到Rails3.2.2。因为我使用的是RVM,所以我只是简单地执行了rvminstall1.9.3,我原以为这是所有必要的。当我运行时railss我得到了错误[BUG]cross-threadviolationonrb_gc()我找到了许多与此问题相关的链接。有oneonStackOverflow,但它并没有真正给出答案。最有希望的答案是ontheRVMsite:IneverycaseofthisIhaveseenthusfarithasalwaysendedupbeingthatarubygem

  5. ruby - 我们如何访问/操作与 byebug 保留关键字冲突的变量名? - 2

    我们如何访问那些与byebug保留名称冲突的变量名称?(byebug)varlocalh={"hierarchyId"=>"59f0b029e4b037ef11a055f7","level"=>2,...self=(byebug)我想访问变量“h”但键入h会显示“byebug的帮助对话框”(byebug)hbreak--Setsbreakpointsinthesourcecodecatch--Handlesexceptioncatchpointscondition--Setsconditionsonbreakpointscontinue--Runsuntilprogramends,hi

  6. ruby - Ruby 线程不能在写入时发生冲突吗? - 2

    在过去的C#和Java工作中,我习惯于这样的声明不是线程安全的:x+=y;但是,在与Ruby并行运行上述代码时,我未能观察到任何线程间的冲突。我读过Rubyautomaticallypreventsmultiplethreadsfromwritingtothesamedataconcurrently.这是真的?因此+=运算符在Ruby中是线程安全的吗? 最佳答案 好吧,这取决于您的实现和很多事情。在MRI中,有一个GVL(GiantVMLock)这样的东西,它控制哪个线程一次实际执行代码。你看,在MRI中,一次只有一个线程可以执行R

  7. ruby-on-rails - 解决 Rails 应用程序中的类名冲突 - 2

    我一直在构建一个执行会计功能的Rails应用程序。作为其中的一部分,我有一个类名为Transaction的模型。到目前为止一切顺利,我构建此功能已有一个月左右的时间,一切都按预期进行。到目前为止...我刚刚发现几个月前使用Ruport库开发的一些旧报告功能已停止工作。看起来Ruport在生成PDF时需要一个库,该库也有一个名为Transaction的类/模块。TypeErrorinAdmin/teamreportsController#generateTransactionisnotamodule...Thiserroroccurredwhileloadingthefollowingf

  8. ruby-on-rails - 如何解决 Rails 模型 namespace 冲突 - 2

    到目前为止的故事:我有一个Rails应用程序,其模型名为“Term”。在尝试安装Cucumber之前一切都很好。运行时rakecucumber我明白了Termisnotaclass(TypeError)发生这种情况是因为Cucumber包含另一个gem,'term-ansicolor'(在控制台中执行漂亮的彩色文本输出),并且term-ansicolor定义了一个名为“Term”的模块。Cucumber在包含Rails模型之前包含term-ansicolor,因此在加载“Term”模型时“Term”已经被定义为一个模块。顶级模块和类在Ruby中不能有相同的名称,因此会发生冲突。不想重命

  9. ruby-on-rails - Railties 的可执行文件 "rails"与/usr/bin/rails 冲突 - 2

    我正在尝试使用命令sudogeminstallrails安装rails但是,当我这样做时,我收到以下错误消息:railties'sexecutable"rails"conflictswith/usr/bin/railsOverwritetheexecutable?[yN]我目前没有安装rails,我也不打算安装RVM或rbenv,尽管我可能会在以后安装。注意当前未安装Rails有人可以建议我应该做什么吗?谢谢 最佳答案 我刚刚在我的MacBook上安装Rails时遇到了这个问题。我打开/usr/bin/目录并在文本编辑器中打开“ra

  10. ruby - Gitlab 配置问题::NGINX Unicorn 端口冲突 - 2

    我已经成功地部分设置了Gitlab在带有Apache、Git、PHP、PostGreSQL和MySQL的LinuxCentOS服务器上。我正在运行ChefCookbookversion.我从here得到了rpm.我想用它来更好、更直观地管理我的Git存储库,这似乎是一个不错的选择。但现在我遇到了让它工作的问题。为了让它真正工作并更新所有文件,我决定使用gitlab-ctlreconfigure重新运行配置。第二次运行确实有效:ChefClientfinished,4resourcesupdatedgitlabReconfigured!参见fulllog托管商已经将NGINX安装在808

随机推荐