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

我想根据评审意见更新代码,并重新提交。做这件事的最佳工作流程是什么?从我有限的git/github知识,我可以做以下任何一个:

Update the code as a new commit, and add both the initial and updated commit to my pull request. Somehow (??) rollback the old commit from my repository, and create a single new commit containing everything, then raise a pull request for that? git commit has an amend feature, but I've heard that you shouldn't use it after you've pushed the commit outside of your local repository? In this case I have made the change on my local PC and pushed to my github branch of the project. Would this be OK to use 'amend'? Something else?

看起来选项2/3会很好,因为开源项目在他们的历史中只有一次提交,它将实现所有的东西,但我不确定如何做到这一点。

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


只需添加一个新的提交到拉请求中使用的分支,并将分支推到GitHub。pull请求将随着额外的提交而自动更新。

第二条和第三条是不必要的。如果人们只想看到你的分支被合并到哪里(而不是额外的提交),他们可以使用git log——first-parent来只查看日志中的合并提交。


更新一个拉请求

要更新一个拉请求(第1点),你唯一需要做的就是签出拉请求来自的同一个分支,并再次推到它:

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

可选-清理提交历史记录

您可能会被要求将提交压缩在一起,以便存储库历史记录干净,或者您自己想要删除中间提交,它会分散您的pull请求中的“消息”(第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 

这将提示你选择如何重写你的pull请求的历史,下面将在你的编辑器中:

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

对于任何你想要成为前一个提交更改的一部分的提交,选择squash:

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

并且您的pull请求将包含一个单独的提交,将之前分裂为几个提交的所有更改合并在一起。

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

重写历史记录并在其他人可能已经克隆的分支上使用git push -f是一件坏事——它会导致存储库的历史和签出的历史背离。

然而,修改你的分支的历史以纠正你提议集成到存储库中的更改是一件好事。因此,毫无保留地挤压“噪音”从你的拉请求。

关于分支的说明

在上面我展示的pull请求来自于你的fork的主分支,这没有什么问题,但它确实产生了一定的限制,比如,如果这是你的标准技术,每个存储库只能打开一个PR。不过,为你想要提出的每个单独的更改创建一个分支是个更好的主意:

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