為你⾃自⼰己學 Git
讀書會
⼀一、Git ⼊入⾨門篇
Git 優點

• 免費、開源

• 速度快、檔案體積⼩小

• 分散式系統
⼀一、Git ⼊入⾨門篇
Git 優點

• 免費、開源

• 速度快、檔案體積⼩小

• 分散式系統
Linux 之⽗父 ( Linus Torvalds )
為了了幫助管理理 Linux 核⼼心

僅花 10 天「順便便」開發出來來的版控軟體
⼀一、Git ⼊入⾨門篇
Git 優點

• 免費、開源

• 速度快、檔案體積⼩小

• 分散式系統
Linux 之⽗父 ( Linus Torvalds )
為了了幫助管理理 Linux 核⼼心

僅花 10 天「順便便」開發出來來的版控軟體
⼤大師⼀一出⼿手便便知有沒有,所以凡⼈人洗洗睡吧~
⼀一、Git ⼊入⾨門篇
Git 優點

• 免費、開源

• 速度快、檔案體積⼩小

• 分散式系統
複製貼上⼤大法
截圖快照⼤大法
⼀一、Git ⼊入⾨門篇
Git 優點

• 免費、開源

• 速度快、檔案體積⼩小

• 分散式系統
發佈於 2005 年年
——— Google docs 分⽔水嶺 ———
在 Google docs 發明之前,是集中式還是分散式?
⼀一、Git ⼊入⾨門篇
Git 優點

• 免費、開源

• 速度快、檔案體積⼩小

• 分散式系統
發佈於 2005 年年
——— Google docs 分⽔水嶺 ———
在 Google docs 發明之前,是集中式還是分散式?
集中式
分散式
Before
After
Git 完全不不需要伺服器器端的⽀支援就可以運作版本控制
因為每個⼈人都有⼀一份完整的儲存庫副本。
⼀一、Git ⼊入⾨門篇
Git 缺點

• 沒有缺點 阿不不是

• 易易學難精,博⼤大精深

傳說中的 80 / 20 法則
⼆二、Git Windows/Mac/Linux 環境安裝
• Install Git

• Github Account

• Optional - Sourcetree / Github Desktop
三、終端機/命令提示字元
• 絕對位置 vs 相對位置

• 資料料夾名稱中間有空格怎麼辦

資料料夾名稱是中⽂文怎麼辦

• 啊崩潰少打⼀一個 ’,進⼊入⻤鬼打牆
三、終端機/命令提示字元
• 絕對位置 vs 相對位置

• 資料料夾名稱中間有空格怎麼辦

資料料夾名稱是中⽂文怎麼辦

• 啊崩潰少打⼀一個 ’,進⼊入⻤鬼打牆
絕對位置
$ cd ~/desktop/yourFile
相對位置
$ cd yourFile
三、終端機/命令提示字元
• 絕對位置 vs 相對位置

• 資料料夾名稱中間有空格怎麼辦

資料料夾名稱是中⽂文怎麼辦

• 啊崩潰少打⼀一個 ’,進⼊入⻤鬼打牆
$ cd ‘oh space’ $ cd ‘中⽂文調⽪皮’
三、終端機/命令提示字元
• 絕對位置 vs 相對位置

• 資料料夾名稱中間有空格怎麼辦

資料料夾名稱是中⽂文怎麼辦

• 啊崩潰少打⼀一個 ’,進⼊入⻤鬼打牆 quote> 尾端補上 ’
control + c
# 中⽌止執⾏行行中的命令
三、終端機/命令提示字元
為什什麼我的 Terminal ⿊黑⿊黑醜醜?

我也想要 炫砲 Terminal
實作題
實作題
開始實作之前的補充:我之前練習時已經建⽴立過資料料夾要怎麼移除?

1. 進⼊入資料料夾,⼀一個⼀一個移除所有檔案

$ rm fileName

2. ⼀一次移除該資料料夾內所有檔案

$ rm -r folderName (⼀一鍵刪除)

$ rm -r -i folderName (安全,詢問每個檔案是否要刪除)

補充:同理理,如果我要複製資料料夾

$ cp -r originalFolderName newFolderName
實作題
開始實作之前的補充:我之前練習時已經建⽴立過資料料夾要怎麼移除?

1. 進⼊入資料料夾,⼀一個⼀一個移除所有檔案

$ rm fileName

2. ⼀一次移除該資料料夾內所有檔案

$ rm -r folderName (⼀一鍵刪除)

$ rm -r -i folderName (安全,詢問每個檔案是否要刪除)

補充:同理理,如果我要複製資料料夾

$ cp -r originalFolderName newFolderName
實作題
開始實作之前的補充:我之前練習時已經建⽴立過資料料夾要怎麼移除?

1. 進⼊入資料料夾,⼀一個⼀一個移除所有檔案

$ rm fileName

2. ⼀一次移除該資料料夾內所有檔案,-r 是 Recursion (遞迴)的意思

$ rm -r folderName (⼀一鍵刪除)

$ rm -r -i folderName (安全,詢問每個檔案是否要刪除)

補充:同理理,如果我要複製資料料夾

$ cp -r originalFolderName newFolderName
實作題
開始實作之前的補充:我之前練習時已經建⽴立過資料料夾要怎麼移除?

1. 進⼊入資料料夾,⼀一個⼀一個移除所有檔案

$ rm fileName

2. ⼀一次移除該資料料夾內所有檔案,-r 是 Recursion (遞迴)的意思

$ rm -r folderName (⼀一鍵刪除)

$ rm -r -i folderName (安全,詢問每個檔案是否要刪除)

補充:同理理,如果我要複製資料料夾

$ cp -r originalFolderName newFolderName
實作題
• 在 /tmp 資料料夾中

