为github pull请求只压缩一次“正确”提交

时间:2012-07-09 13:31:22

标签: git github pull-request

我在github上有一个回购,其他人(Bob,为了争论)发出了拉取请求。他的代码并不完美,所以我们经历了几轮标记。据我了解,他承诺并推动他对每组标记变更的拉动请求。

所以我的存储库现在看起来像这样:

master: ---o A (Chowlett
           |
           |
pull-req:  o---o---o---o
               B   C   D (all Bob)

提交SHAs和消息如下:

A:

123456 Good commit <chowlett>

B:

777ccc Fix the widget bug <bob>

C:

888ddd Review markups <bob>

d

999eee Further markups <bob>

我现在很高兴接受这个拉动请求;但我宁愿预标记版本不在我的回购中。我可以实现以下所有目标吗?怎么样?

  • 合并B,C&amp; D作为单一提交进入我的回购
  • 同时生成“合并拉取请求#99到...”提交
  • 让github自动关闭拉取请求

5 个答案:

答案 0 :(得分:17)

请注意,Bob在制作GitHub PR时不必压缩他的提交 自2016年3月起,您可以将该操作留给维护者(您)接受您的PR。

请参阅“Squash your commits”及其new documentation

  

这是一个新选项,可让您强制提交压缩通过合并按钮合并的所有拉取请求。

https://help.github.com/assets/images/help/pull_requests/squash-and-merge.png

答案 1 :(得分:10)

git内置了两个“壁球”功能。在git merge --squash中有squash git rebase --interactive次操作。前者不保留任何作者或日期信息,只是将一系列提交中的所有更改收集到本地工作副本中。后者很烦人,因为它需要互动。

git squash extension做你想要的。它将当前HEAD重新绑定到指定的基础上,同时自动压缩其间的提交。它还提供了一个命令行选项,用于在rebase不会产生冲突的情况下在最终压缩的提交上设置消息。

hubghi一起投放,您可以沿着以下几行构建脚本:

git pull upstream master
hub checkout https://github.com/$user/$repo/pull/$issue
git squash master
rev=$(git rev-parse --short HEAD)
git checkout master
git merge $rev
git commit --amend "Merged pull request #$issue"
git push upstream master
ghi close $issue $user/$repo
ghi comment $issue "Merged as $rev" $user/$repo 

答案 2 :(得分:9)

您可以使用--squash选项进行合并

git merge <remote url> <remote branch> --squash

但是这不会产生合并提交。它将生成一组正常的工作树更改,就像您手动将所有更改应用于副本一样。然后你会像平常那样提交。

缺点是您在master上的历史记录不会将此提交显示为来自其分支的合并。它看起来就像你自己完成了这项工作,并没有给予鲍勃的信任。

答案 3 :(得分:2)

使用git rebase

一个想法是检查分支并使用iteractive rebase将所有提交压缩为一个,然后强制push更新pull请求并合并(尽管这部分工作可以委托给Bob)。

要自动将所有提交从分支压缩到第一个提交并将其应用于提取请求,您可以使用以下命令:

$ git checkout pull-req
$ GIT_SEQUENCE_EDITOR='sed -i "2,\$s/^pick/s/g" $1' git rebase -i origin/master
$ git push --force

GIT_SEQUENCE_EDITOR是一个Git环境变量,用于为rebase提交列表设置临时编辑器。我们将其设置为内联脚本,将pick替换为s(意思是squash),除了第一行(即2,\$之外的所有行的开头{1}}模式)。传递给脚本的提交列表是一个简单的文本文件。然后Git继续使用rebase并允许您编辑最终的提交消息。

此外,使用git hook,您可以或多或少地轻松编辑此最终消息以满足您的需求(例如在压缩的提交消息之间添加可视分隔符)。

使用git merge --squash

通过sed也可以进行压扁。有关两种方法之间的区别,请参阅here。下面的脚本会使用merge命令将分支的提交压缩成单个提交。它还会创建分支的备份(以防万一)。

git merge --squash

答案 4 :(得分:1)

这对我有用。

  • 我对devtools_import_export的工作保持不变。
  • 我对issue35squashed对上游/主人的拉取请求只有一次提交。
  • 唉,合并没有记录,但提交消息包含所有细节。

这是我实际做的(见https://github.com/anaran/devtools-snippets/network

git checkout master
git status # all clean
git checkout -B issue35squashed master
git merge --squash devtools_import_export
git status # looks good
git commit # review and commit via emacs
git log --graph --abbrev-commit --stat --pretty --decorate=full --branches
git push --all -v

(我之前使用git merge --no-ff ...的尝试位于issue35take2,并且对它的拉取请求包含devtools_import_export的所有单独提交。不好。)