当上游从不完善的PR走向上游时,正确的方法是继续进行?

时间:2018-09-16 22:59:46

标签: git github

简介

我已经建立了一个遵循所谓的“ git flow”的存储库,并且必须开发/掌握/工厂分支。从现在开始,我将在叉上引用origin,在主存储库中引用upstream

打开问题并与回购维护者讨论/达成一些协议后,我开始着手研究。我要做的第一件事是创建功能分支跟踪(起源/开发)。

在几次临时提交并带有临时丢弃的临时坏名之后,我创建了一个PR并推送了。我想到的想法最终是将所有提交压缩到一个提交中,然后提供适当的提交名称/描述,以便维护人员能够毫无问题地将所有合并到上游/开发中,我的主要目标是使对于我和上游维护者而言,整个过程都尽可能地顺利,一旦合并,我将很乐意删除我的本地分支,完成工作,轻松自如...:)

问题

我天真的想法会如此顺利!

无论如何我都不是git专家,并且我认为PR会如此平稳地发展是错误的(这可能在您不真正知道所使用的工具时发生)。在某个时候,我停止了几天的PR工作,显然上游/开发工作在不断发展,远远超出了PR,我的PR尚未通过测试,整个PR仍在等待未完成的工作

几天后,我决定返回该PR,并尝试恢复我的工作,在获取上游/开发后,我发现许多上游提交已经离我的PR遥远了,我真的不知道什么是在特定情况下的最佳选择,我不知道,我仍然不知道合并还是重新部署是最佳选择...

在对合并或重新定级的潜在含义了解甚少的情况下,我认为合并不会那么糟糕,最终一切都有可能整理,对吧?好吧,结果是,在合并并推送了更多临时提交之后,我的本地历史变得有些混乱,我真的不知道是否可以在不弄乱上游历史的情况下将其清除。

让我们说历史看起来像是PR = c1-> c2-> c3->上游1->上游2->上游3-> c4-> c5。在该示例中,c1..c6将是我的本地更改,而上游1..upstream3将是从上游提交的。

问题

  • 当上游与未完成的PR相距很远时,我决定合并一个错误选择的决定吗?在那种情况下进行处理的最佳方法是什么?考虑到我的目标是最终将单个压缩的提交最终合并到上游
  • 一旦造成了伤害,并且在解决冲突后合并并创建了更多提交,是否仍然有可能仅通过一次压缩就可以提供干净的PR,而无需重写上游历史记录?

我想通过询问上游远离您的未完成PR(包含多个临时提交)的最佳方式来总结整个线程。

3 个答案:

答案 0 :(得分:4)

在这种情况下,我会告诉我该怎么做。这种方法非常实用,可能不同的人有不同的个人选择。

与您一样,我也努力将PR中的提交压缩为1。

所以说,有一个dev分支。

当我启动功能分支时,我会做:

>> git checkout dev
>> git pull
>> git checkout -b feature_branch
>> commitA
>> commitB
>> git push -u origin feature_branch // now there is origin/feature_branch available to everyone
>> and create a PR when I'm ready

现在过程如下:

人们查看我的工作并发表评论,然后进行更改并提交。这是一种循环, 结束时,我们所有人都对这些更改感到满意,并准备将事情合并回

>> commitC
>> commitD

所以,现在我准备“将提交压缩为一个”。所以我这样做:

>> // make sure I'm on feature_branch
>> git rebase -i HEAD~4
>> // at this point I have one 'beautiful' commit, lets_call it commit_TO_GO
>> git push -f //forcefully push my commits by overriding the current state of a remote branch in PR, this is not really important, only if I want to "preserve this state for backup or something

只要该分支没有合并,我就不介意这样做,没关系。

让我们假装此过程花费了一些时间,同时,origin/dev分支中还有其他队友完成了一些新的提交(commitX,commitY和commitZ)。

因此,从理论上讲,我现在可以执行以下操作: 通过应用常规的三向合并进行合并,如果有冲突,我首先必须解决它们。

但是,由于我担心提交的历史(就像您一样),因此请执行以下操作:

>> git fetch --all 
>> git rebase origin/dev
>> // at this point The my commit_TO_GO is applied on top of commitX,commitY,commitZ. 
>> // technically it has a different sha1 now, but it's not really important, its 
>> still my own branch, I do whatever I want there :)
>> git push -f // again forcefully push to origin/feature_branch

在此步骤之后,origin/feature_branchorigin/dev的FF,这很酷,因为我可以应用合并,并且它将处于FF模式,甚至不会创建合并提交。 / p>

当然,如果存在冲突,则无法进行重新设置基准,我必须首先解决冲突。我在IDE中执行此操作,然后继续进行变基(git rebase --continue),但是解决冲突已超出此问题的范围

现在我准备将更改合并回origin/dev

通常,我是在bitbucket / github的UI中完成的。

合并后,origin/dev中的历史记录看起来很美:

commitX->commitY->commitZ->commit_TO_GO

结果:根本没有合并提交,我的单个提交最后应用

要考虑的一点:

即使在开发过程中(当您在feature_branch上工作时),只要确保它包含最新更改,就没有必要从dev分支重新建立基础。因此,您可以根据需要多次遍历循环:

 >> git fetch --all 
 >> git rebase origin/dev

我了解到,Git可能袖手旁观了更多的“快捷命令”,也许这个解释太详细了。

答案 1 :(得分:2)

就最终结果而言,合并和重新定基是相同的...但是,就产生的历史记录以及“孤立地”进行工作的轻松程度而言,它们是完全不同的。 ..如果您进行工作,然后进行合并,然后进行更多的工作...然后进行合并...然后进行更多的工作,依此类推,很难仅查看构成该功能的所有修订。

所有这些要说的只是重新设定基准。应该怎么办?转到上游/开发的提示,挑选构成功能的实际修订版本(不合并)...这样,您便清理了分支...设置本地功能指向这一点并继续工作...如果在上游/开发上进行了更多工作,请在此基础上重新构建。

答案 2 :(得分:0)

如上所述,我将选择使用git rebase,如下所示。

topic是您的请求请求,与此同时master分支涉及另一个提交。

      A---B---C topic
     /
D---E---F---G master

rebase意味着更改以前的基础,这也会修改分支的历史记录。

              A'--B'--C' topic
             /
D---E---F---G master

因此,您必须强制推送到远程分支。因为以前没有人合并过您的PR,所以可以,不会对您的合作者造成任何影响。

您可以在此处阅读有关变基的更多详细信息: Pro Git v2, Git Branching - Rebasinggit-rebase command