因此,在许多软件中,您可以使用鼠标轻松地完成此操作:

尽管非常有用,但它们不再按时间顺序排列。

这么做有什么不对吗?

5

  • 8
    你真的可以通过鼠标移动来重新排序提交吗?哇,这对我来说是新鲜事。无论如何,这只有在这些提交独立时才有效。在这种情况下,我想顺序并不重要。


    – 


  • 1
    是的,例如,您可以在 GitHub Desktop 中执行此操作。docs.github.com/


    – 


  • 9
    给读者的提示:这个问题的答案是肯定的,如果你已经推送了你的分支,而其他人出于同样的原因将其拉下,你不应该重新设置已经推送的提交。所以这个问题最大的警告是,你正在处理你自己的私有树——本地提交历史。


    – 


  • 3
    对于那些不熟悉命令行上的 git 的人来说,这个问题中的屏幕截图是git rebase在幕后进行的。


    – 

  • 有趣的是,下一代 VCS 工具(例如 DARCS 和 Pijul)都是围绕着重新排序是一项基本操作这一理念构建的,因此它们的整个系统都是围绕着能够这样做而构建的。由于答案中提到的原因,这在 Git 中很棘手,但 GitHub 只需单击鼠标即可完成这一事实强烈地表明了未来的发展方向!


    – 


最佳答案
3

提交没有时间顺序。提交有依赖关系。哦,当然,我们按时间顺序进行。但他们不在乎。这里的花哨词是拓扑,但让我们保持简洁。

在一个理智的世界里(当然不是这个世界),保持时间顺序有保持依赖关系的令人愉快的副作用。当需要改变顺序时,你最好知道如何解决这些依赖关系。

CommitC可能依赖于 commitA但不依赖于 commit B。在这种情况下,重新排序ABC可以ACB保持这种依赖关系。但CAB会破坏代码。

重新排序提交本质上是重写代码。确保您理解所写的内容。

此外,这样做也算作一次重新定基。请不要在未告知我的情况下公开重写历史记录。否则我们中的一个人将面临噩梦般的合并。

5

  • 4
    然而,时间顺序历史对于人类来说很重要,因为它可以帮助人们确定谁在什么时候做了什么,而无序的历史,即使作为代码有效,也会让人感到困惑,比简单地使用压缩提交更让人困惑。因此,我不会完全忽视时间顺序历史部分,因为它与使用提交历史顺序来拼凑随时间推移的开发流程有关。


    – 

  • (看着我的蒙克雷拓扑副本;“你听到了吗?你很奇特!”)


    – 


  • 3
    +1。有时我提交了,然后才发现它取决于我未决的更改 – 然后我提交并重新排序,以便将来的二分法不会被破坏。


    – 

  • 3
    @bob:我认为这里有一个时间尺度问题。通过将独立提交移到“几个月”之前来重新排序公共历史将非常令人困惑。对私有开发分支上的提交进行重新排序根本无关紧要,因为没有人见过该分支,而且该分支也只包含几天的提交。没有人关心它的历史记录。如果重新排序意味着更小、更独立的提交,那么每个人都是赢家。


    – 

  • @MatthieuM。我同意你的观点,特别是在你对公共和私人历史进行区分的情况下。我认为这是关键。你说得对,每条规则都有例外,有时你可能需要重新排序提交以使事情不那么混乱。我的观点只是,对于公共历史,按时间顺序进行维护通常很重要,因为它对开发团队有各种重要的用途,因此依赖关系并不是唯一的问题。正如你在评论中提到的,公共/私人区别确实很重要。


    – 


这取决于。

这是一个令人惊讶的深刻问题。乍一看,candied_orange 的答案一针见血,也是我的第一个想法。重新排序提交,如问题所示,只需在程序的 UI 中单击一下按钮即可。这掩盖了重新排序提交是git rebase幕后操作的事实。只要您修改自己的私人历史记录,重新排序提交就没有错。这遵循了重新排序提交的良好做法,并且无论您是压缩提交、重新排序提交还是简单地合并新提交,都无关紧要。一旦您推送了分支,这种情况就会发生变化。

重新排序公共历史

除非你与队友协调,否则不要这样做。

推送您的分支后,其他人可以将其拉下并继续处理,将其分支重新定位到您的分支,或将其合并。以前私密的历史记录现在已公开。任何类型的重新定位操作都会使之前推送的提交孤立,这包括对提交进行重新排序。

