术语:
现在假设我的来源/主文件比上游/主文件早一提交
因此,我为上游/主服务器创建了一个拉取请求,并假设上游存储库的所有者接受了拉取请求并将其合并。
这将在上游存储库中创建+1提交,并显示消息“从githubuser / branchname合并请求请求”。因此,现在在github上显示“该分支(源/主节点)比前面的提交多1个,上游/主节点后面有1个提交。” 尽管实际上,这些分支中的代码实际上是相同的,它们应该保持平衡。
我尝试通过以下方法解决此问题:cleaning the branch without pushing,但似乎更像是黑客。
是否有任何方法可以推入上游而无需对上游进行额外的提交。 是否仅合并拉取请求,以使上游/母版和原始/母版分支均匀?
答案 0 :(得分:2)
问题的核心在于GitHub。 (稍后我会详细介绍。)因此,您的问题的答案为both no and yes:
是否有任何方法可以推入上游而无需对上游进行额外的提交。 是否仅合并拉取请求,以使上游/母版和原始/母版分支均匀?
这里有四类人:
那些由GitHub自己编写的程序。它们控制在Web浏览器中显示的内容,即,您在页面上看到的“合并此拉取请求”绿色按钮,该按钮的边缘有一个小下拉箭头,如果单击该按钮,则可以选择以下三种类型之一合并。
三种合并方式不包括您想要的操作。因此,如果他们更改以添加第四种合并,或者更改了现有三种合并中的一种,或者按照这些内容进行了某种更改,那么这可能会使第3组中的每个人都能执行您想要的操作。 / p>
具有对上游资源库的管理访问权限的用户。他们可以git push
直接进入上游存储库。这意味着他们可以使用命令行Git(根本不是GitHub)执行您想要的操作,然后运行git push
来更新GitHub上的存储库。
具有通过GitHub提供的接口对上游存储库的写访问权,但对上游存储库具有管理权限的人。他们无法做您想做的事情-至少要等到第1组的人将其添加为选项时,才能这样做。
那些没有写访问权限(可能包括您自己)的用户:他们无法做到这一点。
现在,对于那些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
。