git rebase 壓縮提交的方法

之前我們用Git merge –squash來將分支中多次提交合併到master後,只保留一次提交歷史。但是有些提交到github遠程倉庫中的commit信息如何合併呢?

歷史記錄

首先我們查看一下master分支的提交歷史:

$ git log
commit 415a0be986a48113829b3c60ee2387c6dbdc81d8
Author: xuxu <xuxu_1988@126.com>
Date:   Mon Jan 26 20:11:29 2015 +0800

    10->1

commit ed09a6cbe0797275ceead3f8c8d829d01f0e604b
Author: xuxu <xuxu_1988@126.com>
Date:   Mon Jan 26 19:57:17 2015 +0800

    2015.01.26

commit 1821f6a1c1ed074fe886228cf33b3b3cb71819c4
Author: xuxu <xuxu_1988@126.com>
Date:   Mon Jan 26 19:53:28 2015 +0800

    2015.01.26

commit cc779982fc61e82ec494d6a5654417fa7194d748
Author: xuxu <xuxu_1988@126.com>
Date:   Mon Jan 26 19:40:24 2015 +0800

    2015.1.26
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

我們看到上面有四次commit,如何將這個四次合併到一次呢?

壓縮

使用下面的命令,最後一個數字4代表壓縮最後四次提交。

git rebase -i HEAD~4
  • 1
  • 1

該命令執行後,會彈出vim的編輯窗口,4次提交的信息會倒序排列,最上面的是第四次提交,最下面的是最近一次提交。

這裏寫圖片描述

我們需要修改第2-4行的第一個單詞pick爲squash,這個意義爲將最後三次的提交壓縮到倒數第四次的提交,效果就是我們在pick所在的提交就已經做了4次動作,但是看起來就是一次而已:

這裏寫圖片描述

然後我們保存退出,git會一個一個壓縮提交歷史,如果有衝突,需要修改,修改的時候要注意,保留最新的歷史,不然我們的修改就丟棄了。修改以後要記得敲下面的命令:

git add .
git rebase --continue
  • 1
  • 2
  • 1
  • 2

如果你想放棄這次壓縮的話,執行以下命令:

git rebase --abort
  • 1
  • 1

如果所有衝突都已經解決了,會出現如下的編輯窗口:

這裏寫圖片描述

這個時候我們需要修改一下合併後的commit的描述信息,我們將其描述爲helloworld吧:

這裏寫圖片描述

保存退出後會看到我們完整的信息:

$ git rebase -i HEAD~4
[detached HEAD 9097684] helloworld
 Author: xuxu <xuxu_1988@126.com>
 Committer: unknown <hui.qian@HuiQianPC.spreadtrum.com>
Your name and email address were configured automatically based
on your username and hostname. Please check that they are accurate.
You can suppress this message by setting them explicitly:

    git config --global user.name "Your Name"
    git config --global user.email you@example.com

After doing this, you may fix the identity used for this commit with:

    git commit --amend --reset-author

 9 files changed, 25 insertions(+), 11 deletions(-)
Successfully rebased and updated refs/heads/master.
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

現在我們來查看一下歷史:

$ git log
commit 90976848524251b0a62376a9e45ea5c8aae25d87
Author: xuxu <xuxu_1988@126.com>
Date:   Mon Jan 26 19:40:24 2015 +0800

    helloworld

commit f57da9460196b950036fe4c2c8f7e4c9131ee04e
Author: xuxu <xuxu_1988@126.com>
Date:   Mon Jan 26 19:38:27 2015 +0800

    2015.01.26

commit 64104e057f48d6dd0e432af8b55cbccd0a09ee63
Author: xuxu <xuxu_1988@126.com>
Date:   Mon Jan 26 19:31:42 2015 +0800

    2015.01.26

commit 8499d4fa23c4395660d21e0b7dca873a7a3ef2b8
Author: xuxu <xuxu_1988@126.com>
Date:   Mon Jan 26 18:58:40 2015 +0800

    2015.01.26
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

歷史很清楚的顯示出了我們的壓縮成功了。

同步到遠程倉庫

那麼這個時候我們的github上的信息又是如何呢?

這裏寫圖片描述

github上的提交歷史還是之前的,如何更新我們壓縮後的歷史記錄呢?

我們採用git push 試試:

To https://github.com/DoctorQ/AndroidTestScrpits.git
 ! [rejected]        master -> master (non-fast-forward)
error: failed to push some refs to 'https://github.com/DoctorQ/AndroidTestScrpit
s.git'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. Integrate the remote changes (e.g.
hint: 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

被拒絕了,因爲我們合併的歷史記錄已經在遠程倉庫之前了,你無法覆蓋它。那怎麼辦?如果你確定你的合併過程都是正確無誤的,那麼就可以強制push:

$ git push -f
warning: push.default is unset; its implicit value is changing in
Git 2.0 from 'matching' to 'simple'. To squelch this message
and maintain the current behavior after the default changes, use:

  git config --global push.default matching

To squelch this message and adopt the new behavior now, use:

  git config --global push.default simple

When push.default is set to 'matching', git will push local branches
to the remote branches that already exist with the same name.

In Git 2.0, Git will default to the more conservative 'simple'
behavior, which only pushes the current branch to the corresponding
remote branch that 'git pull' uses to update the current branch.

See 'git help config' and search for 'push.default' for further information.
(the 'simple' mode was introduced in Git 1.7.11. Use the similar mode
'current' instead of 'simple' if you sometimes use older versions of Git)

Counting objects: 1, done.
Writing objects: 100% (1/1), 232 bytes | 0 bytes/s, done.
Total 1 (delta 0), reused 0 (delta 0)
To https://github.com/DoctorQ/AndroidTestScrpits.git
 + 415a0be...9097684 master -> master (forced update)

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29

我們成功了。。現在來看看以下github的歷史記錄,以及更新了。

這裏寫圖片描述

遺留問題

1.這個方式的侷限性是,我無法單獨建立一個分支,然後在分支上做壓縮動作,再合併到master上,在master上直接操作就存在很大的風險。也可能是我暫時還不會這麼做吧,希望以後能找到答案。 
2.直接強制的push到遠程倉庫也會存在問題,別人pull下來後是不是也會有問題。這個也需要探究 
3.這種方式可以適用在本地分支之間的合併,你在dev分支中做了很多開發工作,修改歷史很多,現在你開發完成了,你就要合併到master分支,然後提交到遠程倉庫。這個時候你可以用上面的流程先把dev的歷史記錄壓縮一下,然後合併到master中。如果你是處在協同開發環境下,你還需要主要經常做遠程倉庫同步到master的動作,master的更新再rebase到dev分支。也需要探究

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章