• 建⽴立⼀一個稱為 Git-Practice 的資料料夾

• 接著建⽴立⼀一個 yourName.txt 的檔案

• 並⽤用 vim 打三⾏行行的⾃自我介紹(可輸⼊入
Enter 換⾏行行)

• 儲存並關閉檔案

• 使⽤用指令開啟該⽂文件(⾮非 vim)
提示

1. 幾乎所有內容都涵蓋在:

終端機及常⽤用指令介紹 & 超簡明 Vim
操作介紹

2. 如果 Gitbook 找不不到答案

記得善⽤用⾕谷歌⼤大神哦
實作題答案
• 在 /tmp 資料料夾中

• 建⽴立⼀一個稱為 Git-Practice 的資料料夾

• 接著建⽴立⼀一個 yourName.txt 的檔案

• 並⽤用 vim 打三⾏行行的⾃自我介紹(可輸⼊入
Enter 換⾏行行)

• 儲存並關閉檔案

• 使⽤用指令開啟該⽂文件(⾮非 vim)
vim 儲存並關閉 :wq
四、設定 Git
• $ git config --global user.name "sunnyleeyun"

• $ git config --global user.email “sunnylee945@hotmail.com”

• $ git config --list

• user.name=sunnyleeyun

user.email=sunnylee945@hotmail.com

• 注意:此時如果資料料很多的話會是 vim 顯示,

使⽤用上下鍵尋找位置,離開是 :q
四、設定 Git
如果覺得學得很痛苦,懷疑⾃自⼰己是不不是頭被⾨門夾過
別擔⼼心,你真的不不孤單!
四、設定 Git
• $ git help sth

• ⽐比如 $ git help config

• $ man [insert command here]

• 補充:每天使⽤用 Git 的 19 ⼩小技巧
Need Some Help?
四、設定 Git
• $ git help sth

• ⽐比如 $ git help config

• $ man [insert command here]

• 補充:每天使⽤用 Git 的 19 ⼩小技巧
更更重要的是

善⽤用⾕谷歌⼤大神的⼒力力量量
Need Some Help?
五、開始使⽤用 Git
五、開始使⽤用 Git
情境題
五、開始使⽤用 Git
情境題
• ⼯工作⽬目錄錄、暫存區域
• 幾個檔案等待被加⼊入
⾄至暫存區域
• 如何從⼯工作⽬目錄錄到暫
存區域
• 如何從暫存區域到儲
存庫
五、開始使⽤用 Git
情境題
⼯工作⽬目錄錄
暫存區域
儲存區
• ⼯工作⽬目錄錄、暫存區域
• 幾個檔案等待被加⼊入
⾄至暫存區域
• 如何從⼯工作⽬目錄錄到暫
存區域
• 如何從暫存區域到儲
存庫
五、開始使⽤用 Git
情境題
⼯工作⽬目錄錄
暫存區域
儲存區
• ⼯工作⽬目錄錄、暫存區域
• 幾個檔案等待被加⼊入
⾄至暫存區域
• 如何從⼯工作⽬目錄錄到暫
存區域
• 如何從暫存區域到儲
存庫
五、開始使⽤用 Git
情境題
⼯工作⽬目錄錄
暫存區域
五個檔案等待被 add
儲存區
• ⼯工作⽬目錄錄、暫存區域
• 幾個檔案等待被加⼊入
⾄至暫存區域
• 如何從⼯工作⽬目錄錄到暫
存區域
• 如何從暫存區域到儲
存庫
五、開始使⽤用 Git
情境題
• ⼯工作⽬目錄錄、暫存區域
• 幾個檔案等待被加⼊入
⾄至暫存區域
• 如何從⼯工作⽬目錄錄到暫
存區域
• 如何從暫存區域到儲
存庫
五、開始使⽤用 Git
情境題
或是在 ExerciseVC 還在⼯工作⽬目錄錄時直接 ___
$ git add kneesup/'Tab Home'/Exercise/ExerciseViewController.swift
• ⼯工作⽬目錄錄、暫存區域
• 幾個檔案等待被加⼊入
⾄至暫存區域
• 如何從⼯工作⽬目錄錄到暫
存區域
• 如何從暫存區域到儲
存庫
五、開始使⽤用 Git
情境題
儲存區
• ⼯工作⽬目錄錄、暫存區域
• 幾個檔案等待被加⼊入
⾄至暫存區域
• 如何從⼯工作⽬目錄錄到暫
存區域
• 如何從暫存區域到儲
存庫
五、開始使⽤用 Git
情境題
儲存區
或是在此區域填下 Commit 資訊,並點選 Commit 按鈕
• ⼯工作⽬目錄錄、暫存區域
• 幾個檔案等待被加⼊入
⾄至暫存區域
• 如何從⼯工作⽬目錄錄到暫
存區域
• 如何從暫存區域到儲
存庫
$ git commit -m "Add Exercise setRssi method"
註: Commit 之後,也還是在本地端,並沒有到

遠端的 Github,到遠端命令是 Push 的事情
五、開始使⽤用 Git
Git 區域分類類
⼯工作⽬目錄錄 暫存區域 儲存區
Local
五、開始使⽤用 Git
Git 區域分類類
⼯工作⽬目錄錄 暫存區域 儲存區
git status
Local
五、開始使⽤用 Git
Git 區域分類類
⼯工作⽬目錄錄 暫存區域 儲存區
git status
Local
補充:紫⾊色問號代表⽂文件是新建的,還沒有添加到 Git 的監視中,

