git merge 與 rebase 的
觀念與實務應用
多奇數位創意有限公司
技術總監 黃保翕 ( Will 保哥 )
部落格:http://blog.miniasp.com/
關於「合併」的觀念解析
The "Merge" Concepts
常見的三種合併方法 (Merge)
• 關於 Git 的快轉機制 (Fast-forward)
– 所謂的「快轉機制」,就是 Git 得知這個合併的過程,其實會依序套用
new_feature 原本就有的變更,所以在合併的時候會直接修改 master 分
支的 HEAD 參照位址,直接移動到 new_feature的 HEAD 那個版本。
• 正常的合併
– git checkout master
– git merge new_feature
• 不快轉的合併
– git checkout master
– git merge new_feature --no-ff
• 壓縮的合併
– git checkout master
– git merge new_feature --squash
不同的合併方式
• git merge <branch1> <branch2> <branch3> …
• git merge --no-ff
• git merge –squash
• git rebase <commit_id>
• git rebase <commit_id> -I
• git cherry-pick <commit_id>
• git revert <commit_id>
一般的合併方法
• 主要步驟
– 先切換至最終要合併完成的分支
• git checkout -b master
– 將另一個分支的變更合併回來
• git merge <new_feature_branch>
– 若合併成功
• 會自動引發一個新的 commit
– 若合併失敗 (發生衝突)
• 會停留在 Unmerged 狀態,需人工介入處理
• 處理完衝突,需繼續完成合併動作 (需做一次commit動作)
– git add
– git commit
• 放棄衝突,可選擇復原至合併前的狀態
– git reset --hard
安全的合併方法
• 方法 1
– git checkout -b merge1
– git merge <new_feature_branch>
– 若合併成功
• git checkout master
• git merge merge1 (Fast-forward)
• git branch –d merge1
– 若合併失敗
• git checkout master
• git branch -D merge1
安全的合併方法
• 方法 2
– git tag -f try_merge_master
– git merge <new_feature_branch>
– 若合併成功
• git tag -d try_merge_master
– 若合併失敗
• git reset try_merge_master --hard
• git tag -d try_merge_master
重新指定基礎位置 (Rebase)
• 將另一個分支當成目前分支的起點
– git checkout branch1
– git rebase master
– git rebase --continue
– git rebase --abort
– git rebase --skip
• 主要任務
– 先找出兩個分支之間的共同起點
– 將目前分支的所有變更套用在另一個分支
• 這就是所謂【重新指定基礎位置】的意思
• 是一個版本一個版本的套用變更
• 注意事項
– 不要在 git rebase 發生衝突的過程中執行 git commit 命令
– 如果真的做了,請改執行 git rebase --skip 跳過這一版套用
MERGE 與 REBASE 的線圖差異
• MERGE
– git checkout master
– git merge branch1
• REBASE
– git checkout branch1
– git rebase master
– git checkout master
– git merge branch1
• REBASE + MERGE --no-ff
– git checkout branch1
– git rebase master
– git checkout master
– git merge branch1 --no-ff
了解 MERGE 與 REBASE 的差異
• 相同之處
– 都是合併的一種,但合併的方式與步驟不同
• MERGE 如何合併
– 假設你有一個 new_feature 分支想合併回 master
– 你會這樣執行
• git checkout master
• git merge new_feature (會建立起一條分支線圖)
• REBASE 如何合併
– 假設你有一個 new_feature 分支想合併回 master
( 事實上是將自己的所有變更 commit 在 master 最新版後面)
– 你會這樣執行
• git checkout new_feature
• git rebase master (會讓 new_feature 併進 master 的線圖上)
• git checkout master
• git merge new_feature
Rebase 能做的事
• 0. 重新 commit (Pick)
• 1. 調換 commit 的順序
• 2. 修改 commit 的訊息 (Edit)
• 3. 插入一個 commit
• 4. 編輯一個 commit
• 5. 拆解一個 commit
• 6. 壓縮一個 commit,且合併訊息紀錄 (Squash)
• 7. 壓縮一個 commit,但丟棄版本紀錄
• 8. 刪除一個 commit (Skip)
關於「合併」的實務應用
The "Merge" Best Practices
正常合併
• 預設會啟用 快轉 (fast-forward) 機制
• 給自己專用的小分支可以直接這樣用的
– 允許一條線畫到底的情境
• 本地 功能分支 (feature branch) 常用
13
不快轉合併 ( --no-ff )
• 用來確保主要分支的線圖保持乾淨
• 本地分支合併回主線時使用
– 主線可能是 master 或 develop
• 遠端分支合併時預設採用這個模式
– GitHub
14
正常變基 ( Rebase )
• 用來確保整體分支線圖保持乾淨
• 通常是在 git pull 的時候發生使用
– 請記得:一個本地分支配一個遠端分支
• 還有在整理分支線圖時會用到
15
常用於有遠端儲存庫的情境
• git pull
– git fetch
– git merge
• git pull --rebase
– git fetch
– git rebase
– 此設定為 GitHub Desktop 的預設值
– 使用 git pull --rebase 可有效避免無謂的合併線圖
使用 git rebase 避免無謂的 merge | ihower { blogging }
http://ihower.tw/blog/archives/3843
• 把 rebase 當做 git pull 的預設
值
[branch "master"]
remote = origin
merge = refs/heads/master
rebase = true
總結
Summary
關於 Git 合併與變基
• Git 打從骨子裡都是分支與合併
• Git 的分支與合併既便宜又安全!
– git reflog
• 釐清 merge 與 rebase 的用途與使用情境
18
聯絡資訊
• The Will Will Web
記載著 Will 在網路世界的學習心得與技術分享
– http://blog.miniasp.com/
• Will 保哥的技術交流中心 (臉書粉絲專頁)
– http://www.facebook.com/will.fans
• Will 保哥的噗浪
– http://www.plurk.com/willh/invite
• Will 保哥的推特
– https://twitter.com/Will_Huang

