在比较分支时,有没有一种方法可以“隐藏”GitHub中的合并提交?

10

我和我的团队(大约10个人)正在使用GitHub进行开发项目。我们有一个主要的develop分支,从中创建功能分支以完成开发任务,然后再将功能分支合并回develop分支。我们使用Pull Requests来进行代码审查。这都是标准流程。

然而,有一件事情一直在困扰着我。

假设开发人员A创建了一个名为myFeature的功能分支。在该分支中,他对单个文件(例如Loop.java)进行了一行更改。

与此同时,其他开发人员通过其他分支将100个不相关的提交合并到develop分支中。

现在,在开发人员A推送其更改并发出pull request之前,他想确保他的更改能够与最新的develop分支配合工作。因此,他将develop的HEAD合并到自己的分支中:

git checkout develop
git pull
git checkout myFeature
git merge develop
# testing and stuff
git push origin myFeature
最后一个命令(git merge develop)总是会产生一个新的提交。 因此,当开发人员A推送他的更改并发布myFeature的拉取请求时,拉取请求的审核者将看到101个提交添加到分支myFeature:其中一个具有对Loop.java的更改,另外100个则无关且已经合并到了develop中。它们只是噪音,掩盖了开发人员在此分支中实际上进行了哪些更改。 有没有一种简单的方法让审核人员只看到由开发人员A进行的更改,并"隐藏"来自与develop的合并的提交?我特别考虑Pull Request视图中的"已更改文件"选项卡。(我知道可以使用“提交”选项卡,逐个查看所有提交以查看进行了哪些更改,但如果有很多提交,这可能很繁琐。我喜欢“已更改文件”选项卡的单一、最终视图。) 编辑:提出了git rebase develop作为一个选项,但我认为这对我们的目的不适用。通常,多个开发人员将在myFeature上工作,因此rebase有可能使每个人都出现问题,因为它重写了历史记录。 编辑2:正如@kan在下面友好地指出的,GitHub实际上表现得很好:是的,在拉取请求的“提交”选项卡中会显示合并提交(这完全没有问题),但在“已更改文件”选项卡下,仅列出此功能分支上更改的文件(而不是来自合并的文件)。这正是我要找的。

如果A的myFeature分支是从develop分支创建的,并且他将最新更改从develop合并到了该分支,那么我认为GitHub上不应该出现数百个额外的提交记录,而只应该是该分支独有的提交记录。A是否正在向错误的分支发起拉取请求,例如向master而不是develop - user456814
@ColdHawaiian:不,A 是从 develop 分支出来,然后合并到 develop,最后发起一个拉取请求合并到 develop。这也是我感到困惑的原因。 - stepthom
另一个可能性是A的开发历史版本已经被修改了(即相应提交的提交shas不同)。也许A的提交已经被重写了,使用了rebasecherry-pickcommit --amend?A是使用命令行中的Git还是像GitHub for Windows这样的GUI?GitHub for Windows会隐式地进行奇怪的重写操作。 - user456814
@ColdHawaiian:不,不是那么复杂的问题。我们在Ubuntu上使用命令行,没有使用rebase或其他任何东西。我能够在测试存储库上重新创建场景,进行非常简单的提交和更改:我将创建一个新分支myFeature,进行更改,然后提交和推送。我会在GitHub上查看,并可以看到myFeature上的单个提交。然后我将检出develop,进行无关的更改并提交。然后我再次检出myFeature,并执行git merge develop,然后推送。我在GitHub上查看myFeature分支的比较视图,它列出了两个提交。 - stepthom
2个回答

7

一种方法是不要使用git merge,而是使用git rebase develop。这样就不会导致合并提交并将新提交放在develop的新提交末尾。

然后历史记录中应只显示一个新提交作为拉取请求中的更改。我认为这也使得历史记录保持线性并更易于跟踪。


2
根据我所读的(包括下面@kan的评论),如果功能分支已经推送到远程服务器,那么git rebase不是一个好主意,因为其他开发人员可能也拉取了该分支。这是真的吗?另外,rebase如何处理合并冲突? - stepthom
1
是的,这是真的。因为这将重写已推出的历史记录。Rebase 的工作方式是 Git 回滚到分支发生分歧的地方,导入远程的更改,并逐个应用回滚的提交。因此,当冲突发生时,您需要在继续之前修改提交。由于更改了历史记录,所以您要小心使用。 - Schleis
@doofuslarge 是的,这基本上意味着所有获得该分支的开发人员都应该进行变基操作。如果您仔细阅读 git help rebase,它们将其描述为“涟漪效应”。Gerrit引入了变更集的概念,可以更优雅地处理它。 - kan
@kan 非常感谢您的建议和帮助。目前,我认为由于其连锁反应效应,变基对我们的工作流程不太适用,因此看起来我只能接受上述问题了。 - stepthom
1
@doofuslarge,有一件事我不喜欢你称之为“问题”。它不是一个问题,而是对历史的更准确的反映——实际上发生了什么。 - kan
显示剩余7条评论

2

是的,您可以使用rebase来完成这个操作。

git checkout myFeature
git fetch
git rebase origin/develop
git checkout develop
git merge @{upstream}
git merge myFeature # it will do fast-forward, so no merge commit

然而,你应该意识到,只有当myFeature未被其他开发人员共享时,才应使用rebase。
顺便说一下,我们正在使用gerrit。它允许在合并之前rebase一个变更集。当然,如果存在冲突,则应在本地执行rebase并重新提交变更集。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接