对于github pull请求,只能压缩到一个“正确的”提交

我在github上有一个回购,其他人(Bob,为了争辩)已经发出了pull request。 他的代码不完美,所以我们经历了几轮加价。 据我所知,他承诺并推动每一组标记变化的拉动请求。

所以我的仓库看起来像这样:

master: ---o A (Chowlett | | pull-req: o---o---o---o BCD (all Bob) 

提交SHA和消息如下:

A:

 123456 Good commit <chowlett> 

B:

 777ccc Fix the widget bug <bob> 

C:

 888ddd Review markups <bob> 

d:

 999eee Further markups <bob> 

我现在很高兴接受这个拉动要求。 但我宁愿预标记版本不在我的回购。 我可以达到以下所有条件吗? 如何?

  • 将B,C&D合并到我的回购中作为一个单独的提交
  • 生成“合并请求#99 …”提交
  • 让github自动closurespull请求

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

请参阅“ 压缩提交 ”及其新文档

这是一个新的选项,可以让你强制对通过合并button合并的所有请求进行压缩。

https://help.github.com/assetshttp://img.dovov.comhelp/pull_requests/squash-and-merge.png

git有两个“squash”函数。 git merge --squashgit rebase --interactive git merge --squashsquash动作。 前者不保留任何作者或date信息,仅收集从一系列提交到本地工作副本的所有更改。 后者是烦人的,因为它需要互动。

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

把这个和hubghi一起扔,你可以根据这些线构build一个脚本:

 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 

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

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

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

不利的一面是,你的主人的历史不会把这个提交显示为从他的分支合并。 它会看起来像你自己做的工作,不给鲍勃信用。

使用git rebase

一个想法是检查分支,并使用iteractive rebase将所有提交压缩成一个,然后强制推送更新pull请求并合并(尽pipe这部分工作可以委托给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环境variables,用来为rebase提交列表设置一个临时编辑器。 我们将它设置为一个内联脚本,它将除了第一个(即sed模式中的2,\$ )之外的所有行的开始处replace为由s (表示squash )的单词。 传递给脚本的提交列表是一个简单的文本文件。 Git然后继续rebase,让你编辑最后的提交信息。

另外,使用git钩子,你可以或多或less地轻松地编辑这个最后的消息,以满足你的需要(比如在压扁的提交消息之间添加一个可视化的分隔符)。

使用git merge –squash

压缩也可以通过git merge --squash 。 这里请看这两种方法的区别。 下面的脚本将使用merge命令将分支的提交压缩为单个提交。 它也创build分支的备份(以防万一)。

 MAINBRANCH="master" CURRENT_BRANCH=$(git rev-parse --abbrev-ref HEAD) # update current feature branch with master git pull origin $MAINBRANCH # delete existing backup git branch -D "$CURRENT_BRANCH-backup" # backup current feature branch and go back git checkout -b "$CURRENT_BRANCH-backup" && git checkout - # checkout and update master branch git checkout $MAINBRANCH && git pull # create new branch from master git checkout -b "$CURRENT_BRANCH-squashed" # set it to track the corresponding feature branch git branch "$CURRENT_BRANCH-squashed" --set-upstream-to "$CURRENT_BRANCH" # merge and squash the feature branch into the one created git merge --squash $CURRENT_BRANCH # commit the squashed changes git commit # force push to the corresponding feature branch git push -f . HEAD:$CURRENT_BRANCH # checkout the feature branch git checkout $CURRENT_BRANCH # delete the squashed copy git branch -D "$CURRENT_BRANCH-squashed" 

这为我解决了。

  • 我在devtools_import_export工作保持不变。
  • 我的issue35squashed上游/主的拉请求只有一个提交。
  • 唉,合并不logging,但提交消息有所有细节。

这是我实际做了什么(请参阅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并且它的pull请求包含devtools_import_export中的所有单个提交,不行。)