用于在代码审查后更新拉取请求的首选Github工作流程

Ori*_*rds 333 git version-control github pull-request

我已经在Github上提交了对开源项目的更改,并收到了其中一个核心团队成员的代码审查意见.

我想考虑审核评论更新代码,然后重新提交.这样做的最佳工作流程是什么?根据我对git/github的有限知识,我可以做以下任何一项:

  1. 将代码更新为新提交,并将初始和更新的提交添加到我的pull请求中.

  2. 不知怎的(??)从我的存储库回滚旧的提交,并创建一个包含所有内容的新提交,然后为此提出拉取请求?

  3. git commit有一个修改功能,但我听说你在本地存储库之外推送提交后不应该使用它?在这种情况下,我在我的本地PC上进行了更改并推送到我的项目的github分支.这可以使用'修改'吗?

  4. 别的什么?

看起来选项2/3会很好,因为开源项目在他们的历史中只有一个提交将实现一切,但我不知道如何做到这一点.

注意:我不知道这是否会影响答案,但我没有在单独的分支中进行更改,我只是在master之上做了一次提交

AD7*_*six 218

更新拉取请求

要更新拉取请求(第1点),您唯一需要做的就是检查拉取请求来自的同一分支并再次推送到它:

cd /my/fork
git checkout master
...
git commit -va -m "Correcting for PR comments"
git push
Run Code Online (Sandbox Code Playgroud)

可选 - 清除提交历史记录

可能会要求您将提交压缩在一起,以便存储库历史记录清晰,或者您自己想要删除中间提交,这些提交会分散您拉取请求中的"消息"(第2点).例如,如果您的提交历史记录如下所示:

$ git remote add parent git@github.com:other-user/project.git
$ git fetch parent
$ git log --oneline parent/master..master
e4e32b8 add test case as per PR comments
eccaa56 code standard fixes as per PR comments
fb30112 correct typos and fatal error
58ae094 fixing problem
Run Code Online (Sandbox Code Playgroud)

将事物压缩在一起是个好主意,因此它们只显示为一次提交:

$ git rebase -i parent/master 
Run Code Online (Sandbox Code Playgroud)

这将提示您选择如何重写拉取请求的历史记录,以下内容将在您的编辑器中:

pick 58ae094 fixing actual problem
pick fb30112 correct typos
pick eccaa56 code standard fixes
pick e4e32b8 add test case as per PR comments
Run Code Online (Sandbox Code Playgroud)

对于任何提交,您希望成为之前提交的一部分 - 更改选择以进行压缩:

pick 58ae094 fixing actual problem
squash fb30112 correct typos
squash eccaa56 code standard fixes
squash e4e32b8 add test case as per PR comments
Run Code Online (Sandbox Code Playgroud)

并关闭你的编辑器.然后,Git将重写历史记录并提示您为一个组合提交提供提交消息.相应修改,您的提交历史现在将简明扼要:

$ git log --oneline parent/master..master
9de3202 fixing actual problem
Run Code Online (Sandbox Code Playgroud)

把它推到你的前叉:

$ git push -f
Counting objects: 19, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (5/5), done.
Writing objects: 100% (11/11), 978 bytes, done.
Total 11 (delta 9), reused 7 (delta 6)
To git@github.com:me/my-fork.git
   f1238d0..9de3202  HEAD -> master
Run Code Online (Sandbox Code Playgroud)

并且您的pull请求将包含一个提交,其中包含先前拆分为多个提交的所有更改.

改变公共回购的历史是件坏事

重写历史记录并git push -f在可能已经克隆其他人的分支上使用是一件坏事 - 它会导致存储库的历史记录和结帐的历史记录发生分歧.

但是,修改fork的历史记录以纠正您建议集成到存储库中的更改- 这是一件好事.因此,毫无保留地压低你的拉动请求中的"噪音".

关于分支的说明

