目前有两种方案:

  1. git merge --squash
  2. git rebase -i HEAD~n

1. merge

  1. git merge --squash <要合并的分支>

例子:
本地的情况:

  1. 用普通的git merge
    git压缩版本快照 - 图1

当用git checkout master+git merge develop:
git压缩版本快照 - 图2
此时用git push,会将3,4,5,10,11,12,13版本快照全部push到服务器去。那么如果要我要压缩,把这么多版本快照压缩成一个版本快照然后push到服务器呢?

  1. 用git merge —squash <要合并的分支>
  1. git checkout master
  2. git merge --squash develop

git压缩版本快照 - 图3
此时用git push,只会push3和13到服务器去,于和之前的区别在于,13不再指向12,因此不会把12那边的链都push上去。

当然,此时还是会push两个版本快照到服务器,那么咋办:从origin/master再checkout一个新的分支,然后用git merge -squash master,再push,就可以了。

2. rebase

  1. git rebase -i HEAD~n

上述表示选定当前分支中包含HEAD在内的n个最新版本快照为对象,并在编辑器中打开。
比如本地版本库为如下:

  1. * f9bcbae (HEAD -> master) 12346579
  2. * aa82af1 132
  3. * 58f2314 用文本编辑器写的comment
  4. * e5d8212 (origin/master) 123

这个时候push的话,会吧f9bcbae,aa82af1,58f2314都push到服务器去。
执行:

  1. git rebase -i HEAD~3

git打开了文本编辑器,显示:

  1. pick 58f2314 用文本编辑器写的comment
  2. pick aa82af1 132
  3. pick f9bcbae 12346579
  4. # Rebase e5d8212..f9bcbae onto e5d8212 (3 commands)
  5. #
  6. # Commands:
  7. # p, pick <commit> = use commit
  8. # r, reword <commit> = use commit, but edit the commit message
  9. # e, edit <commit> = use commit, but stop for amending
  10. # s, squash <commit> = use commit, but meld into previous commit
  11. # f, fixup <commit> = like "squash", but discard this commit's log message
  12. # x, exec <command> = run command (the rest of the line) using shell
  13. # d, drop <commit> = remove commit
  14. # l, label <label> = label current HEAD with a name
  15. # t, reset <label> = reset HEAD to a label
  16. # m, merge [-C <commit> | -c <commit>] <label> [# <oneline>]
  17. # . create a merge commit using the original merge commit's
  18. # . message (or the oneline, if no original merge commit was
  19. # . specified). Use -c <commit> to reword the commit message.
  20. #
  21. # These lines can be re-ordered; they are executed from top to bottom.
  22. #
  23. # If you remove a line here THAT COMMIT WILL BE LOST.
  24. #
  25. # However, if you remove everything, the rebase will be aborted.
  26. #
  27. #
  28. # Note that empty commits are commented out

把后面的两个版本快照的前缀pick修改为fixup

  1. pick 58f2314 用文本编辑器写的comment
  2. fixup aa82af1 132
  3. fixup f9bcbae 12346579

保存,关掉文本编辑器。
显示:

  1. $ git rebase -i HEAD~3
  2. Successfully rebased and updated refs/heads/master.

查看版本库信息:

  1. * 2db421a (HEAD -> master) 用文本编辑器写的comment
  2. * e5d8212 (origin/master) 123

原本那三个版本快照只剩了一个刚才没有修改pick前缀的版本快照,并且hash也改变了,猜测意思是:重新生成了版本快照。
此时也达到了压缩版本快照的目的。push时,只会push2db421a上去。