整洁,干净的压缩git PR和合并提交,进入一次提交

时间:2014-11-29 22:55:42

标签: git github commit pull-request

大多数情况下,在repos中,我们看到PR,然后是该PR的合并提交,它只是说“Merged pull request #XXX from ...”。

但是最近,我看到了一个压缩版本,其中拉请求者的角色和提交者重叠,并且only one clean commit出现在历史中:

enter image description here

如何做到这一点?

我尝试过但不起作用:


更新

以这种方式合并one of my PRs时的样子示例:

enter image description here

结果:

enter image description here

2 个答案:

答案 0 :(得分:5)

2016年4月更新

GitHub已经为squash commits when merging引入了一个选项,因此您可以直接从其网络用户界面执行此操作:

Squash and merge

旧解决方案

刚发现这个workflow from the Meteor team(巧合的是,感谢@Emily):

  

当您在GitHub网络界面中查看拉取请求时,有一个非常有吸引力的"合并"按钮。永远不要使用合并按钮。这是attractive nuisance。它导致git历史比必要的更复杂:如果PR在一个月前提交,那么提交的父级将是一个非常旧的修订版,导致在图形视图中输出的行数超过必要git历史。另外,如果您使用合并按钮,这意味着您没有查看代码并自行尝试!以下是更好的拉取请求的方法。

首先,在您的存储库中,找到[remote "origin"]文件的.git/config部分并添加以下行:

fetch = +refs/pull/*/head:refs/remotes/origin/pr/*

确保在现有的提取行之前添加它。现在,每次git fetch,你都会更新repo中的所有Pull请求!这是一次性更改,可让您永久直接访问PR。

然后您可以git checkout pr/XXX直接处理更改。樱桃采摘后git push origin将创建紧凑的PR:

git checkout pr/32
# ... test changes ...
git checkout master
git cherry-pick pr/32
git push 

enter image description here

唯一的缺点是GitHub在关闭时不会自动删除PR分支,但只需点击一下即可获得更好的历史记录。

  

如果PR是多次提交,最好的办法是检查它,将它重新绑定到您的开发分支,进行您需要的任何其他更改,并将其合并回开发分支使用显式合并提交。这类似于GitHub合并按钮所做的,除了合并按钮没有做非常重要的rebase步骤,因此它在项目的git提交历史中留下了丑陋的意大利面。为此,请运行:

git checkout pr/32; git rebase devel; git checkout devel; git merge --ff-only pr/32
     

然后测试并推动。

     

如果您想将某些提交合并到一个提交中,则可以通过运行git rebase -i devel来使用交互式rebase。一些教程:http://gitready.com/advanced/2009/02/10/squashing-commits-with-rebase.html https://www.atlassian.com/git/tutorials/rewriting-history/git-reflog

     

不幸的是,GitHub不够智能,无法检测到您手动合并PR,因此您需要手动注释并通过指向相关提交的链接关闭该问题。或者,确保合并提交的消息包含Fixed #123

更新: Kahmali Rose进行了进一步更新,使GitHub能够检测到PR已合并,就像点击了邪恶的Merge按钮一样:make sure to rebase and merge instead of cherry-picking

答案 1 :(得分:1)

如果PR只是一次提交,您可以将其选择到主分支(或将PR合并到的任何分支)。所以,例如:

$ git checkout -b branch-for-pr master
$ git pull <fork url> <pr branch name>
$ git checkout master
$ git cherry-pick branch-for-pr

或者,您可以在master之上重新绑定PR分支以允许快进合并(这将跳过合并提交):

$ git checkout -b branch-for-pr master
$ git pull <fork url> <pr branch name>
$ git rebase master
$ git checkout master
$ git merge --ff-only branch-for-pr