git merge 與 rebase 的觀念與實務應用

  • 1.
    git merge 與rebase 的 觀念與實務應用 多奇數位創意有限公司 技術總監 黃保翕 ( Will 保哥 ) 部落格:http://blog.miniasp.com/
  • 2.
  • 3.
    常見的三種合併方法 (Merge) • 關於Git 的快轉機制 (Fast-forward) – 所謂的「快轉機制」,就是 Git 得知這個合併的過程,其實會依序套用 new_feature 原本就有的變更,所以在合併的時候會直接修改 master 分 支的 HEAD 參照位址,直接移動到 new_feature的 HEAD 那個版本。 • 正常的合併 – git checkout master – git merge new_feature • 不快轉的合併 – git checkout master – git merge new_feature --no-ff • 壓縮的合併 – git checkout master – git merge new_feature --squash
  • 4.
    不同的合併方式 • git merge<branch1> <branch2> <branch3> … • git merge --no-ff • git merge –squash • git rebase <commit_id> • git rebase <commit_id> -I • git cherry-pick <commit_id> • git revert <commit_id>
  • 5.
    一般的合併方法 • 主要步驟 – 先切換至最終要合併完成的分支 •git checkout -b master – 將另一個分支的變更合併回來 • git merge <new_feature_branch> – 若合併成功 • 會自動引發一個新的 commit – 若合併失敗 (發生衝突) • 會停留在 Unmerged 狀態,需人工介入處理 • 處理完衝突,需繼續完成合併動作 (需做一次commit動作) – git add – git commit • 放棄衝突,可選擇復原至合併前的狀態 – git reset --hard
  • 6.
    安全的合併方法 • 方法 1 –git checkout -b merge1 – git merge <new_feature_branch> – 若合併成功 • git checkout master • git merge merge1 (Fast-forward) • git branch –d merge1 – 若合併失敗 • git checkout master • git branch -D merge1
  • 7.
    安全的合併方法 • 方法 2 –git tag -f try_merge_master – git merge <new_feature_branch> – 若合併成功 • git tag -d try_merge_master – 若合併失敗 • git reset try_merge_master --hard • git tag -d try_merge_master
  • 8.
    重新指定基礎位置 (Rebase) • 將另一個分支當成目前分支的起點 –git checkout branch1 – git rebase master – git rebase --continue – git rebase --abort – git rebase --skip • 主要任務 – 先找出兩個分支之間的共同起點 – 將目前分支的所有變更套用在另一個分支 • 這就是所謂【重新指定基礎位置】的意思 • 是一個版本一個版本的套用變更 • 注意事項 – 不要在 git rebase 發生衝突的過程中執行 git commit 命令 – 如果真的做了,請改執行 git rebase --skip 跳過這一版套用
  • 9.
    MERGE 與 REBASE的線圖差異 • MERGE – git checkout master – git merge branch1 • REBASE – git checkout branch1 – git rebase master – git checkout master – git merge branch1 • REBASE + MERGE --no-ff – git checkout branch1 – git rebase master – git checkout master – git merge branch1 --no-ff
  • 10.
    了解 MERGE 與REBASE 的差異 • 相同之處 – 都是合併的一種,但合併的方式與步驟不同 • MERGE 如何合併 – 假設你有一個 new_feature 分支想合併回 master – 你會這樣執行 • git checkout master • git merge new_feature (會建立起一條分支線圖) • REBASE 如何合併 – 假設你有一個 new_feature 分支想合併回 master ( 事實上是將自己的所有變更 commit 在 master 最新版後面) – 你會這樣執行 • git checkout new_feature • git rebase master (會讓 new_feature 併進 master 的線圖上) • git checkout master • git merge new_feature
  • 11.
    Rebase 能做的事 • 0.重新 commit (Pick) • 1. 調換 commit 的順序 • 2. 修改 commit 的訊息 (Edit) • 3. 插入一個 commit • 4. 編輯一個 commit • 5. 拆解一個 commit • 6. 壓縮一個 commit,且合併訊息紀錄 (Squash) • 7. 壓縮一個 commit,但丟棄版本紀錄 • 8. 刪除一個 commit (Skip)
  • 12.
  • 13.
    正常合併 • 預設會啟用 快轉(fast-forward) 機制 • 給自己專用的小分支可以直接這樣用的 – 允許一條線畫到底的情境 • 本地 功能分支 (feature branch) 常用 13
  • 14.
    不快轉合併 ( --no-ff) • 用來確保主要分支的線圖保持乾淨 • 本地分支合併回主線時使用 – 主線可能是 master 或 develop • 遠端分支合併時預設採用這個模式 – GitHub 14
  • 15.
    正常變基 ( Rebase) • 用來確保整體分支線圖保持乾淨 • 通常是在 git pull 的時候發生使用 – 請記得:一個本地分支配一個遠端分支 • 還有在整理分支線圖時會用到 15
  • 16.
    常用於有遠端儲存庫的情境 • git pull –git fetch – git merge • git pull --rebase – git fetch – git rebase – 此設定為 GitHub Desktop 的預設值 – 使用 git pull --rebase 可有效避免無謂的合併線圖 使用 git rebase 避免無謂的 merge | ihower { blogging } http://ihower.tw/blog/archives/3843 • 把 rebase 當做 git pull 的預設 值 [branch "master"] remote = origin merge = refs/heads/master rebase = true
  • 17.
  • 18.
    關於 Git 合併與變基 •Git 打從骨子裡都是分支與合併 • Git 的分支與合併既便宜又安全! – git reflog • 釐清 merge 與 rebase 的用途與使用情境 18
  • 19.
    聯絡資訊 • The WillWill Web 記載著 Will 在網路世界的學習心得與技術分享 – http://blog.miniasp.com/ • Will 保哥的技術交流中心 (臉書粉絲專頁) – http://www.facebook.com/will.fans • Will 保哥的噗浪 – http://www.plurk.com/willh/invite • Will 保哥的推特 – https://twitter.com/Will_Huang