第三課 分支合併 (branch & merge)
把練習貼上 FB 社團時請在貼文加上自己的中文名字
Name: CSIE_guest
User ID: guest_DRCN1
Pass: 6BXDZVA3
取消上一個 commit,但是保有 commit 內容
git reset --soft HEAD^
取消上一個 commit,並且刪除 commit 內容
git reset --hard HEAD^
將工作目錄現有的編輯合併到上一個版本
git commit --amend --no edit
要把程式碼回覆到上一個版本的狀態...
git status
git log
若要檢查現在工作目錄的狀態:
在 git 的世界裡,分支 (branch) 是很重要的概念,簡單來說,分支就像是你的程式碼的平行世界,你可能在一個分支上搞砸了,但是不會影響到另一個分支的程式碼
建立分支十分簡單,建立完分支後需要切換到該分支才能開始作業
創立新的分支:
git branch 新分支名稱
切換到該分支:
git checkout 新分支名稱
之後我若要切換到其他的 branch,就可直接下:
git checkout 我要切換到的分支名稱
# 回到預設的分支請輸入:
git checkout master
git log --oneline --graph --all
今天一你不管在一個分支上做了多少開發,終究還是需要把該分支和預設分支 (master) 進行合併,這樣才會把分支上的 commit 納入 master 裡面
開始前,請確保你的跟目錄下沒有 lesson3 這個資料夾,若有,請刪除它
mkdir lesson3
cd lesson3
git init
echo '# hello world!' >> lesson3_1.md
git add lesson3_1.md
git commit -m "added lesson3_1.md"
echo '# hello world!' >> lesson3_2.md
git add lesson3_2.md
git commit -m "added lesson3_2.md"
git branch feature
git checkout feature
echo '# another hello world!' >> lesson3_1.md
git add lesson3_1.md
git commit -m "edit lesson3_1.md"
目前我們已經切換到 feature 分支上,現在我們在 feature branch 上做一個 commit...
git status
接下來檢查一下目前的 commit:
注意最後一個 commit 是在 feature 分支上
git checkout master
我們再用 git log 看一下,此時的 master 應該只有兩個 commit
現在我們回到 master branch 上:
echo '# hello world in lesson3_3.md' >> lesson3_3.md
git add lesson3_3.md
git commit -m "added lesson3_3.md"
此時 master 與 feature 的內容開始出現 "分叉"
接下來我們再創造一個檔案並且做 commit:
若我們用 Sourcetree 來查看目前分支的狀況:
接下來把 feature branch 上面的 commit 合併到 master branch 上:
git merge feature
此時我們已經完成合併,也就是把 feature 分支裡的內容加入 master 分支裡,我們查看一下 Sourcetree:
注意 merge 並非是把 feature 分支的 commit 放入 master 內,而是在 master 上創造一個新的 'merge commit',裡面包含了所有 feature 分支的內容
merge commit 的產生是由於合併的兩個分支都各自擁有不存在另一個分支的 commit,若不希望 merge commit 出現,可以先 '更新' feature 分支的內容,確保 feature 分支擁有 master 分支所有的內容,接下來我們就來實際操作一次
創造另外一個分支 - feature2,並且在裡面做一個 commit
git branch feature2
git checkout feature2
echo '# hello world in lesson3_4.md' >> lesson3_4.md
git add lesson3_4.md
git commit -m "added lesson3_4.md"
接下來我們切換回 master branch,並且也再做一個 commit:
git checkout master
echo '# hello world in lesson3_5.md' >> lesson3_5.md
git add lesson3_5.md
git commit -m "added lesson3_5.md"
此時 Sourcetree 的狀態應該是:
接下來我們切換回 master branch,並且也再做一個 commit:
git checkout master
echo '# hello world in lesson3_5.md' >> lesson3_5.md
git add lesson3_5.md
git commit -m "added lesson3_5.md"
此時 Sourcetree 的狀態應該是:
接下來我們切換回 feature branch,並且使用 git rebase
把 master 分支的 commit 更新到
git checkout feature2
git rebase master
此時 feature2 分支的 commit 會被重新 commit 到 master 最新的 commit 之後,因此在 Sourcetree 的圖會呈現一條線:
re - 從新
base - 基礎
重新改變一個分支的基礎至母分支的最新版本
最後我們就可以進行 merge 了:
git checkout master
git merge feature2
此時我們已經不需要 feature2 分支,我們可以刪除它
git branch -d feature2
剛才我們經歷了無痛合併,也就是兩個分之沒有任何需要處理的 "衝突",接下來我們就來理解什麼是 git 的衝突
接下我們再開出另一個 feature branch:
git branch feature4
git checkout feature4
接下來在我們的 feature4 branch 上對 lesson3_2.md 進行修改並且 commit
echo '# this is my second line of code' >> lesson3_2.md
git add lesson3_2.md
git commit -m "edited lesson3_2.md"
接下我們回到 master branch 上:
git checkout master
接下來在我們的 master branch 上對 lesson3_2.md 進行修改並且 commit:
echo '# this is my second line of code on master branch' >> lesson3_2.md
git add lesson3_2.md
git commit -m "edited lesson3_2.md on master"
此時我們若執行 git merge
git merge feature4
就出錯啦!原因是今天在 merge 的狀態下,若兩個分支裡的同一個檔案的同一行是不相同的,就會產生衝突 (conflict)!
面對 conflict,我們能做的事就是找出發生衝突的程式碼的作者,討論後寫出兩者都同意的版本,並且手動把衝突的地方修好並做 commit
# hello world!
<<<<<<< HEAD
# this is my second line of code on master branch
=======
# this is my second line of code
>>>>>>> feature2
從 <<<<<<< HEAD 到 ======= 的內容,HEAD 代表當前 master 分支的最新版 lesson3_2.md 內容
從 ======= 到 >>>>>>> feature2 的內容,代表 feature2 分支裡的 lesson3_2.md 內容