1-介紹 git commit
1-1-說明
一個 commit 在 git repo 中會記錄目錄下所有文件的快照。感覺像是大量的複製和貼上,但 git 的速度更快!
git 希望 commit 儘可能地不占空間,所以每次進行 commit 的時候,它不會單純地複製整個目錄。實際上它把每次 commit 視為從目前的版本到下一個版本的變化量,或者說一個 “(delta)”。
git 會保存 commit 的歷史紀錄,所以,絕大部分的 commit 的上面都會有 parent commit,在我們的圖形表示中,箭頭方向表示從 parent commit 到所對應的 child commit,保存這樣子的一個歷史紀錄是非常有用的。
要學的東西有很多,但現在你可以把 commit 當作是當下的 project 的快照。commit 不佔空間且可以快速切換!
1 | git commit |
看吧!很厲害!我們對於文件做了一些修改,並且把這些修改表示成一個 commit。剛剛做的 commit C2 有一個 parent commit C1,代表此次修改是從那裡過來的
1-2-解題
接下來你可以隨便測試。當目前的視窗關閉之後,輸入兩次 commit 就可以過關!
1 2 | git commit git commit |
2-建立 git branch
2-2-說明
git 的 branch 非常不佔空間。它們只是一個指向某個 commit 的 reference,就這麼簡單。所以許多 git 的愛好者會建議:
早點建立 branch!經常建立 branch!
因為建立 branch 不怎麼會佔用到硬碟空間或者是記憶體,所以你可以把你目前的工作分成好幾個 branch,這比只用一個 branch 要來的好。
同時使用 branch 和 commit 時,我們待會可以看到兩者如何配合。現在,只要記住使用 branch 其實就是在說:「我想要包含這一次的 commit 以及它的所有 parent 的 commit。」
舉一個例子來看看 branch 到底是什麼。
這裡,我們建立一個名稱為 newImage 的新的 branch。
1 | git branch newImage |
看吧!這就是建立 branch 所需的操作啦! newImage branch 現在指向 commit C1。
現在讓我們這個新的 branch 做一些操作。點擊下面的按鈕。
1 | git commit |
太奇怪了啦! master branch 前進了,但 newImage branch 沒有前進!這是因為我們沒有「在」這個新的 branch 上,這也是為什麼星號(*)會在 master 上。
使用如下指令告訴 git 我們想要切換到新的 branch , git checkout [name] 這可以讓我們在 commit 之前切換到新的 branch。
1 2 | git checkout newImage git commit |
太好了!新的 branch 已經記錄了我們的修改。
2-2-解題
好啦,你已經準備好使用 branch 了。當目前的視窗關閉後, 建立一個叫 bugFix 的新的 branch,然後切換過去。
1 2 | git branch bugFix git checkout bugFix |
3-git 中的 merge
3-1-說明
3-1-1-branch 以及 merge
太好了! 我們已經知道怎麼使用 commit 和 branch 了。接下來要學的一招是如何合併(merge)兩個不同 branch 的工作。這讓我們可以建立一個新的 branch ,並且在上面開發新功能,然後合併回 master branch。
git merge 是我們要學習 merge 的第一個方法。該 merge 會產生一個特殊的 commit,它包含兩個唯一 parent commit。一個 commit 如果有兩個 parent commit 的話,那就表示:「我想把這兩個 parent commit 本身及它們的 所有的 parent commit 都包含進來。」
有圖有真相,看看下面的圖就明白了。
在這裡,我們有兩個 branch:各自都有一個唯一的 commit。這意味著沒有一個 branch 包含我們對文件的所有修改。讓我們 merge 這兩個 branch 來解決這個問題。
我們要 merge bugFix 到 master
哇!看見了沒有?首先, master 現在指向一個 commit,這個 commit 有兩個 parent commit。假如從 master 開始沿著箭頭向上走,在到達起點的路上會經過所有的 commit。這說明了現在 master 紀錄了對文件的所有修改。
還有,看見各個 commit 的顏色變化了嗎?為了幫助學習,我混合了顏色。每個 branch 都有特定的顏色。每個 commit 的顏色都變成了含有此 commit 的所有 branch 的混合色。
所以, master branch 的顏色被混入到所有的 commit,但 bugFix 沒有。接下來就改一下這裡吧。
讓我們 merge master branch 到 bugFix 吧。
1 2 | git checkout bugFix git merge master |
因為 bugFix branch 只是 master branch 的 parent,git 什麼都不用做,只是簡單地把 bugfix branch 移動到 master 指向的 commit。
現在所有的 commit 的顏色都是一樣的啦,這表示每一個 branch 都包含了所有文件的修改!太厲害了啦!
3-2-解題
想完成這一關,執行以下的操作:
– 建立新的 branch,叫做 bugFix
– 用 git checkout bugFix 切換到 bugFix branch
– commit 一次
– 用 git checkout 切換回 master branch
– 再 commit 一次
– 用 git merge 將 bugFix merge 到 master
1 2 3 4 5 6 | git branch bugFix git checkout bugFix git commit git checkout master git commit git merge bugFix |
1 2 3 4 5 | git checkout -b bugFix git commit git checkout master git commit git merge bugFix |
git checkout -b bugFix 的參數 -b 是指 build (建立),在切換分支時同時建立新分支與命名。
資料來源:3.2 Git 分支 – 分支的新建与合并-新建分支
4-介紹 rebase
4-1-說明
4-1-1-git rebase
rebasing 是 merge branch 的第二種方法。 rebasing 就是取出一連串的 commit,”複製”它們,然後把它們接在別的地方。
雖然聽起來難以理解,rebasing 的優點是可以建立更線性的 commit history。假如只允許使用 rebasing 的話,則我們的 repo 中的 commit log 或者是 commit history 會更加簡潔好看。
4-1-2- HAED 於目前分支上直接指定另外分支名
這裡,還是有兩個 branch;注意目前我們所在的 branch 是 bugFix(看那顆星啦)
我們想要把在 bugfix 所做的修改直接移到 master branch上。使用 rebasing 的話,兩個 branch 看起來像是依序按順序進行修改,實際上它們的修改是平行進行的。
用 git rebase 來實現吧
1 | git rebase master |
很厲害吧!現在 bugFix branch 上的工作在 master branch 的最前端,同時我們也得到了一個更加線性的 commit 順序。
注意,本來的 commit C3 沒有消失(在圖上面呈現陰影),而我們”複製” C3,將它的副本 C3′ 接在 master branch 的後面。
現在唯一的問題是 master branch 還沒有更新…我們接下來就更新它吧!
4-1-3-同線同基底上使用 rebase 將 commit 同步
現在,切換到 master branch。接下來就把它 rebase 到 bugFix 上面吧…
1 | git rebase bugFix |
完成!因為 master branch 是 bugFix 的 parent,所以 git 只是把 master branch 往前移動到 bugFix 上。
4-2-解題
想完成這一關,執行以下操作:
– 建立 bugFix branch
– commit 一次
– 切換回 master branch 再 commit 一次
– 再次切換到 bugFix branch,接著 rebase bugFix 這個 branch 到 master branch 上
1 2 3 4 5 6 | git branch bugFix git checkout bugFix git commit git checkout master git commit git rebase master bugFix |
將 bugFix 與 master 分支各建 C2 與 C3 的 commit 點出來,接著使用 git rebase master bugFix 指令,指令是指以 master 目前的 commit 點為基底,將 C1 到 bugFix commit 點接過來。