[关闭]
@runzhliu 2018-07-17T06:00:23.000000Z 字数 3091 阅读 818

Git 如何压缩 commit

git commit


今天同事突然问我,由于在给老大的开源项目提 pr 的时候,自己比较长时间没有 rebase 的老大的项目 master 分支了,而自己提交的 commit 又很多,有些 commit 又是实验性质的,乱七八糟的(其实就是没有用熟 git......),还有不少和老大的代码冲突了。提交代码的时候,老大要求精简一下 commit 否则其他人在看项目的演进的时候会一头雾水的。

我认为老大说的是对的,当然也存在一个问题就是同事没有用熟 git,因为在我们在版本管理的时候,其实每个 commit 都是有一定意义的,commit 不应该成为实验性质的一个动作。

回到老大的问题,「精简一下 commit」,那么好几个 commit 如何进行压缩呢?当然是有办法的。

下图是为了演示所提交的三个 commit

  1. * commit c4bf6724a039b524edeca2489086fbed0c4b5a0d
  2. | Author: Oscar <runzhliu@163.com>
  3. | Date: Mon Jun 11 11:02:33 2018 +0800
  4. |
  5. | [add] third commit
  6. |
  7. * commit a7e9aa4654e7f7d99ba530211e056a55314a3fff
  8. | Author: Oscar <runzhliu@163.com>
  9. | Date: Mon Jun 11 11:01:35 2018 +0800
  10. |
  11. | [add] second commit
  12. |
  13. * commit 0350222da791e26d07a4e77060709700cb48608d
  14. Author: Oscar <runzhliu@163.com>
  15. Date: Mon Jun 11 11:01:17 2018 +0800
  16. [add] first commit

可以利用 git rebase 来实现本文所说的压缩 commit-i 是代表 let the user edit the list of commits to rebase,这是在 git rebase -h 抄过来的,所以为什么是 -i 呢?就是因为我们需要编辑之前提交过的 commit

  1. git-compress git:(master) git rebase -i <指定的 commit>

当我们指定到第一个 commit 的时候,我们可以编辑 a7e9aa4 还有 c4bf672 两个节点。具体命令的含义,在操作的清单上已经列举没明显了,有兴趣的可以逐个命令进行测试。这里我选择 squash

  1. pick a7e9aa4 [add] second commit
  2. pick c4bf672 [add] third commit
  3. # Rebase 0350222..c4bf672 onto 0350222 (2 commands)
  4. #
  5. # Commands:
  6. # p, pick = use commit
  7. # r, reword = use commit, but edit the commit message
  8. # e, edit = use commit, but stop for amending
  9. # s, squash = use commit, but meld into previous commit
  10. # f, fixup = like "squash", but discard this commit's log message
  11. # x, exec = run command (the rest of the line) using shell
  12. # d, drop = remove commit
  13. #
  14. # These lines can be re-ordered; they are executed from top to bottom.
  15. #
  16. # If you remove a line here THAT COMMIT WILL BE LOST.
  17. #
  18. # However, if you remove everything, the rebase will be aborted.
  19. #
  20. # Note that empty commits are commented out

以下是编辑最后的情况,把第三个节点压缩到第二个节点,并且保留第二个节点。

  1. pick a7e9aa4 [add] second commit
  2. squash c4bf672 [add] third commit
  3. # Rebase 0350222..c4bf672 onto 0350222 (2 commands)
  4. #
  5. # Commands:
  6. # p, pick = use commit
  7. # r, reword = use commit, but edit the commit message
  8. # e, edit = use commit, but stop for amending
  9. # s, squash = use commit, but meld into previous commit
  10. # f, fixup = like "squash", but discard this commit's log message
  11. # x, exec = run command (the rest of the line) using shell
  12. # d, drop = remove commit
  13. #
  14. # These lines can be re-ordered; they are executed from top to bottom.
  15. #
  16. # If you remove a line here THAT COMMIT WILL BE LOST.
  17. #
  18. # However, if you remove everything, the rebase will be aborted.
  19. #
  20. # Note that empty commits are commented out

压缩完后,需要重新编辑一下 commit 信息。

  1. # This is a combination of 2 commits.
  2. # This is the 1st commit message:
  3. [add] second commit
  4. # This is the commit message #2:
  5. [add] third commit
  6. # Please enter the commit message for your changes. Lines starting
  7. # with '#' will be ignored, and an empty message aborts the commit.
  8. #
  9. # Date: Mon Jun 11 11:01:35 2018 +0800
  10. #
  11. # interactive rebase in progress; onto 0350222
  12. # Last commands done (2 commands done):
  13. # pick a7e9aa4 [add] second commit
  14. # squash c4bf672 [add] third commit
  15. # No commands remaining.
  16. # You are currently editing a commit while rebasing branch 'master' on '0350222'.
  17. #
  18. # Changes to be committed:
  19. # new file: b.txt
  20. # new file: c.txt
  21. #

最后压缩成功的提示。

  1. git-compress git:(master) git rebase -i 0350222da791e26d07a4e77060709700cb48608d
  2. [detached HEAD 51c5f09] [add] second commit
  3. Date: Mon Jun 11 11:01:35 2018 +0800
  4. 2 files changed, 1 insertion(+)
  5. create mode 100644 b.txt
  6. create mode 100644 c.txt
  7. Successfully rebased and updated refs/heads/master.

自此,就完成了压缩多个「无意义」节点的需求了。操作简单,但是在我看来这不应该成为经常性的操作。因为在提交代码的时候,为了展示更加清晰的演进图,应该处理好自己的 commit 信息,主动去避免冗余。

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注