標籤:

Git將分支合併到master,有沒有辦法讓master不要產生分支中那些冗餘的commits?

在使用Git的過程中,我們一般是在master分支中切出一個工作分支,然後大家都在工作分支之中push代碼,工作完成後再將分支與主分支合併,但是這同樣會導致master分支產生大量冗餘commits,因為工作中的commits可能很隨意,改幾行字就提交這樣


用 git rebase -i 命令即可實現,下面我將演示一下這個命令:

①首先,我有一個新的倉庫,只有一個空提交。

Mac: demo$ git hi
dccff7e 2015-09-18 | initial commit (empty) [fuhaiwei]

②在master分支添加一個文件,並提交。

Mac: demo$ touch master_file
Mac: demo$ git add master_file
Mac: demo$ git commit -m "add master_file"
[master a4959da] add master_file
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 master_file
Mac: demo$ git hi
a4959da 2015-09-18 | add master_file [fuhaiwei]
dccff7e 2015-09-18 | initial commit (empty) [fuhaiwei]

③新開一個分支develop,並添加三個提交。

Mac: demo$ git branch develop
Mac: demo$ git checkout develop
// 省略命令若干
Mac: demo$ git hi
28646e2 2015-09-18 | add develop3 [fuhaiwei]
c341f75 2015-09-18 | add develop2 [fuhaiwei]
22f95c8 2015-09-18 | add develop1 [fuhaiwei]
a4959da 2015-09-18 | add master_file [fuhaiwei]
dccff7e 2015-09-18 | initial commit (empty) [fuhaiwei]

④使用 rebase -i 命令合併歷史提交

Mac: demo$ git rebase -i a4959da
會出現如下界面:

將想要合併進前一個提交的提交,前面的pick 改成 s,保存退出。

這時又會進入一個界面,是讓你輸入想要三個提交合併後的提交信息。

將前面的都刪掉,在第一行輸入想要的提交信息即可,第二行有個空行最好保留。保存退出。

Mac: demo$ git rebase -i a4959da
[detached HEAD 5ec37e0] add develop1 develop2 develop3
Date: Fri Sep 18 09:17:13 2015 +0800
3 files changed, 0 insertions(+), 0 deletions(-)
create mode 100644 develop1
create mode 100644 develop2
create mode 100644 develop3
Successfully rebased and updated refs/heads/develop.
Mac: demo$ git hi
5ec37e0 2015-09-18 | add develop1 develop2 develop3 [fuhaiwei]
a4959da 2015-09-18 | add master_file [fuhaiwei]
dccff7e 2015-09-18 | initial commit (empty) [fuhaiwei]

可以看到,這時三個提交已經合併了。

⑤將develop分支合併到master分支

Mac: demo$ git checkout master
Switched to branch "master"
Mac: demo$ git merge develop
Updating a4959da..5ec37e0
Fast-forward
develop1 | 0
develop2 | 0
develop3 | 0
3 files changed, 0 insertions(+), 0 deletions(-)
create mode 100644 develop1
create mode 100644 develop2
create mode 100644 develop3
Mac: demo$ git hi
5ec37e0 2015-09-18 | add develop1 develop2 develop3 [fuhaiwei]
a4959da 2015-09-18 | add master_file [fuhaiwei]
dccff7e 2015-09-18 | initial commit (empty) [fuhaiwei]

總結:git rebase -i 可以交互性的改變提交歷史,包括但不限於改變某次提交的內容,改變提交的順序,去除某次提交,合併某些提交。

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

當然上面的問題還有更暴力的方法可以解決,就是先 reset 到修改之前的狀態,然後在重新發起一次提交。

① 首先恢復到合併之前的狀態

Mac: demo$ git checkout develop
Switched to branch "develop"
Mac: demo$ git reset --hard 28646e2
HEAD is now at 28646e2 add develop3
Mac: demo$ git hi
28646e2 2015-09-18 | add develop3 [fuhaiwei]
c341f75 2015-09-18 | add develop2 [fuhaiwei]
22f95c8 2015-09-18 | add develop1 [fuhaiwei]
a4959da 2015-09-18 | add master_file [fuhaiwei]
dccff7e 2015-09-18 | initial commit (empty) [fuhaiwei]

②重置本地倉庫和暫存區到修改之前的狀態

Mac: demo$ git reset a4959da
Mac: demo$ git hi
a4959da 2015-09-18 | add master_file [fuhaiwei]
dccff7e 2015-09-18 | initial commit (empty) [fuhaiwei]

注意此時本地倉庫已經被重置,但是工作區的內容是修改之後的內容。

注意:這裡千萬不要打成 git reset --hard a4959da,要不然連工作區的內容都沒了。

(萬一不小心打錯了,導致修改的數據都沒了,不要慌,翻看前面的內容,找到最新提交的ID,git reset --hard 28646e2,即可找回。或者git reflog查看HEAD記錄,找到這個ID

③重新發起一次提交即可

Mac: demo$ git add .
Mac: demo$ git status
On branch develop
Changes to be committed:
(use "git reset HEAD &..." to unstage)

new file: develop1
new file: develop2
new file: develop3

Mac: demo$ git commit -m "add develop1 develop2 develop3"
[develop b36bff8] add develop1 develop2 develop3
3 files changed, 0 insertions(+), 0 deletions(-)
create mode 100644 develop1
create mode 100644 develop2
create mode 100644 develop3
Mac: demo$ git hi
b36bff8 2015-09-18 | add develop1 develop2 develop3 [fuhaiwei]
a4959da 2015-09-18 | add master_file [fuhaiwei]
dccff7e 2015-09-18 | initial commit (empty) [fuhaiwei]


針對一個bug或一個feature創建一條工作分支(假設這條分支與主分支的分離節點是commitA),改完確認後將其merge到主分支上。merge之前可以用git reset commitA --soft;git commit;將工作分支上新增的若干個commit合併成一個commit


你需要的是 git rebase,在 feature 分支上開發隨時保持與 master 同步最新代碼,即在 feature 分支上 執行 git rebase master。等待 feature 開發完了,切到 master,執行 git merge feature,這個時候的 merge 會是 Fast-Forward,不會產生任何無用的 commit。

我所負責的項目代碼的提交歷史幾乎都是一條線的,不管團隊中有多少人。


為每個小工作項創建一條feature分支,在featureX完成後,通過命令:

git merge --squash featureX

將featureX中的所有commit合併成master中的一個commit,master測試通過後就可以將featureX分支刪除了。

這樣,你的master分支上看到都是乾乾淨淨的一個feature一個commit。


看了一下其他人的答案,都沒說到重點:小顆粒度提交是一個非常好的習慣。不管是站在代碼審查還是持續集成的角度。


4種方式可以選擇。假設要將當前分支合到master,以下是簡要信息。

  1. git rebase -i, git checkout, git merge

  2. git checkout, git merge --squash, git commit
  3. git reset, git add, git commit, git checkout, git merge

  4. git commit --amend, git checkout, git merge


難道不是 merge 的時候加個--squash?

git merge --squash 你的feature分支


rebase可以哈


直接採用gerrit,逼著你squash


推薦閱讀:

GitHub的個人資料中,為什麼不提供性別選項?
GitHub 上有什麼好的或者有趣的 Shell 項目?
GitHub 如何基於 Node.js 和 Chromium 開發 Atom?
在MSys版的Git中使用git pull --rebase進行代碼更新到底是做了什麼?
如何使用10個小時搭建出個人域名而又Geek的獨立博客?

TAG:Git | GitHub |