網頁

2014年11月19日 星期三

Git rebase 操作與練習


rebase 是 Git 中非常重要的一個功能
其解說可以參考最底下的 Ref
我這邊一樣透過例子引導學習,以實作的步驟來感受 rebase 的魅力

開始玩吧


首先到我的 github 下載非常簡易的 git 專案,並先察看其 log
git clone https://github.com/PhelimXue/gittest.git

git lg

目前此 git 專案有 3 個檔案 a b c
在 initial 時 a b c 3 個檔案都是空檔案
而我分別在 a b c 輸入字串並各別作 commit 所以專案狀況如下
echo "aaa" > a
git commit -am 'edit 3a with master'

echo "bbb" > b
git commit -am 'edit 3b with master'

echo "ccc" > c
git commit -am 'edit 3c with master'


pull merge 與 pull rebase

最一開始就可以過 pull 來看出 merge 與 rebase 的差異,預設的 pull 為 merge 型式
由上圖可得知遠端的 origin/master 已經更改過 a b c 3 個檔案,所以我們先故意回到 initial 狀態並作些動作在 pull
git reset --hard 6e6fe0f

echo "aaaa" > a

git commit -am 'edit 4a with master'

此時看到 local 的 commit log 狀況如下圖

接著我們 pull,會發現衝突,解完衝突在作一次 commit
git pull

vi a (這邊解衝突 保留 4 個a

git add a

git commit

git lg

我們來看看一般的 pull 會看到怎麼樣的 log

這邊會看到他原先將 origin/master 與 master 視為不同 branch 然後在 pull 之後將兩條線 merge
少人共同開發或許還好,只要共同開發人數夠多,這個 log 將會變得很難讀

接下來再次回到 initial 狀態,也一樣修改 a 檔案並做 rebase 的 pull
git reset --hard 6e6fe0f

echo "aaaa" > a

git commit -am 'edit 4a with master'

git pull --rebase

這邊也是需要解衝突並保留 4 個 a,但操作行為不太一樣,最後 show 出 log 來看看
vi a (這邊解衝突 保留 4 個a

git add a

git rebase --continue

git lg

由上圖可以看出來,透過 rebase 來作 pull 視為同一個 branch 的合併
因為在我開發經驗看來,遠端 master 與 local master 為同一條線,別人家的 master 也是同一條,沒有必要被切割為多條線,最後又一堆 merge commit 回一條,所以透過 rebase 來 pull 的確是好方式..不過前題是開發者每個都會用

透過 Rebase 修改已 commit 的紀錄

延伸上面的動作繼續往下,現在我們讓自己 local 多幾筆 commit
echo "bbbb" > b
git commit -am 'edit 4b with master'

echo "cccc" > c
git commit -am 'edit 4c with master'

git lg

好的,我們看到了多了幾筆紀錄,此時我想更改 4a 的那筆 commit
透過 rebase 去存取 4a 之前的那比 commit 0edaebc
git rebase -i 0edaebc

由於我們要修改 4a 那比紀錄,於是最前面改成 e (edit) 儲存後退出,git 也有教我們後續操作

如果只是單純想改 commit 資訊,直接下 git commit --amend 就可以了
git commit --amend

git rebase --continue
 
git lg

當然除了改 commit 資訊以外也可以順便再修內文,接下來我將 4b 那個改為 5b 並覆蓋原 commit
git rebase -i 0edaebc (這變換成 4b 那個改為 e(edit)

echo 'bbbbb' > b

git add b

git commit --amend

git rebase --continue
 
git lg

由上圖可得看出,commit 改為 5b 而 b 的那個檔案也修改了。

切記!由於 rebase 會修改紀錄,所以請不要修改在 remote 端的紀錄,這樣 log 會大亂
如我上述的動作,其實都在改 local 的 master 而已,等修改完成在一次 push 上去就好

其他更強的功能 待續...


個人心得

小弟近來 rebase 也才剛接觸,使用的不夠熟練,卻深深感到它神奇的地方
不過話說回來...我是寫 Java 的人,在 eclipse 中的 rebase 好難操作..
誰有 eclipse 上操作 rebase 的好文章阿~~~~~~~(跪求


Ref:

http://ihower.tw/git/

沒有留言:

張貼留言