# Merge

Git merge 區分兩種類型：

1. Fast-forward merge: 兩分支的所有 commit 紀錄沒有分歧
2. Three-way merge: 兩分支的 commit 紀錄有分歧，需要人工介入排除衝突的內容。

##### Git merge 基本流程

在一般的開發流程，建立新分支來開發新功能或修復 bug，在分支完成開發後，最後會將分支的內容合併到主分支 (main/master)。

- `git merge <branch-name>` : 合併分支 &lt;branch-name&gt; 至目前分支
- `git merge --abort` : 放棄目前的合併

分支 fix\_something 合併指令

```bash
git checkout main
git merge fix_something
```

合併後如果系統顯示 Merge conflict，必須依照訊息找出檔案(some.py)裡衝突的內容，進行手動修正。

手動修正以下標記的衝突內容：

- &lt;&lt;&lt;&lt; HEAD : 目前分支 (main) 的內容
- &gt;&gt;&gt;&gt; fix\_something: 要合併的分支 (fix\_something) 內容
- ====== : 分隔兩分支的衝突內容
- 技巧：參考標記的內容做適當的修改，最後移除所有的標記

```python
<<<<<<< HEAD         
print("Keep me!")
=======
print("No, keep me instead!")
>>>>>>> fix_something
```

完成後，依序再執行：

```bash
git add some.py
git status
# Check if the conflict has been fixed
git commit
```

檢視合併的紀錄

```bash
git log --graph --oneline
```

如果合併檔案的衝突內容太複雜，且無法有效地修正，可以使用以下指令，放棄這次分支的合併，並且讓專案回到合併前的內容。

```bash
git merge --abort
```

##### Git rebase

- [送 PR 前，使用 Git rebase 來整理你的 commit 吧！](https://medium.com/starbugs/use-git-interactive-rebase-to-organize-commits-85e692b46dd)

`git rebase <branch-name>` : Move the current branch on top of the &lt;branch-name&gt; branch

透過將已完成的工作從一個分支轉移到另一個分支來防止 three-way merges。這可保持線性歷史紀錄，且讓除錯更容易。

```bash
# 以互動方式 rebase
git rebase -i master
```

Interactive Rebasings 可讓開發人員修改個別提交，而不會因為多餘或不相關的變更而導致提交歷史雜亂無章。保持提交乾淨且相關，有助於建立更有條理且可維護的程式碼庫。通常用在 Pull Request 分支