在上面我将pull请求显示为来自masterfork 的分支,这没有什么不妥,但它确实会产生某些限制,例如,如果这是您的标准技术,只能在每个存储库中打开一个PR .虽然为您希望提出的每个单独的更改创建一个分支,但这是一个更好的主意:

$ git branch feature/new-widgets
$ git checkout feature/new-widgets
...
Hack hack hack
...
$ git push
# Now create PR from feature/new-widgets
Run Code Online (Sandbox Code Playgroud)

  • +1提及如何清理提交而不是推送额外的fixup提交. (28认同)
  • 为了清楚起见,当你重新定位一个干净的历史时,你确实在改变你的公共提交,你只是假设没有人关心因为它是一个分支. (5认同)
  • 我在挑选/挤压时遇到了一些问题,[这个答案](http://stackoverflow.com/a/2568581)帮助了我.还注意到Github在我做了`git push -f`之后删除了之前的对话.没有太多评论,但这是我没想到的. (3认同)
  • 考虑重写已审查的拉取请求的历史记录(或通常对/引用代码进行评论)可能会导致混淆,因为历史记录将不再匹配评论所指的内容。没有简单的解决方案:有人会关闭 PR 并在新的 PR 中引用它(而不是重写历史);我的想法是只备份正在重置/重写的最新提交 SHA,并在执行强制推送后在 PR 的评论中引用它。**IF** `prune` 不会删除那个分离的提交,那么它的历史记录仍然会匹配 PR 的评论。 (3认同)
  • 跟进:在PR期间主人改变时的最佳做法? (2认同)

Amb*_*ber 214

只需向pull请求中使用的分支添加新提交,然后将分支推送到GitHub.拉取请求将自动使用附加提交进行更新.

#2和#3是不必要的.如果人们只想查看合并分支的位置(而不是其他提交),则可以使用它们git log --first-parent仅查看日志中的合并提交.

  • 由于代码仍处于*review*中,通常更好的方法是修复提交,而不是引入额外的修复提交,这些提交只会使历史变得混乱...... (18认同)
  • @OrionEdwards - 正如poke所提到的,master是一个分支,因此,更新它将导致任何基于它的pull请求也被更新.(对于您计划提交拉取请求的任何内容,这是一个很好的理由使用单独的分支.) (10认同)
  • `master`也是一个分支,所以在技术上它没关系:) (7认同)
  • @mgalgs这是一个偏好问题. (4认同)
  • 我不喜欢这个答案,因为[我刚写的博客文章]中解释的原因(http://blog.adamspiers.org/2015/03/24/why-and-how-to-correctly-amend-github-拉请求/); 我相信[另一个答案](http://stackoverflow.com/a/15055649/179332)要好得多. (4认同)
  • @Amber - 啊,它解释了我所做的最后2次拉取请求的行为(他们被卷入一个请求,我无法弄清楚为什么),因为他们都在掌握 (2认同)
  • imho做一个额外的提交有助于看到先前和当前补丁之间的变化,修复提交更简单,我同意Amber这是一个偏好的问题.无关评论:Gerrit审核允许您查看修补程序之间的更改,因此您可以随时修改提交并推送修复补丁程序的建议修补程序,并仍然能够看到2个修补程序版本之间的差异. (2认同)

Cla*_*ges 5

我对最佳实践的看法:一旦你准备打包拉取请求,它应该在一开始就得到它自己独特的主题分支,特别是为此目的.首先将该分支推送到您的github存储库,例如

git push origin name-of-pull-request-branch
Run Code Online (Sandbox Code Playgroud)

并将拉取请求基于该分支.完成此操作后,您推送到该分支的任何提交都将自动附加到pull请求中.你只使用那个分支.

有些人更喜欢用你的github userid命名这样的分支.通过这种方式,他们可以在当地免费查看,以便尝试一下

  • 减少对分支名称冲突的恐惧
  • 更容易记住它是什么

我通常将我的拉请求分支命名为

claybridges-do-the-things
Run Code Online (Sandbox Code Playgroud)