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


340

我已向Github上的一个开源项目提交了更改,并收到了一位核心团队成员的代码审查意见。

我想在考虑评论意见的情况下更新代码,然后重新提交。最佳的工作流程是什么?根据我对git / github的有限了解,我可以执行以下任一操作:

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

  2. 以某种方式(??)从我的存储库回滚旧提交,并创建一个包含所有内容的新提交,然后对此提出一个拉取请求?

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

  4. 还有吗

选项2/3似乎不错,因为开放源代码项目在其历史记录中只有一次提交可以实现所有内容,但是我不确定如何做到这一点。

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

Answers:


219

只需向pull请求中使用的分支添加新提交,然后将该分支推送到GitHub。拉取请求将通过其他提交自动更新。

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


7
master也是一个分支,所以从技术上讲它并不重要:)

10
@OrionEdwards-正如戳所提到的,master是一个分支,因此,对其进行更新将导致所有基于它的拉取请求也将被更新。(这是对计划提交请求的任何内容使用单独分支的一个很好的理由。)
琥珀色

18
由于代码仍在审查中,通常最好修复提交而不是引入只会使历史混乱的附加修复提交……
mgalgs 2013年

4
@mgalgs这是一个优先事项。
2013年

4
我不喜欢这个答案,因为我在刚刚写的博客中解释了原因; 我相信其他答案会更好。
亚当·斯皮尔斯

223

更新请求请求

要更新拉取请求(第1点),您唯一需要做的就是签出拉取请求所来自的同一分支,然后再次将其推入:

cd /my/fork
git checkout master
...
git commit -va -m "Correcting for PR comments"
git push

可选-清洁提交历史记录

可能会要求您将提交压缩在一起,以使存储库历史记录整洁,或者您自己想删除中间的提交,这些提交会分散您的拉取请求中的“消息”(第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

压缩在一起是一个好主意,这样它们就可以显示为单个提交:

$ git rebase -i parent/master 

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

pick 58ae094 fixing actual problem
pick fb30112 correct typos
pick eccaa56 code standard fixes
pick e4e32b8 add test case as per PR comments

对于您想成为上一次提交的一部分的任何提交,请更改为壁球:

pick 58ae094 fixing actual problem
squash fb30112 correct typos
squash eccaa56 code standard fixes
squash e4e32b8 add test case as per PR comments

并关闭您的编辑器。然后,Git将重写历史记录,并提示您提供一个合并提交的提交消息。相应地进行修改,您的提交历史现在将很简洁:

$ git log --oneline parent/master..master
9de3202 fixing actual problem

将其推入叉子:

$ 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

并且您的拉取请求将包含一个提交,其中包含以前拆分为多个提交的所有更改。

更改公共回购记录的历史是一件坏事

重写历史记录并git push -f在可能已被其他人克隆的分支上使用是不好的一件事-它导致存储库的历史记录和结帐的历史记录不一致。

但是,修改您的叉子来纠正你的改变的历史提议被整合到一个存储库-是一件好事。因此,没有保留会在您的拉取请求中消除“噪音”。

关于分支的说明

在上面的示例中,我将拉取请求显示为来自master分支的分支,这并没有错,但确实会造成某些限制,例如,如果这是您的标准技术,则每个存储库只能打开一个PR 。不过,最好为要提出的每个更改创建一个分支:

$ git branch feature/new-widgets
$ git checkout feature/new-widgets
...
Hack hack hack
...
$ git push
# Now create PR from feature/new-widgets

28
+1表示如何清理提交而不是推送其他修正提交。
mgalgs

3
我在挑选/压榨时遇到了一些问题,这个答案帮助了我。还注意到Github在我删除之后删除了先前的对话git push -f。没有太多评论,但这是我没想到的。
Hitesh 2013年

5
需要明确的是,在改组以拥有清晰的历史记录时,您实际上是在更改公共承诺,只是假设没人在乎,因为这是一个分支。
brita_

2
后续:最佳实践,即在PR期间更改主控?
凯文·索特尔

1
考虑到已审核(或通常有评论/引用代码的)拉取请求的重写历史记录可能会导致混乱,因为历史记录不再与注释所指的内容匹配。没有简单的解决方案:有人将关闭PR并将其引用到新的PR中(以不重写历史记录)。我的想法是仅在执行强制推送之后,备份正在重置/重写的最新提交SHA,并在PR的注释中引用它。如果 prune不删除该分离的提交,则其历史记录仍将与PR的注释匹配。
卡马菲瑟
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.