學習目標:了解 git 是什麼,如何安裝,以及學習本地端(localrepo)版本控管與 Git 基本概念指令(本地端操作:add、commit、checkout 等)
本文主要源自以下資料的學習整理:
- 為自己學 git
- Git 與 Github 版本控制基本指令與操作入門教學
- Learn-Git-in-30-days
- [GIT101] Git 超新手入門
- [第一週] 版本控制 — 原理 & 基本 Git 指令
版本控管(Version Control System)的概念
以設計的角度看版本控管:
在做設計時常常會遇到客戶東改西改的需求,就會把每個版本都保存起來,以免客戶說「還是回到那個綠色的版本好了!」然後你打開資料夾…
- 主視覺_200303.ai
- 主視覺_200304.ai
- 主視覺_final.ai
- 主視覺_final_200307.ai
- 主視覺_final_200310.ai
哪個是綠色版本啦QAQ
以工程師的角度看版本控管:
剛剛設計師的版本控管屬於一個人的版本控管,而工程師的版本控管是通常屬於多人的版本控管 。
現在雲端上有個穩定的版本 v3 ,而會有設計、前端及後端會更改這個版本的檔案。
某天設計接到圖片跟樣式要更新的需求,就拿到本地端改成 v4,同時前端與後端都在持續開發中的 v4,現在在個別的電腦中都有一份 v4,要如何統整所有人的檔案呢?這時候就需要軟體的版本控管了,而軟體控管又可以分為為中央式系統(例如:Subversion、CVS 等)與分散式系統(例如:Git、BitKeeper、mercurial 等)。
- 中央式系統
主要在一個伺服器上進行,由中央管理權限進行「上鎖」,一次只能讓一個開發者進行工作。 - 分散式系統
讓開發者在沒有網路的情況下也能進行工作,也讓開發者有充分的控制能力,不需經過中央許可,並且也向中央式系統一樣有上鎖的能力,因此相較來說彈性更大。
是一個分散式版本控制的軟體,擁有非常齊全的功能管理好檔案的所有版本,在開發上也提供了可以同時保留不同功能版本,以利於之後的合併,例如:主要的穩定版 、 開發新功能版 、 修 bug 版。
如果想多了解 git 的各種優點,可以詳讀:為自己學 git,非常全面詳細的說明如何用 CLI 及 GUl 介面操作 git,也補充非常多的狀況題,有時候工作上碰到忘記的指令就會翻翻,非常推薦大家買起來。
以下會直接以實作來了解指令:
安裝 git
方法一、官網下載
適用:windows、Mac OS X
跟一般的軟體安裝方式相同:下載、安裝、執行。
方法二、Homebrew 下載
適用:Mac OS X
Homebrew是一款自由及開放原始碼的軟體套件管理系統,用以簡化 macOS系統上的軟體安裝過程。
Step.1 在終端機上輸入以下指令就可以安裝
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homwbrew/install/master/instakk.sh)"
Step2. 接著安裝 git 輸入
$ brew install git
Step3. 檢查 git 版本
$ git --version
設定使用者
$ git config
- 安裝 git 時會附帶一個 config 工具,讓我們可以取得及設定組態參數,會有一個總體設定,而每個專案也有自己的 config。
- 變化型:
1. 列出目前設定的參數:git config --list
2. 設定使用者名稱及信箱(總體):git config --global user.name
、git config --global user.email
如果已經有 GitHub 帳戶的話可以設定與帳戶相同的 name 及 mail
[補充說明] 為每個專案設定不同的 user 資料
如果指定不同名字或信箱在特定的專案中(例如:公司跟個人分開)就只要在專案資料夾底下輸入此指令(注意!就不用加 --global 參數)就為此專案額外設定使用者資訊。
開始 Git 之(本地端)
以步驟的方式說明最基本的 git 的相關指令。
Step1. 先開一個資料夾吧!
- 首先在 desktop 新增一個 git_test 的資料夾:
$ mkdir git_test
Step2. 將資料夾初始化 git
- 讓 git 開始對這個資料夾進行版控:
$ git init
進行版控後,Git 會在這個資料夾內新增隱藏的資料夾 .git
裡面包含了系統檔
[補充說明1] 為什麼我看不到隱藏檔案?Mac 預設是看不到隱藏檔案的。 #想要顯示隱藏檔案可以參考:三招讓 Mac 顯示出隱藏檔案
[補充說明2] 要如何停止版本控制?刪除 .git: $ rm -r .git
Step3. 時常檢查狀態,永保安康
$ git status
隨時檢查目前檔案的情況,才不會發生推不上去拉不下來的情況!
Step4. 在目錄裡新增兩個檔案
- 可以透過 GUI 直接移入
- 或透過 Terminal
$ echo ‘hello, git’ > welcome.html
、$ echo ‘body{margin:0;}’ > style.css
- 再次查看 git 狀態
$ git status
git 很貼心的說明:nothing added to commit but untracked files present (use “git add” to track)
沒有添加任何內容提交但存在未跟踪的文件(使用“ git add”進行跟踪)
雖然我們將檔案加入到資料夾了,但這些檔案還沒有交給 git 進行版控。
step5. Pick me pick me pick me up
- 決定哪些檔案是否加入版本控制,把檔案交給 git 追蹤:
$ git add <file>
- 再次查看 git 狀態
$ git status
可以看到被分成兩個區塊,一個「有」版控的區塊叫做「暫存區」(Staging Area)的一個是「沒有」版控的區塊叫做「工作目錄」(working directory)的。
區塊內都有提示說要怎麼取消跟加入。
- 取消追蹤:
$ git rm --cached <file>
[補充說明] 暫存區 Staging Area 在 sourcetree 內被稱作 index。
- 小訣竅:
1. 如果資料夾內有很多檔案,可以使用$ git add .
,就可以把當前路徑的檔案全部加入版控。
2. 若想要將目錄(資料夾)底下的全部加入,可以使用$ git --all
[情況1] 若在 git add 之後又修改了檔案的內容這時候需要再一次執行 $ git add ,後續才能把第二次修改的部分一起 commit
step5. 新建一個版本
- 加入本地端儲存庫:
$ git commit
- 輸入之後會跳到 VIM 編輯你的版本訊息 #超簡單 VIM 操作,如果覺得太麻煩可以在 commit 的時候一次完成:
$ git commit -m '版本訊息'
- 變化型:
1.--amend
修改最後一次 commit 的訊息 #若再後方加上-m
就不會跳 VIM 囉。舉例:$ git commit -amend -m “edit commit message”
[情況] 追加檔案到最近的 commit
有時候會遺漏掉某些檔案沒有上傳,又不想再推一次造成很多細碎的 commit 可以這樣做:step1. 先將遺漏的檔案放入暫存區 $ git add hi.htmlstep2. 接著合併最後次 commit $ git commit --amend --no-edit補充說明:修改了一次歷史,可能會造成協作同事的困擾(拿刀),所以 push 到遠端之後就不要這樣做。
當完成 commit 這個動作後,就是成功把放在暫存區(Staging Area)的東西放到儲存庫(Repository)裡囉!
到這邊先暫停一下,回到 git 的基本觀念 🔙
以上的步驟就是在本地端(local)上傳的整個流程
本地端又分為:工作目錄(Working Directory)、暫存區(Stating Area)、本地端檔案庫(local repo)
- Working Directory ➡️ Stating Area:
$ git add <file>
- Stating Area ➡️ local repo:
$ git commit <file>
- Working Directory ➡️ local repo:
$ git commit -am 'message'
Q:一定要先 add 再 commit 這麼麻煩嗎?能不能快速 commit?
A:可以在執行 commit 時增加 -a
$ git commit -am “update”
這樣就可以快速 commit 了。 #此指令對新加入的檔案無效
檢視 commit 紀錄
- 越新的資訊會在越上面,由上到下的資訊為下圖:
- 寫法:
$ git log <版本號>
[補充說明] 版本號都是使用 SHA-1(Secure Hash Algorithm 1)的演算法計算的結果,可以想像成每個 commit 底身份字號,以利於往後查找及回溯。
- 變化型
1. 輸出更簡潔的 log:$ git log —-oneline
。
2. 檢視特定檔案的 commit:$ git log <file>
# 如果想要看詳細的修改內容 可再加上參數-p
。
3. 檢視特定作者的 commit:$ git log --author="Mia"
# 如果想要找兩人以上"Mia\|Ben"
。
4. 檢視包含特定字串的 commit :$ git log --grep="string"
。
5. 檢視特定區間的 commit:$ git log --since="9am" --until="6pm"
。
git 其他常用指令
git rm (remove)
- 請 git 幫你刪除檔案,對 git 來說刪除也是一種修改。
- 寫法:
$ git rm <fileName>
- 舉例:
$ git rm welcome.html
- 變化型:
1.--cached
:讓檔案不再受 git 版控(並不是刪除!),舉例:$ git rm --cached welcome.html
git mv (move)
- 請 git 幫你變更檔名,跟刪除檔案雷同,對 git 來說更改檔名也是一種修改。
- 寫法:
$ git mv <originFileName> <newFileName>
- 舉例:
$ git mv welcome.html hello.html
git checkout
- 切換版本/分支,跟檢視狀態一樣是非常常用到的指令!可以借由輸入版本號切換到任何 commit 過的版本。
- 寫法:
$ git checkout <版本號/分支名>
- 舉例:
$ git checkout bb2e45db8c6bdc75f1035d78f46e09f88609e5dc
- 小訣竅:
1. 切換到最新版本:$ git checkout master
- 變化型:
1. 取消暫存檔上的變更:$ git checkout --
2.不小心把檔案或目錄刪掉了:$ git checkout <fileName>
[補充說明] 使用 checkout 把刪除的檔案救回來的底層運作當 checkout 後面接的是檔名或路徑時,會從 .git 目錄將暫存區(Stagung Area)的內容或檔案覆蓋到目前工作目錄(Working Directory)
git diff (different)
- 比對工作目錄(Working Directory)與暫存區(Stating Area)全部檔案的差異。
- 寫法:
$ git diff
- 變化型:
1. 比對工作目錄與暫存區(Stating Area)全部檔案的差異:$ git diff --cached
2. 比對當前文件與暫存區(Stating Area)全部檔案的差異:$ git diff <filename>
3. 比對工作目錄(Working Directory)與指定 commit 之間的差異:$ git diff <commit-id>
4. 比對兩個 commit 之間的差異:$ git diff <commit-id> <new commit-id>
5. 比對兩個 branch 之間的差異:$ git diff <branch1> .. <branch2>
- 將暫存區(Stating Area) 恢復到 工作目錄(Working Directory)
- 寫法:
$ git reset
- 變化型
1. 將上一次到本地端檔案庫(local repo)的 commit,恢復到暫存區(Stating Area):$ git reset HEAD^
2. 直接刪除上一次到本地端檔案庫(local repo)的 commit:$ git reset HEAD^ — hard
忽略不要版本控制的檔案
有些比較機密或程式編譯的中間檔或暫存檔(想知道一般 .gitignore 會紀錄哪些檔案,可以參考 Huli 舉出 Facebook 的開源專案 React 裡的 .gitignore 示範。),其實是不太需要備份的,因為對專案來說沒有實質的利用價值,如果使用 git add . 提交所有檔案,又會把這些的檔案 add 進來,因此可以在專案目錄中放一個 .gitignore 檔案,並且設定想要忽略的規則就可以了
$ touch .gitignore
然後就可以將不需要的檔案寫在文件內並記得 $ git commit .gitignore
以下是可以參考的寫法:
- 忽略單一檔案: node_modules
node_modules
- 忽略特定資料夾:dist
packages/react-devtools-core/dist
- 忽略特定副檔名:.crx
*.crx
重點整理
git 是一種分散式的版本控管,可以幫助我們清楚的紀錄檔案的所有版本,他的優點在於:
- 開源免費。
- 速度快、體積小。
- 分散式系統,每個人都有一個自己的版本控制。
- 本地端又分為:工作目錄(Working Directory)、暫存區(Stating Area)、本地端檔案庫(local repo)
- 初始化 git:
$ git init
- 刪除 .git,讓此資料夾沒有 git :
$ rm -r .git
- 將檔案加入暫存區(Stating Area):
$ git init <file>
- 查看狀態:
$ git status
- 將暫存區(Stating Area)進行版控:
$ git commit 'message'
- 檢視紀錄:
$ git log
- 切換版本:
$ git checkout <版本號>
- 不想要加入版本控制的檔案:將檔案寫入
.gitignore
此檔案也必須 commit - 比較差異:
$ git diff