⼀一旦被添加⼀一次,以後對於這個⽂文件,就是修改狀狀態(⿈黃⾊色狀狀態)。
五、開始使⽤用 Git
Git 區域分類類
⼯工作⽬目錄錄 暫存區域 儲存區
git status
Local
ExerciseViewController.swift 在暫存區域,
其他檔案則在⼯工作⽬目錄錄等待被 add ⾄至暫存區域
五、開始使⽤用 Git
Git 區域分類類
⼯工作⽬目錄錄 暫存區域 儲存區
Local
git add git commit
五、開始使⽤用 Git
Git 區域分類類
⼯工作⽬目錄錄 暫存區域 儲存區
Local
git add git commit
⼯工作⽬目錄錄
暫存區域
$ git add
五、開始使⽤用 Git
Git 區域分類類
⼯工作⽬目錄錄 暫存區域 儲存區
Local
git add git commit
$ git commit
⼯工作⽬目錄錄
暫存區域
儲存區
$ git add
實作題
提示

1. Add, Commit 內容隨意

2. 有⼩小陷阱哦~

3. 如果做錯的話想要重新開始可以試試

> 回到 /tmp 資料料夾

> $ rm -r -i Git-Practice

檢視哪些檔案需要被刪除
(yourName.txt 不不要誤刪囉,如果真
的不不⼩小⼼心刪掉也沒關係,Let it go~ )
• 回到前⾯面做的 Git-Practice

• 初始化 git

• 建⽴立⼀一個檔案 fileDirectory.txt

將檔案放在「⼯工作⽬目錄錄(Working
Directory)」(呈現 untracked file 狀狀態)

• 建⽴立⼀一個檔案 fileStaging.txt

將檔案放在「暫存區(Staging Area)」

• 建⽴立另⼀一個檔案 fileRepository.txt

將檔案放在「儲存庫(Repository)」
• 回到前⾯面做的 Git-Practice

• 初始化 git

• 建⽴立⼀一個檔案 fileDirectory.txt

將檔案放在「⼯工作⽬目錄錄(Working
Directory)」(呈現 untracked file 狀狀態)

• 建⽴立⼀一個檔案 fileStaging.txt

將檔案放在「暫存區(Staging Area)」

• 建⽴立另⼀一個檔案 fileRepository.txt

將檔案放在「儲存庫(Repository)」
實作題答案
五、開始使⽤用 Git
• ⼀一個檔案通常包含不不只⼀一個內容

• Staging ⼀一個 file 裡⾯面⼀一個區塊的程式碼

• ⽬目的:盡量量讓每個 commit 有意義
實際應⽤用 $ git add -p
五、開始使⽤用 Git
Hunk 是什什麼?
直觀的翻譯來來說,是⼀一塊⼀一塊的意思
在 Git 裡⾯面是⼀一個區塊、⼀一個區塊進⾏行行變更更
五、開始使⽤用 Git
Hunk 是什什麼?
呃換個領域就需要⾺馬賽克了了呢
直觀的翻譯來來說,是⼀一塊⼀一塊的意思
在 Git 裡⾯面是⼀一個區塊、⼀一個區塊進⾏行行變更更
五、開始使⽤用 Git
⼯工作⽬目錄錄 暫存區域 儲存區
Local
Hunk A
Git commit & add 組合技
五、開始使⽤用 Git
⼯工作⽬目錄錄 暫存區域 儲存區
Local
git add
Hunk A
Git commit & add 組合技
五、開始使⽤用 Git
⼯工作⽬目錄錄 暫存區域 儲存區
Local
git add
Hunk A
git commit
Git commit & add 組合技
五、開始使⽤用 Git
⼯工作⽬目錄錄 暫存區域 儲存區
Local
git add
Hunk A
git commit
Hash A
Git commit & add 組合技
五、開始使⽤用 Git
⼯工作⽬目錄錄 暫存區域 儲存區
Local
Hunk B
Hunk C
Hunk D
Hunk AHash A
Git commit & add 組合技
五、開始使⽤用 Git
⼯工作⽬目錄錄 暫存區域 儲存區
Local
git add
Hunk B
Hunk C
Hunk AHash A
Hunk D
Git commit & add 組合技
五、開始使⽤用 Git
⼯工作⽬目錄錄 暫存區域 儲存區
Local
git add
Hunk A
git commit
Hash A
Hunk B
Hunk C
Hunk D
Git commit & add 組合技
五、開始使⽤用 Git
⼯工作⽬目錄錄 暫存區域 儲存區
Local
git add
Hunk A
git commit
Hash A
Hunk B
Hunk C
Hunk D
Git commit & add 組合技
Hash B
五、開始使⽤用 Git
⼯工作⽬目錄錄 暫存區域 儲存區
Local
Hunk AHash A
Hunk B
Hunk C
Hunk D
Git commit & add 組合技
Hash B
五、開始使⽤用 Git
⼯工作⽬目錄錄 暫存區域 儲存區
Local
git add
Hunk AHash A
Hunk B
Hunk C
Hunk D
Git commit & add 組合技
Hash B
五、開始使⽤用 Git
⼯工作⽬目錄錄 暫存區域 儲存區
Local
git add
Hunk A
git commit
Hash A
Hunk B
Hunk C
Hunk D
Git commit & add 組合技
Hash B
五、開始使⽤用 Git
⼯工作⽬目錄錄 暫存區域 儲存區
Local
git add
Hunk A
git commit
Hash A
Hunk B
Hunk C
Hunk DHash C
Git commit & add 組合技
Hash B
五、開始使⽤用 Git
• ⼀一個 hash 代表⼀一次 change

• ⼀一個 change 可以包含多個 hunk

