如何解决与远程git repo的冲突?

时间:2014-10-06 21:39:31

标签: git merge conflict

所以,首先,我是一个完全新手的git。

我们的工作流程是克隆远程仓库,做工作,提交等等,直到我们开心,然后推送到原点/分支。然后做一个拉取请求。 (这可能是疯了,它似乎容易出现问题,但我对这些东西一无所知,只是盲目地遵循程序:-))我这样做......并且与其他人编辑的文件存在冲突在我克隆了主人后,他们在自己的分支中合并了。我的提交使该文件多余,所以我想要的快速答案是,如何使git只是破坏这个文件?但更长远的是,只要发生冲突,这显然不是正确的答案:-)但是我向Google提出的所有内容似乎都假设我直接在有问题的回购中工作。像" git status'告诉他们一切都很好,因为它正在看我的回购克隆。我无法找到解决这个问题的方法。

1 个答案:

答案 0 :(得分:8)

在其他任何事情之前,让我这样说(虽然它有点简化但足够准确):git pull只是一个便利脚本,它执行两个基础git命令,git fetch跟随按git merge。如果你用fetch而不是pull而不是git push(获取+合并)来思考,事情会更有意义。

你确实,不能 - 使用git在#34;远程存储库"上工作。一切都是本地的。当您获取或推送时,您的本地git会联系远程 - 将其视为通过互联网电话呼叫其他人 - 以及您的git和他们的git交换信息,之后您要给他们一些东西(git fetch )或者他们给你东西(origin/master)。

当他们给你的东西时,你的git会记下他们拥有的分支,并更新你对#34;遥控器上的内容的看法。这些进入你的(本地!)"远程分支",例如origin/developorigin/,或者他们使用的任何分支名称:你的git将git fetch origin放在前面,因为你正在做git fetch 1 这个分支重命名技巧非常重要。这尤其意味着无论您在哪个地方分支机构工作,运行.git始终都是安全的,因为这只会更新您的远程分支机构"。 (这又是本地的 - 他们会在您的git push origin master目录中,而不是远程用户。只要您的git调用,您只需与他们同步,添加,更改和删除您的副本他们在互联网电话上的git。)

但是,当你给他们的东西时,没有重命名。当你执行origin时,你的git会说,无论是谁,你都可以致电master:"嘿,我建议你们将master更改为这个新的提交我'给你。"他们是否接受这一点取决于他们。一般来说,他们(无论他们是谁)接受"快速前进"但不是"非快速前进"。有关这方面的更多信息,请参阅this much longer answer

当使用拉取请求(并将它们与用户启动的推送相结合)时,您通常会将提交推送到每个用户的位置:例如,而不是从您的master推送到to-everyone/from-JohnOliver/master遥控器,你可以推到master。或者,您可能会推送到只有您推送的存储库,但其他人都可以看到。这里的想法是,你在这里所做的推动从不与其他任何人发生冲突,只是让你的提交可见,然后你发出"拉请求"告诉别人去看那些提交。如果他们(无论他们是谁)喜欢他们,他们会将它们添加到遥控器上的pull。如果没有,他们会让你重写它们。

请注意,如果您重写提交,则会获得新的不同的提交。每个提交都有一个非常丑陋的SHA-1 ID作为其完整的"真实名称"。此ID是提交的全部内容的加密校验和:所涉及的所有文件,您的姓名和电子邮件,日期/时间戳以及您的提交的父提交。如果你改变任何东西,你会得到一个新的不同的提交。 (您的新提交可以使用与旧提交相同的父ID,以及相同的用户名和电子邮件。如果您足够快[可以在一秒钟内完成多少次提交?:-)],或者钻井时间,你甚至可以得到相同的时间戳。但是如果文件不同,您将获得不同的commit-ID。没关系:这就是我们想要的。如果你得到相同的提交ID,那么所有文件都是相同的,你的名字和时间也是如此,所以它毕竟是旧的提交。)


现在,回到你的问题......

  

我做了[拉] ...并且在我克隆了主人之后,在他们自己的分支中编辑的其他人编辑的文件发生了冲突。我的提交使该文件多余,所以我想要的快速答案是,如何让git只是破坏这个文件?

