git中的合并拉取请求导致上游分支超出原点

时间:2018-08-25 18:39:00

标签: git github

术语:

  1. 本地分支称为master
  2. github上的存储库称为origin / master
  3. 我分叉的根存储库称为上游/主存储库。

现在假设我的来源/主文件比上游/主文件早一提交

因此,我为上游/主服务器创建了一个拉取请求,并假设上游存储库的所有者接受了拉取请求并将其合并。

这将在上游存储库中创建+1提交,并显示消息“从githubuser / branchname合并请求请求”。因此,现在在github上显示“该分支(源/主节点)比前面的提交多1个,上游/主节点后面有1个提交。” 尽管实际上,这些分支中的代码实际上是相同的,它们应该保持平衡。

我尝试通过以下方法解决此问题:cleaning the branch without pushing,但似乎更像是黑客。

是否有任何方法可以推入上游而无需对上游进行额外的提交。 是否仅合并拉取请求,以使上游/母版和原始/母版分支均匀?

1 个答案:

答案 0 :(得分:2)

问题的核心在于GitHub。 (稍后我会详细介绍。)因此,您的问题的答案为both no and yes

  

是否有任何方法可以推入上游而无需对上游进行额外的提交。 是否仅合并拉取请求,以使上游/母版和原始/母版分支均匀?

这里有四类人:

  1. 那些由GitHub自己编写的程序。它们控制在Web浏览器中显示的内容,即,您在页面上看到的“合并此拉取请求”绿色按钮,该按钮的边缘有一个小下拉箭头,如果单击该按钮,则可以选择以下三种类型之一合并。

    三种合并方式包括您想要的操作。因此,如果他们更改以添加第四种合并,或者更改了现有三种合并中的一种,或者按照这些内容进行了某种更改,那么这可能会使第3组中的每个人都能执行您想要的操作。 / p>

  2. 具有对上游资源库的管理访问权限的用户。他们可以git push直接进入上游存储库。这意味着他们可以使用命令行Git(根本不是GitHub)执行您想要的操作,然后运行git push来更新GitHub上的存储库。

  3. 具有通过GitHub提供的接口对上游存储库的写访问权,但对上游存储库具有管理权限的人。他们无法做您想做的事情-至少要等到第1组的人将其添加为选项时,才能这样做。

  4. 那些没有写访问权限(可能包括您自己)的用户:他们无法做到这一点。

现在,对于那些GitHub clicky按钮-或更确切地说, button 单数,具有三种模式:提供的三种模式以这种方式标记:

  • 合并。

    您可能会认为这样做可以完成任务,但不会这样做,因为它运行的过程与git checkout branch && git merge --no-ff -m message hash等效。 branch 很明显, message 部分是Merge pull request #number from repository hash 部分比较复杂:它是refs/pull/number/head下的哈希ID。这是您通过单击“比较并提取请求” clicky按钮单击的提交的特定提交的提交ID。

    如果GitHub使用与git checkout branch && git merge --ff-only hash等效的 branch hash ,您将得到你想要什么。当然,将不会包含文本Merge pull request ...的提交。但是那很好。 (这是我希望他们添加的新模式。也许可以将其称为合并而无需其他提交快速转发。)

  • 重新合并并合并

    这会将分支中当前没有的拉取请求提交(可能有多个)提交到分支。它运行与git checkout branch && git rebase --force-rebase hash等效的命令(也许也与--merge--strategy merge一起运行)。最终结果是,拉取请求中的提交被复制,而不是合并到具有新的和不同的哈希ID的新提交中。合并请求完成而没有添加合并提交,因此没有Merged pull request ...消息。

    您可能会认为,在要复制的提交或提交已经位于正确位置的情况下(即,在单击按钮之前刚过去分支的尖端),GitHub不会复制提交,而是按原样使用它们,如果它们运行了git rebase 而没有 --force-rebase--no-ff的情况,则会发生这种情况。但这种情况并非如此。我不知道是否有很好的理由(在GitHub内部)。

  • 压缩并合并。

    这相当于git checkout branch && git merge --no-commit --squash hash && git commit -m message。 (这里的--no-commit是多余的:--squash意味着--no-commit。这是git merge --squash的命令行Git实现的不必要之处,因为如果您想要< / em> --no-commit,您只需指定它即可。)

    因为这产生了一个新的提交,而该新的提交与带来其效果的提交没有任何关系,所以显然完全不适合实现您想要的。

摘要

对上游存储库具有写访问权的用户可以将您的拉取请求放入他们控制的计算机上的Git存储库中,手动将其合并,然后将结果推回到GitHub上的上游存储库中。这就是Tobias K. refers to in a comment。那将实现您想要的。

如果GitHub要添加我希望添加的合并模式,则当前将您的拉取请求与Web-UI合并按钮合并的用户将能够一步完成此操作,而无需涉及自己的计算机和Git命令行命令。但是如果没有这种额外的模式,他们将无法实现。

他们现在实际使用的是 Rebase and merge 模式。我们可以这样判断:

  

所以现在在github上显示“ 此分支(源/主节点)在前面提交1次,在上游/主节点后面进行1次提交。

如果他们使用 Merge 模式,您会发现自己落后于一个提交,而不是向前提交。这对您会更友好,但是在某些方面对他们自己(以及他们存储库的其他用户)不太友好。当他们使用 Rebase and merge 时,他们最终会复制所有提交,因此,如果您之前是 k 个提交,那么您突然会成为 k k 后面:您处于领先位置的 k 您的提交,而您的哈希ID,以及后面的 k 是它们的提交副本 ,带有哈希ID。

从上游的恢复并合并

请注意,您可以通过在自己的计算机上执行以下操作来恢复:

git fetch upstream
git checkout $branch
git rebase upstream/$branch
git push --force-with-lease origin $branch

(其中$branch代表您的分支名称)。 fetch获得其提交的副本。 checkout为您定位要由rebase执行的重新定位。 1 git push将新的提交发送到您的派生(如果尚未存在)然后要求GitHub将您的fork $branch的概念更改为指向上次此类复制的提交,即使此 drop 一些提交成功,也成功(好像通过--force一样),但是如果删除的提交与预期的不完全相同,则失败(--force-with-lease


1 实际上,您可以一步完成此操作,因为git rebase可以让您在开始重新设置基准之前签出一个分支,但是我认为这种方法更清楚。要一步一步完成,请使用git rebase origin/$branch $branch