• ⼀一個 hunk 最⼩小單位是⼀一⾏行行
回顧
五、開始使⽤用 Git
⼯工作⽬目錄錄 暫存區域 儲存區
Local
Hunk AHash A
Hunk B
Hunk C
Hash B
Hunk DHash CHead
Git HEAD
五、開始使⽤用 Git
⼯工作⽬目錄錄 暫存區域 儲存區
Local
Hunk AHash A
Hunk B
Hunk C
Hunk DHash C
Git HEAD HEAD 是⼀一個指標,也就是你現在在哪裡的意思
Hash B
五、開始使⽤用 Git
⼯工作⽬目錄錄 暫存區域 儲存區
Local
Hunk AHash A
Hunk B
Hunk C
Hunk DHash CHead
Head^
Git HEAD
Hash B
五、開始使⽤用 Git
⼯工作⽬目錄錄 暫存區域 儲存區
Local
Hunk AHash A
Hunk B
Hunk C
Hunk DHash CHead
Head^
Head^^
Git HEAD
Hash B
五、開始使⽤用 Git
⼯工作⽬目錄錄 暫存區域 儲存區
Local
Hunk AHash A
Hunk B
Hunk C
Hunk DHash C
Git reset 重置:Mixed, Soft, Hard
Hash B
五、開始使⽤用 Git
⼯工作⽬目錄錄 暫存區域 儲存區
Local
Hunk AHash A
Hunk B
Hunk C
Hunk DHash C
Hash B
Git reset 重置:Mixed, Soft, Hard
五、開始使⽤用 Git
⼯工作⽬目錄錄 暫存區域 儲存區
Local
Hunk AHash A
Hunk B
Hunk C
Hunk DHash C
— mixed HEAD^
Hash B
Git reset 重置:Mixed, Soft, Hard
五、開始使⽤用 Git
⼯工作⽬目錄錄 暫存區域 儲存區
Local
Hunk AHash A
Hunk B
Hunk C
— mixed HEAD^
Hunk D
Hash B
Git reset 重置:Mixed, Soft, Hard
五、開始使⽤用 Git
⼯工作⽬目錄錄 暫存區域 儲存區
Local
Hunk AHash A
Hunk B
Hunk C
Hunk DHash C
Hash B
Git reset 重置:Mixed, Soft, Hard
五、開始使⽤用 Git
⼯工作⽬目錄錄 暫存區域 儲存區
Local
Hunk AHash A
Hunk B
Hunk C
Hunk DHash C
— soft HEAD^
Hash B
Git reset 重置:Mixed, Soft, Hard
五、開始使⽤用 Git
⼯工作⽬目錄錄 暫存區域 儲存區
Local
Hunk AHash A
Hunk B
Hunk C
— soft HEAD^
Hunk D
Hash B
Git reset 重置:Mixed, Soft, Hard
五、開始使⽤用 Git
⼯工作⽬目錄錄 暫存區域 儲存區
Local
Hunk AHash A
Hunk B
Hunk C
Hunk DHash C
Hash B
Git reset 重置:Mixed, Soft, Hard
五、開始使⽤用 Git
⼯工作⽬目錄錄 暫存區域 儲存區
Local
Hunk AHash A
Hunk B
Hunk C
Hunk DHash C
— hard HEAD^
Hash B
Git reset 重置:Mixed, Soft, Hard
五、開始使⽤用 Git
⼯工作⽬目錄錄 暫存區域 儲存區
Local
Hunk AHash A
Hunk B
Hunk C
— hard HEAD^
Hunk D
某些東⻄西完全不不要
Hash B
Git reset 重置:Mixed, Soft, Hard
五、開始使⽤用 Git
⼯工作⽬目錄錄 暫存區域 儲存區
Local
— hard HEAD^
— mixed HEAD^
— soft HEAD^
Git reset 重置:Mixed, Soft, Hard
實作題
提示:

1. 「修改 commit 紀錄錄」

2. 「剛才的 Commit 後悔悔了了,想要拆掉
重做…」
• 回到前⾯面做的 Git-Practice

• 修改你的前⼀一次 commit 紀錄錄為

“Change commit message”

• 建⽴立⼀一個檔案 reset.txt,並使⽤用 vim 添加內容 “I want
to”,將此檔案 commit(commit message 都可)

• 拆掉 commit 把檔案丟回暫存區,並使⽤用 vim 添加內
容 “I want to LEARN GIT!”,commit 檔案,commit
message 為 “Add a dream”

