【问题标题】:Fixing git double-commit history修复 git 双重提交历史
【发布时间】:2014-04-02 16:19:14
【问题描述】:

前几天我不得不跑git filter-branch。我按照on github 的说明进行操作,但出了点问题。我认为团队中的某个人没有在本地分支上运行 rebase,而是合并了更改。从那以后,提交日志中充满了双重提交,例如:

commit b0c03ec925c0b97150594a99861d8f21fd3ab22d
Author: XXX
Date:   Wed Mar 19 17:01:52 2014 -0400

    Removed most clearfixs in templates

commit f30c21d21b5ea715a99b0844793cb4b5f5df97a1
Author: XXX
Date:   Wed Mar 19 17:01:52 2014 -0400

    Removed most clearfixs in templates

commit 2346be43d0e02d3987331f0a9eeb2f12cd698ede
Author: XXX
Date:   Wed Mar 19 16:40:26 2014 -0400

    new redirect logic

commit 1383070b31bde1aaa9eda7c2a9bcb598dd72247b
Merge: d1e2eb6 94e07fe
Author: XXX
Date:   Wed Mar 19 16:28:41 2014 -0400

    Merge branch 'develop' of github.com:xxx/xxx into develop

commit 79ce7824688cf2a71efd9ff82e3c7a71d53af229
Merge: 6079061 1ed3967
Author: XXX
Date:   Wed Mar 19 16:28:41 2014 -0400

    Merge branch 'develop' of github.com:xxx/xxx into develop

commit d1e2eb645a4fe2a1b3986082d0409b4075a0dbc9
Author: XXX
Date:   Wed Mar 19 16:28:36 2014 -0400

    Fixed broken responsiveness for companies listing page and code refactoring.

commit 6079061f6ef1f856f94d92bc0fdacf18854b8a89
Author: XXX
Date:   Wed Mar 19 16:28:36 2014 -0400

    Fixed broken responsiveness for companies listing page and code refactoring.

奇怪的是,并不是所有的提交都是加倍的,比如上面的“新重定向逻辑”。我能做些什么来解决这个问题吗?这是相对良性的,但现在我们的提交历史看起来像废话。这个SO post 建议保持原样,但为了后代,我宁愿有一个干净的提交历史。

【问题讨论】:

    标签: git github git-filter-branch


    【解决方案1】:

    完成此操作的命令是:

    git rebase -i HEAD~7
    

    这将打开你的编辑器,如下所示:

    pick f392171 Removed most clearfixs in templates
    pick ba9dd9a Removed most clearfixs in templates
    pick df71a27 Unew redirect logic
    pick 79ce782 Merge branch 'develop' of github.com:xxx/xxx into develop
    pick 1383070 Merge branch 'develop' of github.com:xxx/xxx into develop
    ...
    

    现在您可以告诉 git 如何处理每个提交。让我们保留提交 f392171,这是我们添加功能的地方。我们会将以下两个提交压缩到第一个提交中——留下一个干净的提交。

    把你的文件改成这样:

    pick f392171 Removed most clearfixs in templates
    squash ba9dd9a Removed most clearfixs in templates
    pick df71a27 Unew redirect logic
    pick 79ce782 Merge branch 'develop' of github.com:xxx/xxx into develop
    squash 1383070 Merge branch 'develop' of github.com:xxx/xxx into develop
    

    当您保存并退出编辑器时,Git 会应用所有两个更改,然后将您放回编辑器以合并三个提交消息:

    # This is a combination of  commits.
    # The first commit's message is:
    Removed most clearfixs in templates
    
    # This is the 2nd commit message:
    
    Removed most clearfixs in templates
    

    完成后,保存并退出编辑器。 Git 现在会将提交压缩为一个。全部完成!

    那你必须做

    git push origin your-branch -f
    

    强制您在本地提交更改到远程分支。

    注意:您必须对每个重复的提交进行 squash。

    【讨论】:

    • 当我运行这个时,重复的提交并不相邻。例如对于Removed most clearfixs in templates,一个在 4512 行,另一个在 6683。有没有办法解决这个问题?我还担心会出现这样的情况,即我们有两个提交的消息相同但内容不同,在这种情况下我们不想压缩。有没有办法检查这个?
    • 我不明白你的第一个问题...你能详细解释一下吗?否则,要重命名提交,您必须使用“编辑”而不是 squash,保存文件,然后 git commit --amend。这将打开一个编辑器,您必须使用提交的新名称保存文件。
    • 关于第一个问题,虽然git log 显示双重提交彼此相邻,但此 rebase 命令生成的日志文件不会 - 它们将位于非常不同的位置日志文件。对于第二个问题,在历史进程中,我们已经提交了具有相同消息的非常不同的更改 - 例如合并提交通常会有相同的消息。我对重命名这些并不感兴趣,而是检查哪些是多余的。有没有办法在日志文件中显示更改摘要?
    • 我想到的是,您可以先更改提交顺序,以收集那些想要做壁球的人。要更改顺序,您只需在打开git rebase -i 的文件中交换提交的行。另一方面,要查看提交是否相等,我会使用gitg 工具来检查具有相同名称的提交并验证这些提交是否具有相同的更改。不知道有没有什么工具可以自动比较。
    【解决方案2】:

    @VAIRIX 的回答是完美的,但在某些复杂的情况下,重复提交不会彼此相邻,因此压缩无济于事。

    所以取下面的历史,(假设 a~ 是 a 的重复)

     # h
     # g
     # f
     # c~
     # b~
     # a~
     # e
     # d
     # c
     # b
     # a
    

    要遵循的命令:(如@VAIRIX 或下面的回答中所述,如果您想与主人一起变基) git rebase master -i (最好关注git rebase -i HEAD~n 以避免变基头痛)

    现在! 1)压缩重复提交如下:

     pick h
     pick g
     pick f
     pick c~
     s b~
     s a~
     pick e
     pick d
     pick c
     pick b
     pick a
    

    现在,这将压缩你在 c 中的提交

     # h
     # g
     # f
     # c~ (having changes of a~ and b~)
     # e
     # d
     # c
     # b
     # a
    

    在我的例子中,c~ 是 c 的反提交,所以我只需要再次执行该过程,但现在我不再使用 s 挤压,而是使用 d 放弃提交

     pick h
     pick g
     pick f
     d c~ (having changes of a~ and b~)
     pick e
     pick d
     pick c
     pick b
     pick a
    

    现在,您的历史记录将删除所有重复的提交。现在,您可以与使用 git diff 的原始分支进行比较,该分支对您的此分支有重复提交。如果你做得很好,就不应该有任何差异。

    这个过程可能看起来有点长,但你确信你没有错过任何提交。

    【讨论】:

    • 您的用户名也为 +1 :D。是的,应该非常小心地选择 squash 和 drop,并使用提交的数量来开始 squash。 HEAD~10 或类似的东西。
    猜你喜欢
    • 1970-01-01
    • 2011-01-19
    • 2021-04-25
    • 1970-01-01
    • 2017-09-11
    • 1970-01-01
    • 2014-09-13
    • 2016-01-04
    • 2015-09-02
    相关资源
    最近更新 更多