Git rebase 和 merge 合併操作示範錄影

昨天的 Git 教學投影片 還蠻多人按贊分享的,謝謝大家。不過其中少了重要的 live demo 覺得有點可惜,所以來把其中最有趣的一段錄下來好了。第一次錄影加聲音發現還蠻緊張的,獻醜哩。

這是先用 rebase 整理 commit history (包括修改訊息、修改內容、刪除、拆開、新增和調換commit順序),然後再進行 merge 的示範。但誠如我投影片 p117~p118 所說,這是一種追求完美潔癖龜毛的作法,但是看到最後的 commits 線圖這麼漂亮,就覺得值得啦,而且中間的過程很有趣不是嗎? XD (除非一直發生 rebase conflict 情況啦,那就不好玩了,請量力而為 :p)

情境是我們想把 feature/forum 這個 branch 合併進主幹 master,這是合併前:

以下是直接在 master branch 做 merge feature/forum 的合併結果。你會發現 feature/forum 與 feature/chatroom 這兩個分支出現交疊的情況,當合併的分支一多,線圖就容易變得雜亂:

以下是改成用 rebase 整理之後再 merge 的方式,做出漂亮的合併線圖:

ps. 如果有人想練習的話,可以 fork sandbox 這個專案(純粹練習git,是個亂寫的rails專案)。

Git 教育訓練課程投影片 (2012)

Update(7/21): 我把 p117 rebase 和 merge 操作的示範 錄成影片啦 :)

這是最近準備的 Git 教育訓練課程,加上 live demo (一般操作、merge、reset、rebase等等示範) 時間大概是三個小時。其內容主要基於去年的演講,新增了Git內部原理(p36~51)、分支模式(p143)和更多 Tips(p168)內容等等,總頁數從117成長到198… XD

再次感謝 schacon 公開的 OmniGraffle Diagrams 圖檔讓我可以改來用 :>

如何建立一個沒有 Parent 的獨立 Git branch

首先,你一定會問幹嘛這樣做。我在上回的Git 演講中有提到:在 Git,你可以建立毫不相關的分支,用來保存其他資訊,就像目錄一樣。這 Branch 的用途不會被 Merge 進開發主幹,是完全獨立的。

實務上的一個應用,就是 Github 提供的 Github Pages 功能,只要你在專案下開一個 branch 叫做 gh-pages,那這個 branch 的內容就會變成靜態網頁。我之前的作法是先分支出來,然後再 commit 一次砍掉所有檔案。雖然結果是ok可以用啦,但是總覺得 gh-pages 這 branch 有 parent 就是意思不對勁,它是完全獨立於主幹的,不應該有 parent 資訊。

剛突然想到這個問題可以 google 看看(Github Pages上其實也有寫 XD),還真的有:

方法一 (source)

因為 git branch 預設是從 HEAD 分支,所以可以這樣 Hack HEAD:

echo ref: refs/heads/newbranch > .git/HEAD
git rm -rf .   # 砍掉所有檔案重來
.....   # 加新檔案
git add .
git commit -m 'create new branch'

方法二(source)

Git 1.7.2 之後版本有支援 –orphan 參數:

git checkout --orphan newbranch
git rm -rf .    # 砍掉所有檔案重來
...  # 加新檔案
git add .
git commit -m 'create new branch'

方法三(source)

git symbolic-ref HEAD refs/heads/newbranch
rm .git/index
git clean -fdx
...  # 加新檔案
git add .
git commit -m 'create new branch'

結果就像是這樣,master 跟 newbranch 的節點完全是分開的:

我的 Git 偏好設定

1. 讓 Command Line 指令列顯示目前處在哪一個 Git Branch 分支,最早是在 RGBA 看到這一招,非常方便。另外我最近看到一個點子是顯示從上一次 commit 之後過了多久時間,這可以提醒你是不是該 commit 了 XD

請修改家目錄的 ~/.bash_profile 檔案 (我是用 Bash)。

結果如下,各位可以看到目前處在 master 分支,並且這個專案已經過了 1821 個小時沒有 commit 了.... :p

2. 安裝 Git 的 Bash autocompletion,這樣按 tab 就會有自動完成的效果,它甚至包括 git checkout 時都可以抓到你的 branch 名稱。這裡我用 Homebrew 來安裝 bash-completion,這套件其實包括很多 autocompletion script,你可以去 /usr/local/etc/bash_completion.d 這個目錄找找看。

brew install bash-completion
cp /usr/local/etc/bash_completion.d/git-completion.bash ~/.git-bash-completion.sh

編輯 ~/.bash_profile 加入

[ -f ~/.git-bash-completion.sh ] && . ~/.git-bash-completion.sh

3. 打開 Git 的 color 顏色設定,這樣 Git 指令的輸出結果才會加上顏色,像是 git status 等:

git config --global color.ui true

4. 設定你偏好的文字編輯器和 diff 工具

git config --global core.editor
git config --global merge.tool opendiff

5. 最後,我個人喜歡以下的 alias:

git config --global alias.co checkout
git config --global alias.ci commit
git config --global alias.st status
git config --global alias.br branch

這樣只要輸入 git st 就是 git status 了。

FYI,以上 git 設定檔的位置在 ~/.gitconfig,你也可以直接修改這個檔案。

Git and Github 演講投影片(2011)

Update(2012/7): 有 2012 年新版內容。

釋出明天在Facebook 軟體開發團隊工具心得分享要演講的投影片。如果你是 Git 初學者,建議可以從我之前的文章看起。

我的 Git 系列文章:

其他很棒的英文網頁:

Git flow 開發流程

Update: 2011/3/19 受邀有場分享 Git介紹,使用與開發流程 at Facebook 軟體開發團隊工具心得分享

大家都知道 Git 開 branch 很方便,非常鼓勵 topic branch,但有沒有一套模型流程告訴我們應該怎麼管理 branch 呢? 有人便整理出一套最佳實踐慣例 A successful Git branching model我們團隊就採用了這套流程。簡單來說,他將 branch 分成兩個主要分支,三種支援性分支:

  • 主要分支
    • master: 永遠處在 production-ready 狀態
    • develop: 最新的下次發佈開發狀態
  • 支援性分支
    • Feature branches: 開發新功能都從 develop 分支出來,完成後 merge 回 develop
    • Release branches: 準備要 release 的版本,只修 bugs。從 develop 分支出來,完成後 merge 回 master 和 develop
    • Hotfix branches: 等不及 release 版本就必須馬上修 master 趕上線的情況。會從 master 分支出來,完成後 merge 回 master 和 develop

作者還提供了 git-flow 指令工具幫助我們很容易的實踐,用法如下:
Continue reading