• 現在,現實讓你發現這個夢不不可能會實現了了,你必須
忘了了這個夢,所以直接回到前⼀一個 commit 吧(連
Working Directory 的檔案都不不要了了
實作題答案
• 回到前⾯面做的 Git-Practice

• 修改你的前⼀一次 commit 紀錄錄為

“Change commit message”

• 建⽴立⼀一個檔案 reset.txt,並使⽤用 vim 添加
內容 “I want to”,將此檔案
commit(commit message 都可)

• 拆掉 commit 把檔案丟回暫存區,並使⽤用
vim 添加內容 “I want to LEARN GIT!”,
commit 檔案,commit message 為 “Add
a dream”
為你⾃自⼰己學 Git - Branch 篇
Branch 是什什麼
Branch 是什什麼
Branch 是⼀一種指標,40 字元的 SHA-1 值
⽬目前有哪些分⽀支
⽬目前有哪些分⽀支
$ git branch
如何新增分⽀支、前往分⽀支
如何新增分⽀支、前往分⽀支
$ git branch dog (新增分⽀支)

$ git checkout dog (前往分⽀支)

/ or /

$ git checkout -b dog

(新增並前往分⽀支)
如何刪除分⽀支
如何刪除分⽀支
$ git branch -d cat

$ git branch -D cat (分⽀支尚未 merge)
不不⼩小刪掉還沒 merge 的分⽀支
不不⼩小刪掉還沒 merge 的分⽀支
$ git branch new_dog SHA-1

忘記 SHA-1: $ git reflog
如何更更改分⽀支名字
如何更更改分⽀支名字
$ git branch -m dog wolf
為你⾃自⼰己學 Git - Merge 篇
場景
我從 master 開了了分⽀支 dog

並在 dog 往前推進了了兩個 commits

我要怎麼把 dog 合併(merge) 進 master
場景
我從 master 開了了分⽀支 dog

並在 dog 往前推進了了兩個 commits

我要怎麼把 dog 合併(merge) 進 master
切換到 master: $ git checkout master

將 dog merge 進 master: $ git merge dog
Merge Conflict 分享
Merge Conflict 分享
神秘的 Xcode
Storyboard project.pbxproj
什什麼是 fast-forward
Fast-forward: 不不會產⽣生 commit 的 merge

develop 是從 master 創建出來來的,master 並沒有新的 commit,此時會 fast-forward
不不會有⼩小⽿耳朵
什什麼是 fast-forward
Fast-forward: 不不會產⽣生 commit 的 merge

develop 是從 master 創建出來來的,master 並沒有新的 commit,此時會 fast-forward
$ git checkout master

$ git merge develop
不不會有⼩小⽿耳朵
什什麼是 fast-forward
Not Fast-forward: 兩個 branch 皆各有 commit

或是分出兩個不不同的 branch,如:master 分出 cat & dog,彼此 merge
$ git checkout master

$ git merge develop
不不會有⼩小⽿耳朵
什什麼是 fast-forward
如何不不使⽤用 fast forward 進⾏行行合併
什什麼是 fast-forward
如何不不使⽤用 fast forward 進⾏行行合併
$ git checkout master

$ git merge --no-ff develop
為你⾃自⼰己學 Git - Rebase 篇
Rebase 是什什麼
Rebase 是什什麼
重新定義分⽀支的參參考基準
與 Merge 的差異異是
與 Merge 的差異異是
Rebase 會改變 SHA-1 值,並進⾏行行 fast-forward

Merge 不不會改變 SHA-1 值,會視情況進⾏行行 fast-forward
場景 1
Git pull 時使⽤用 rebase 避免產⽣生新的 commit
場景 1
Git pull 時使⽤用 rebase 避免產⽣生新的 commit
場景 2
Branch 想合併為⼀一個,不不想要產⽣生新的 commit
$ git rebase -i bb0c9c2

Vim: pick 改成 squash,整合進最前⾯面的 pick

儲存 & 離開

Another Vim: 修改整合後的 commit 訊息

儲存 & 離開
1- pick 382a2a5 add database
2- pick cd82f29 add cat 1
3- pick 1de2076 add cat 2
4- pick ca40fc9 add 2 cats
5- pick 2bab3e7 add dog 1
6- pick 27f6ed6 add dog 2
Branch 想合併為⼀一個,不不想要產⽣生新的 commit
1- pick 382a2a5 add database
2- pick cd82f29 add cat 1
3- pick 1de2076 add cat 2
4- pick ca40fc9 add 2 cats
5- pick 2bab3e7 add dog 1
6- pick 27f6ed6 add dog 2
squash
squash
$ git rebase -i bb0c9c2

Vim: pick 改成 squash,整合進最前⾯面的 pick

儲存 & 離開

Another Vim: 修改整合後的 commit 訊息

儲存 & 離開
Branch 想合併為⼀一個,不不想要產⽣生新的 commit
1- pick 382a2a5 add database
2- pick cd82f29 add cat 1
3- pick 1de2076 add cat 2
4- pick ca40fc9 add 2 cats
5- pick 2bab3e7 add dog 1
6- pick 27f6ed6 add dog 2
squash
squash
$ git rebase -i bb0c9c2

Vim: pick 改成 squash,整合進最前⾯面的 pick

儲存 & 離開

Another Vim: 修改整合後的 commit 訊息

儲存 & 離開
Branch 想合併為⼀一個,不不想要產⽣生新的 commit
場景 3
調整 commit 順序
場景 3
調整 commit 順序
$ git rebase -i bb0c9c2

Vim: 直接調整順序

儲存 & 離開
場景 4
修改歷歷史 commit message
怎麼修改歷歷史紀錄錄
怎麼修改歷歷史紀錄錄
$ git rebase -i bb0c9c2

Vim: pick 改成 reword(或 r)

儲存 & 離開

Another Vim: 修改 commit 訊息

儲存 & 離開
怎麼修改歷歷史紀錄錄
$ git rebase -i bb0c9c2

Vim: pick 改成 reword(或 r)

儲存 & 離開

Another Vim: 修改 commit 訊息

儲存 & 離開
怎麼修改歷歷史紀錄錄
$ git rebase -i bb0c9c2

Vim: pick 改成 reword(或 r)

儲存 & 離開

Another Vim: 修改 commit 訊息

儲存 & 離開
怎麼修改歷歷史紀錄錄
$ git rebase -i bb0c9c2

Vim: pick 改成 reword(或 r)

儲存 & 離開

Another Vim: 修改 commit 訊息

儲存 & 離開
怎麼修改歷歷史紀錄錄
$ git rebase -i bb0c9c2

Vim: pick 改成 reword(或 r)

儲存 & 離開

Another Vim: 修改 commit 訊息

儲存 & 離開
更更早 commit 的 SHA-1
場景 5
刪除 commit
場景 5
刪除 commit
$ git rebase -i bb0c9c2

Vim: pick 改成 drop

儲存 & 離開
場景 6
⼀一個 commit 拆成多個 commit
把⼀一個 Commit 拆解成多個 Commit
把⼀一個 Commit 拆解成多個 Commit
$ git rebase -i bb0c9c2

Vim: pick 改成 edit

儲存 & 離開

$ git reset HEAD^
把⼀一個 Commit 拆解成多個 Commit
$ git rebase -i bb0c9c2

Vim: pick 改成 edit

儲存 & 離開

$ git reset HEAD^
把⼀一個 Commit 拆解成多個 Commit
$ git rebase -i bb0c9c2

Vim: pick 改成 edit

儲存 & 離開

$ git reset HEAD^

$ git rebase —continue
$ git status

$ git add cat3.html

$ git commit -m "add cat 3”

$ git add cat4.html

$ git commit -m "add cat 4”
把⼀一個 Commit 拆解成多個 Commit
$ git rebase -i bb0c9c2

Vim: pick 改成 edit

儲存 & 離開

$ git reset HEAD^

$ git rebase —continue
為你⾃自⼰己學 Git - Rebase 篇
番外篇
Reset, Revert, Rebase

有什什麼差別
Reset, Revert, Rebase

有什什麼差別
為你⾃自⼰己學 Git - Tag 篇
如何新增標籤
如何新增標籤
$ git tag big_cats 51d54ff

$ git tag big_cats 51d54ff -a -m "Big Cats are coming"
如何刪除標籤
如何刪除標籤
$ git tag -d big_cats
標籤跟分⽀支有什什麼不不同
標籤跟分⽀支有什什麼不不同
$ cat .git/refs/heads/master
db3bbec63301d1c638e828c9a38a29314c8a0c44
$ cat .git/refs/tags/big_cats
552a844022bad7f24c5e6e3b0fc2528c8ec86df7
• 標籤跟分⽀支都是⼀一種指標

• 也都是放在 .git/refs ⽬目錄錄下

• 分⽀支是在 heads ⽬目錄錄

• 標籤則是在 tags ⽬目錄錄
標籤跟分⽀支有什什麼不不同
實際碰到的問題,想刪遠端 branch 刪不不掉
標籤跟分⽀支有什什麼不不同
//删除 dev_test 分⽀支
git push origin :refs/heads/dev_test
//删除 dev_test 標籤
git push origin :refs/tags/dev_test
解法
實際碰到的問題,想刪遠端 branch 刪不不掉
遠端共同協作 - 使⽤用 GitHub
• 重新建⽴立⼀一個專案(檔案、名稱、位置什什麼的都隨便便)

• 建好之後推到 GitHub
Practice-Git
遠端共同協作 - 使⽤用 GitHub
• $ mkdir Git-Practice

• $ cd Git-Practice

• $ echo “Add sth file” > ./sth.txt

• $ git init

• $ git add sth.txt

• $ git commit -m “Add a file called sth”

• $ git remote add origin git@……

• $ git push -u origin master
Practice-Git
遠端共同協作 - 使⽤用 GitHub
• 複製專案到⾃自⼰己 GitHub 下⾯面,並放到本地端

• 請原專案作者更更改⼀一些東⻄西佈上 GitHub(如果可以)

• 更更新到最新的版本

• 並隨意更更改⼀一點東⻄西推上 GitHub (隨便便編譯器器)

• 發 PR 給原作者
Practice-Git
遠端共同協作 - 使⽤用 GitHub
• GitHub 上 fork 專案

• $ git clone ⾃自⼰己的專案 url

• $ git remote -v

• $ git remote add origin_author 原專案 url

• $ git fetch origin_author

• $ git merge origin_author/master
Practice-Git
• 更更改⼀一點點⽂文件內容

• $ git add sth.txt

• $ git commit -m “Update file”

• $ git push origin master

• Github 上開 PR
遠端共同協作 - 使⽤用 GitHub
Practice-Git
• $ git push -f 會發⽣生什什麼事情

• 本地分⽀支覆蓋遠端分⽀支

• 有⼈人死亡
• --force-with-lease 將解決這種安全問題
遠端共同協作 - 使⽤用 GitHub
Practice-Git
• $ git push -f 會發⽣生什什麼事情

• 本地分⽀支覆蓋遠端分⽀支

• 有⼈人死亡
• --force-with-lease 將解決這種安全問題
遠端共同協作 - 使⽤用 GitHub
Practice-Git
• $ git push -f 會發⽣生什什麼事情

• 本地分⽀支覆蓋遠端分⽀支

• 有⼈人死亡
• --force-with-lease 將解決這種安全問題
遠端共同協作 - 使⽤用 GitHub
Practice-Git
• $ git push -f 會發⽣生什什麼事情

• 本地分⽀支覆蓋遠端分⽀支

• 有⼈人死亡
• --force-with-lease 將解決這種安全問題
Git flow 是什什麼
Git flow 是什什麼
• Master

• Develop

• Hotfix

• Release

• Feature
雙主線
Git flow 是什什麼
• Master

• Develop

• Hotfix

• Release

• Feature
Git flow 是什什麼
右邊沒有看到?
Git flow 是什什麼
• Github flow 是什什麼

• gitflow 將流程建⽴立在 develop 之上是不不必要的,也是所有問題的根源,應單純以 master 為
主。

• gitflow 要求 hotfix 及 release 需要分別 merge 進去 master 及 develop。這個想法製造了了相當
多不不必要的 merge 動作。這邊正確的原則應跟前⼀一點⼀一樣,全部透過 master 來來同步⽐比較簡
潔。

• 從尚未出版的 develop 建⽴立分⽀支,有可能會造成在每次出版週期中應該各⾃自獨⽴立的分⽀支間產
⽣生不不必要的相依性。

• 另外,develop 分⽀支是由 master ⻑⾧長出來來的,所以不不要再有 master 不不能 merge 進
去 develop 這種想法。
Git flow 是什什麼
Git Flow Github Flow
Git flow 是什什麼
• GitHub flow 是什什麼 (以下為推崇 GitHub Flow 的重點)

• gitflow 將流程建⽴立在 develop 之上是不不必要的,也是所有問題的根源,應單純以 master 為
主。

• gitflow 要求 hotfix 及 release 需要分別 merge 進去 master 及 develop。這個想法製造了了相當
多不不必要的 merge 動作。這邊正確的原則應跟前⼀一點⼀一樣,全部透過 master 來來同步⽐比較簡
潔。

• 從尚未出版的 develop 建⽴立分⽀支,有可能會造成在每次出版週期中應該各⾃自獨⽴立的分⽀支間產
⽣生不不必要的相依性。

• 另外,develop 分⽀支是由 master ⻑⾧長出來來的,所以不不要再有 master 不不能 merge 進
去 develop 這種想法。
Git flow 是什什麼
• Github flow vs Git flow

• Git Flow 是以 Release 為基礎的開發流程

• 在開發過中,⼈人每⼀一個儲存庫除了了有 Master 這個主要的分⽀支之外,還會有為不不同 Release 版本設置的
分⽀支、不不同 Feature 的分⽀支

• 等分⽀支出去的新功能完成後,依序再從新功能分⽀支併回 Develop,Release 之後,最後併回 Master 來來
做發⾏行行(Release 有更更新還須 Merge 回 Develop),流程上⽐比較複雜

• Github Flow 是以持續整合 (CI) 開發為⽬目的開發流程

• 可能⼀一天之內就會有多次的部署或發⾏行行

• Github Flow 就只有⼀一個 Master 分⽀支,沒有再分 Release 和 Development 等等的分⽀支,流程上⽐比較簡
單
Git flow 是什什麼
• Github flow vs Git flow

• Git Flow 是以 Release 為基礎的開發流程

• 在開發過中,⼈人每⼀一個儲存庫除了了有 Master 這個主要的分⽀支之外,還會有為不不同 Release 版本設置的
分⽀支、不不同 Feature 的分⽀支

• 等分⽀支出去的新功能完成後,依序再從新功能分⽀支併回 Develop,Release 之後,最後併回 Master 來來
做發⾏行行(Release 有更更新還須 Merge 回 Develop),流程上⽐比較複雜

• Github Flow 是以持續整合 (CI) 開發為⽬目的開發流程

• 可能⼀一天之內就會有多次的部署或發⾏行行

• Github Flow 就只有⼀一個 Master 分⽀支,沒有再分 Release 和 Development 等等的分⽀支,流程上⽐比較簡
單
Git flow 是什什麼
• GitHub flow vs Git flow

• Git Flow 是以 Release 為基礎的開發流程

• 在開發過中,⼈人每⼀一個儲存庫除了了有 Master 這個主要的分⽀支之外,還會有為不不同 Release 版本設置的
分⽀支、不不同 Feature 的分⽀支

• 等分⽀支出去的新功能完成後,依序再從新功能分⽀支併回 Develop,Release 之後,最後併回 Master 來來
做發⾏行行(Release 有更更新還須 Merge 回 Develop),流程上⽐比較複雜

• GitHub Flow 是以持續整合 (CI) 開發為⽬目的開發流程

• 可能⼀一天之內就會有多次的部署或發⾏行行

• GitHub Flow 就只有⼀一個 Master 分⽀支,沒有再分 Release 和 Development 等等的分⽀支,流程上⽐比較
簡單
⾯面試題
⾯面試題
1. 什什麼是 Git?跟 SVN 的差別是什什麼?
⾯面試題
1. 什什麼是 Git?跟 SVN 的差別是什什麼?
SVN 優缺點
優點:
1、 管理理⽅方便便,邏輯明確,符合⼀一般⼈人思維習慣。
2、 易易於管理理,集中式伺服器器更更能保證安全性。
3、 程式碼⼀一致性⾮非常⾼高。
4、 適合開發⼈人數數不不多的專案開發。
缺點:
1、 伺服器器壓⼒力力太⼤大,資料料庫容量量暴暴增。
2、 如果不不能連線到伺服器器上,基本上不不可以⼯工作,看
上⾯面第⼆二步,如果伺服器器不不能連線上,就不不能提交,還
原,對⽐比等等。
3、 不不適合開源開發(開發⼈人數數⾮非常⾮非常多,但是
Google app engine就是⽤用svn的)。但是⼀一般集中式
管理理的有⾮非常明確的許可權管理理機制(例例如分⽀支訪問限
制),可以實現分層管理理,從⽽而很好的解決開發⼈人數數眾
多的問題。
Git 優缺點
優點:
1、適合分散式開發,強調個體。
2、公共伺服器器壓⼒力力和資料料量量都不不會太⼤大。
3、速度快、靈靈活。
4、任意兩個開發者之間可以很容易易的解決衝突。
5、離線⼯工作。
缺點:
1、學習週期相對⽽而⾔言⽐比較⻑⾧長。
2、不不符合常規思維。
3、程式碼保密性差,⼀一旦開發者把整個庫克隆隆下來來就
可以完全公開所有程式碼和版本資訊。
Git 是分散式版本控制系統,起初為了了版控 Linux ⽽而開發的。
⾯面試題
2. Pull 跟 Fetch 有什什麼差別?
⾯面試題
2. Pull 跟 Fetch 有什什麼差別?

git pull 是 git fetch + git merge。

當你使⽤用 pull,Git 會試著⾃自動為你完成⼯工作。Git 會把所有拉取的提交合併到你當前處理理的分⽀支中。

Pull 是⾃自動合併提交⽽而沒有讓你復查的過程。如果沒有細⼼心管理理分⽀支,可能會遇到衝突。
Fetch 是取回遠端更更新,不會對本地執⾏行行 merge 操作,不會去動本地的內容
⾯面試題
3. Fork, Branch, Clone 之間的關係、差別與⽤用途
⾯面試題
3. Fork, Branch, Clone 之間的關係、差別與⽤用途
- Fork

是對存儲倉庫(repository)進⾏行行的遠程的、服務器器端的拷⾙貝,從源頭上就有所區別。Fork 實際上不不
是 Git 的範疇。它更更像是個政治/社會概念。

- Clone

Clone 是個對某個遠程倉庫的本地拷⾙貝。Clone 時,實際上是拷⾙貝整個源存儲倉庫,包括所有歷歷史記
錄錄和分⽀支。

- Branch

是⼀一種機制,⽤用於處理理單⼀一存儲倉庫中的變更更,並最終⽬目的是⽤用於與其他部分代碼合併。
⾯面試題
4. Git HEAD 是什什麼?最後三個 HEAD 分別怎麼表示?

HEAD就是當前分⽀支的游標

形象化:你現在在哪兒,HEAD 就指向哪兒,所以 Git 才知道你在那裡!
最後三個版本:HEAD, HEAD^, HEAD~2
⾯面試題
4. Git HEAD 是什什麼?最後三個 HEAD 分別怎麼表示?

HEAD就是當前分⽀支的游標

形象化:你現在在哪兒,HEAD 就指向哪兒,所以 Git 才知道你在那裡!
最後三個版本:HEAD, HEAD^, HEAD~2
⾯面試題
5. 如何回復復到之前的 commit?

$ git reset SHA-1

// OR //

$ git reset HEAD^ (回到前⼀一個)

$ git reset HEAD~2 (回到前兩個)
⾯面試題
5. 如何回復復到之前的 commit?

$ git reset SHA-1

// OR //

$ git reset HEAD^ (回到前⼀一個)

$ git reset HEAD~2 (回到前兩個)
⾯面試題
6. Git reset 分成哪幾種?差別⼜又是什什麼?
⾯面試題
6. Git reset 分成哪幾種?差別⼜又是什什麼?
⼯工作⽬目錄錄 暫存區域 儲存區
— hard HEAD^
— mixed HEAD^
— soft HEAD^
⾯面試題
7. Git 是什什麼語⾔言寫的?

C 語⾔言,GIT 很快,C 語⾔言通過減少運⾏行行時的開銷來來做到這⼀一點。
⾯面試題
7. Git 是什什麼語⾔言寫的?

C 語⾔言,GIT 很快,C 語⾔言通過減少運⾏行行時的開銷來來做到這⼀一點。
⾯面試題
8. 什什麼是 git cherry-pick?
⾯面試題
8. 什什麼是 git cherry-pick?

挑選⼀一個我們需要的 commit 進⾏行行操作。它可以⽤用於將在其他分⽀支上的 commit 修改,移植到
當前的分⽀支。

常⾒見見的場景:某個穩定版本上,添加⼀一個剛開發完成 Branch 的「部分」功能。就可以使⽤用
Cherry-pick 命令,將這個功能相關的 commit 提取出來來,合入穩定版本的分⽀支上。
基本⽤用法:$ git cherry-pick <commit-id>
⾼高階⽤用法:

$ git cherry-pick -x <commit_id> 保留留原提交的作者信息

$ git cherry_pick <start-commit-id>…<end-commit-id> (不不包含 start)

$ git cherry_pick <start-commit-id>^…<end-commit-id> (包含 start)
⾯面試題
9. 什什麼時候使⽤用「git rebase」代替「git merge」?
⾯面試題
9. 什什麼時候使⽤用「git rebase」代替「git merge」?

這兩個命令都是把修改從⼀一個分⽀支集成到另⼀一個分⽀支上,卻是以⾮非常不不同的⽅方
式進⾏行行。 
原狀狀態(merge or rebase 之前)
Merge
Rebase
1. 取決於你對歷歷史紀錄錄的想法
2. 分⽀支本身是否為有⽤用信息:若有⽤用 merge ,無⽤用 rebase
3. 團隊是否技術夠成熟處理理 rebase?因其為破壞性操作
4. 是否與外部團隊共享或開源,同理理 rebase 破壞原本狀狀態
註:實際狀狀況依照團隊處理理。
⾯面試題
10. 請簡述 Git Flow 流程,與 GitHub Flow 有什什麼差別?
⾯面試題
10. 請簡述 Git Flow 流程,與 GitHub Flow 有什什麼差別?
• Git Flow 使⽤用兩個並⾏行行且⻑⾧長期運⾏行行的分⽀支來來記錄錄項⽬目的歷歷史記錄錄,分別是
master 和 develop

• feature 分⽀支作為功能開發(從 develop 出),完成後會 merge 回 develop
,視情況

• 進版前會開 release 分⽀支做進版前修改,QA 後會將 release 分別 merge 進
master & develop

• GitHub Flow 移除 「develop 分⽀支為主線」的概念,將所有進出放在
master
最後來來碗毒雞湯
如果你覺得⾃自⼰己,整天累得跟狗⼀一樣。

你真是誤會⼤大了了,狗根本沒有你這麼累。
終
於
換
我
當
主
⻆角
了了
︐
ㄎ
ㄎ
資料料來來源
• 為你⾃自⼰己學 Git

• Git 讀書會

• Git 從⼊入⾨門到應⽤用-線上讀書會

• Mac 酷炫 Terminal 樣式 iTerm2 + oh-my-zsh

• 每天使⽤用 Git 的 19 ⼩小技巧

• GIT FAST-FORWARD MERGE

• Git Flow 和 Github Flow 的不不同

• git flow 實戰經驗談 part1 - 別再讓 gitflow 拖累團隊的開發速度

• git flow 實戰經驗談 part2 - 可能更更好的 gitflow

• Cherry-Pick | ⼀一⽇日⼀一 Git

為自己學 Git