当您执行fetch时,您正在执行merge后跟fetchorigin/master带来了其他人的提交,现在可以在master(或任何分支;我只是假设master上找到它们这里)。

如果您已经提交了自己的工作,那么您可以在git merge找到自己的提交内容。 (如果你没有做出承诺,那么做 A <-- master <-- HEAD / ...* <-- * \ B <-- origin/master 可能不是一个好主意。但是你上面的工作流程说明了你。所以让我们假设你有我们绘制了生成的#34;提交图表&#34;,这只是一种写下来(在白板上或作为ASCII艺术或其他什么)一些提交显示谁做了什么的奇特方式:

A

您的提交master位于B。他们的提交origin/master位于您的master上(从A复制)。 B*都具有相同的父提交,即图中最右侧的*节点。 /指向其父级,依此类推。 (\*行确实应该是指向git merge的箭头,但箭头仅适用于某些浏览器。)

A所做的是尝试将B中的更改与git status中的更改结合起来。只要git无法自行组合,就会出现合并冲突。

  

...我的提交使该文件变得多余,所以我想要的快速答案是,如何让git只是破坏这个文件?但更长远的是,只要发生冲突,这显然不是正确的答案:-)但是我向Google提出的所有内容似乎都假设我直接在有问题的回购中工作。像&#34; git status&#39;告诉我一切都很好......

如果git merge认为合并进展顺利,并且merge没有停止并说出存在冲突,那么git没有意识到冲突。它认为您的更改和更改都可以合并为所有更改的总和&#34;。然后 A / \ ...* <-- * M <-- master <-- HEAD \ / B <-- origin/master 继续进行新的提交:

M

这里唯一的问题是与合并结果git push相关联的文件错误:正如您所说,他们的更改(或整个文件本身)应该消失,但是git认为这与你的更改没有冲突,所以git保留了两者!

让我在这里重复一句话:

  

我向Google提出的所有内容似乎都假设我直接在有问题的回购中工作。

。您正在 回购中工作。如果您git commit或以其他方式邀请其他人从您的回购中获取内容,您就会分享您所做的事情,但在此之前,这一切都是您的。 在发布之前它是私密的,这意味着您也可以更改

如果您确实有这样的虚假合并提交,那么要做的就是在发布之前删除或修复合并。 (你当然可以在事后修复它,但以前其他人都可以更好地修复它。)

how to remove a merge with git reset的stackoverflow上,或者如何修改一个(你可以git commit --amend a merge commit,如果你想保留合并本身,这是特别方便的)。如果你删除合并,你可以&#34; rebase&#34;你提交的新的提交,但在这里要小心:因为git在合并时没有发现任何冲突,它几乎肯定不会在重新定位时检测到冲突,并且你会发现想要重做一个文件,特别是在你的提交不需要更改的时候(或者不需要整个文件)。交互式rebase为您提供了执行此操作所需的所有工具,当然,在此过程中还有很多东西需要了解git。有关变基的更多stackoverflow答案。


最后,如果确实发生冲突,但解决了(可能不正确)并git merge --no-commit - 结果,则解决方法仍然与上述相同:删除或修复合并。如果要删除合并,然后重复它,但没有让git提交生成的文件,请使用git rm file.dat # no longer needed at all 。 Git将尽最大努力自动合并所有内容,但随后停止而不提交。这为您提供了撤消更改的位置,甚至:

git commit

之后,您可以git fetch batman结果(作为合并提交)。


1 如果您正在执行batman/master,那么您的git会将它们命名为git fetch,依此类推。基本上,遥控器只是&#34;你的名字&#34;,他们的分支将这个名字推到前面,你的git以这种方式跟踪他们的分支。这就是为什么他们被称为远程分支机构&#34;,或者有时是稍长的短语&#34;远程跟踪分支机构&#34;。

如果您只是运行origin,而没有命名origin,git会自动确定要使用哪个遥控器;通常情况下,batman只是brucewayne(但是谁知道,如果你已经设置了它,那么可能是{{1}},甚至{{1}}或其他什么。在任何情况下,相应的远程名称都会卡在&#34;远程分支&#34;。

之前