重新排序提交将创建新的提交对象。提交的内容将保持不变,但提交 ID 将发生变化,父提交也将发生变化。Git 将提交存储为有,因此更改提交的顺序会修改提交对象的图形树。如果您的队友将您的更改合并到他们的更改中,则重新排序您已推送的提交将给他们带来麻烦,因为他们不再与您的分支共享历史记录。

重新排序私人历史

轻率的回答是这是你的历史,所以就去做吧!谁在乎应用程序是否在某个提交中编译。这是你的私人历史。尽早提交并经常提交。根据你认为合适的方式打破一些东西。请在推送之前修复它。无论如何,在推送之前重新定基并清理你的私人历史是个好主意。

Linus Torvalds 对于重新定基提交提出了一些很好的建议。相关内容如下:

人们可以(可能也应该)重新定位他们的私有树(他们自己的工作)。这是清理。但绝不能重新定位其他人的代码。这是“销毁历史”

来源:Linus Torvalds;2009 年 3 月 29 日;

如果您认为有必要,此“清理”包括重新排序提交。现在,去阅读,了解提交之间的代码依赖关系可能导致麻烦的情况。您可以在中间提交中引入代码,后面的提交需要编译应用程序。将中间提交移到历史记录的后面可能会导致分支中的某些提交无法正常工作。但如果这是私人历史,谁在乎呢?考虑在推送之前重新定基并压缩提交,这可能会合并您之前重新排序的提交,从而使这个问题变得毫无意义。

概括

  • 您是否应该对已推送的提交进行重新排序?不。这会破坏历史记录并使您的队友的工作变得孤立。

  • 您是否应该对尚未推送的提交进行重新排序这取决于您。您可能会破坏应用程序,但话又说回来,您是唯一受苦的人,因此您可以决定这是否“错误”。只需在推送之前清理好混乱局面即可。

4

  • “人们可以(可能也应该)重新定基他们的私有树(他们自己的工作)。这是一种清理。但绝不是其他人的代码。这是一种“破坏历史””,但 Linux 内核仍然使用“补丁系列”作为接受贡献的主要方式。制作和应用补丁系列实际上相当于重新定基。


    – 

  • 2
    @PeterGreen:不同之处在于补丁系列创造了从未与其他开发人员共享的新历史。请阅读我链接到的邮件列表消息中 Linus 的完整回复。它相当冗长,但其中包含许多非常有用的信息。


    – 

  • +1 激励我编辑我的答案。重新定基的首要规则是私下进行。


    – 

  • 2
    在我的团队中,我们的工作协议规定,“功能”分支被视为可进行 rebase 操作,除非分支所有者同意任何相关工作。如果有相关工作,则只有在受影响的开发人员批准的情况下才允许进行 rebase(并且,如果导致问题,则隐含地需要所有者的帮助)。


    – 

我认为对于项目历史的意义存在不同的看法。

  1. 发展过程的历史。谁做了什么,按照什么顺序。
  2. “主存储库”的历史,这个项目一周前是什么样子的?一年前?昨晚?
  3. 一组逻辑步骤将我们从 A 带到 B。

这些观点有些相互冲突,而 VCS 系统的选择也会产生影响。集中式 VCS 系统往往更适合 2,而分布式版本控制系统(尤其是 git)更倾向于 1。

在 git 中重新排序提交是一种“变基”的形式。变基通常用于替换真正混乱的历史记录,使用一组更合乎逻辑的步骤将我们从旧状态带到新状态。它将历史记录的焦点更多地放在 3 上,而不是 1 上。

我认为“仅仅”重新排序是非常罕见/奇怪的,我希望重新排序能够与清理一些提交、挤压其他提交甚至完全删除一些提交相结合。

除了历史的美观性之外,还要记住 git 最初设计为“仅附加”。重新定位分支实际上会创建新的提交,尤其是重新定位其他人在其上构建工作的分支可能会导致可怕的混乱。一旦提交被推送到广泛共享/协作的分支,您可能不应该重新定位它。

另一方面,重新定位您未与任何人共享的私人开发分支通常是可以的,而且通常受到鼓励。如果错误从未在开发人员的计算机上留下任何人的历史记录,通常没有什么帮助。

中间部分是诸如主题/功能分支之类的内容。在合并这些分支之前对其进行变基可以使主分支的历史记录更加清晰,也更容易跟踪(特别是如果主题/功能分支包含大量“反向合并”),但这意味着任何关注主题/功能分支开发的人都必须采取手动步骤来协调他们的历史记录。