如何修复GitHub拉取请求中的提交顺序,由git rebase打破?

时间:2017-06-22 16:08:25

标签: git github rebase

当我编写代码时,我将其分解为易于快速查看的小型逻辑更改。

为此,我使用git rebase -i(交互式)来压缩,删除和更改提交顺序。

我注意到这有时会导致GitHub拉取请求的提交顺序不同(尽管订单保留在远程分支上)。

例如,

  • commit 1
  • commit 2
  • commit 3

可能会在PR中显示为:

  • commit 3
  • commit 1
  • commit 2

我搜索了互联网,但却找到了这个GitHub帮助页面:Why are my commits in the wrong order?他们的回答:

  

如果您通过git rebase或强制推送重写提交历史记录,那么   打开时可能会注意到您的提交顺序无序   拉请求。

     

GitHub强调Pull Requests是一个讨论的空间。各方面   它的注释,引用和提交 - 用a表示   按时间顺序排列。重写你的Git提交历史while performing rebases会改变时空连续体,这意味着   提交可能无法按照您期望的方式表示   GitHub界面。

     

如果您总是希望按顺序查看提交,我们建议您不要使用   git rebase。但是,请放心,当你没有任何事情被打破   看看时间顺序之外的东西!

有办法解决这个问题吗?

6 个答案:

答案 0 :(得分:13)

我设法解决了这个问题:

  1. 找到保留订单的最后一次提交
  2. 运行git rebase -i <hash of that commit>
  3. 将所有pick替换为reword
  4. 运行git push -f
  5. 在此之前,我尝试仅更改第一个提交消息,该消息也会更改以下所有哈希值,但是没有修复它。

    我必须为之后的每一次提交都这样做才能发挥作用。

答案 1 :(得分:6)

要自动化Eliad建议我使用Piotr中的脚本:

git rebase "$(git merge-base HEAD master)" --ignore-date -x 'git commit --amend -C HEAD --date="$(date -R)" && sleep 1.05'

答案 2 :(得分:2)

您可能不必再进行任何修复(2020年7月,三年后)

请参阅:

Pull request commits now ordered chronologically

我们正在更改拉取请求时间轴和提交视图中提交排序的方式。

当前按作者日期对提交进行排序,这可能会导致提交在某些情况下(例如在重新定基后)显示为乱序

通过此更改,提交将按照其在head分支中的时间顺序进行排序,这与Git中的顺序一致

此顺序还反映在GraphQL中的List commits on a pull request REST API和PullRequest对象的时间轴连接中。

详细了解pull requests

答案 3 :(得分:0)

  

如何通过git rebase破坏GitHub拉取请求中的提交顺序?

这可以通过(仍在讨论中)2019 git evolve command完成:

  

客观

     

创建“ evolve”命令以帮助用户制作高质量的提交历史记录。

     

用户可以一次以任何顺序改进一次提交,然后运行git evolve   重写他们的最近历史以确保所有内容都是最新的。
  我们会在变更图中跟踪对一段时间内提交的修订。用户可以共享他们的   通过使用标准推送交换他们的变更图来与他人一起进步,   提取和格式化补丁命令。

     

状态

     

该提案尚未实施。

     

背景

     

想象一下,您要进行三个连续的更改以供审核,您会收到反馈   需要编辑所有三个更改。
  稍后我们将正式定义“更改”一词,但现在我们说,更改是一个进行中的工作,其最终版本将在将来作为提交提交。

     

虽然您正在编辑一项更改,但更多的反馈来自其他更改。
  你做什么?

     

evolve命令是使用以下提交链的便捷方法:   正在审核中。
  每当您对提交进行基础更改或修改时,存储库都会记住旧的提交已过时,并已由新的提交替换。

     

然后,在将来的某个时候,您可以运行“ git evolve”,正确的重新排列顺序将以正确的顺序发生,从而使任何提交都不会过时   父母。

     

使“ evolve”命令起作用的一部分涉及跟踪对提交的编辑   随着时间的流逝,这就是为什么我们需要一个变化图。
  但是,更改图还将带来其他好处:

     
      
  • 用户可以直接查看更改的历史记录(修改顺序和   对其经历的基础进行重新定位,与它所在的分支的历史正交)。
  •   
  • 可以快速找到并列出用户的所有更改   目前正在进行中。
  •   
  • 它可以用作组合或拆分的其他高级命令的一部分   变化。
  •   
  • 它可用于装饰提交(在git loggitk等中)   过时或只是正在进行中的工作的提示。
  •   
  • 通过推动和拉动变更图,用户可以进行更多协作   轻松进行更改。
      这比推动和拉动   更改自身,因为更改图可用于查找更多   特定的合并基础,以便更好地合并不同版本的   同样的变化。
  •   
  • 它可以用来正确地为本地更改和其他本地分支建立基础   运行git-filter-branch之后。
  •   
  • 它可以代替gerrit使用的change-id页脚。
  •   

答案 4 :(得分:0)

我提议这样的~/.gitconfig别名:

[alias]                                                                            
    rewrite = rebase -x 'git commit --amend -C HEAD --date=\"$(date -R)\" && sleep 1.05'

完成常规的rebase -i master修复工作后,您只需执行git rewrite master即可按照GitHub提交顺序对其进行修复。它将基于旧的提交每秒创建一个新的提交。通过覆盖--date,它将迫使GitHub保持正确的顺序。

答案 5 :(得分:-1)

rebase的--ignore-date选项可用于重置提交者的提交日期。这将修复github上提交的顺序。

通过强制推送,您甚至可以将提交顺序固定在现有的拉取请求上。

例如:

  1. git checkout my_pull_request_branch
  2. git rebase --ignore-date origin/master
  3. git push -f origin my_pull_request_branch