[第一週]版本控制與 Git 基本指令

MiaHsu
13 min readMar 5, 2020

--

學習目標:了解 git 是什麼,如何安裝,以及學習本地端(localrepo)版本控管與 Git 基本概念指令(本地端操作:add、commit、checkout 等)

本文主要源自以下資料的學習整理:

版本控管(Version Control System)的概念

以設計的角度看版本控管:

在做設計時常常會遇到客戶東改西改的需求,就會把每個版本都保存起來,以免客戶說「還是回到那個綠色的版本好了!」然後你打開資料夾…

  • 主視覺_200303.ai
  • 主視覺_200304.ai
  • 主視覺_final.ai
  • 主視覺_final_200307.ai
  • 主視覺_final_200310.ai

哪個是綠色版本啦QAQ

以工程師的角度看版本控管:

剛剛設計師的版本控管屬於一個人的版本控管,而工程師的版本控管是通常屬於多人的版本控管 。

現在雲端上有個穩定的版本 v3 ,而會有設計、前端及後端會更改這個版本的檔案。

某天設計接到圖片跟樣式要更新的需求,就拿到本地端改成 v4,同時前端與後端都在持續開發中的 v4,現在在個別的電腦中都有一份 v4,要如何統整所有人的檔案呢?這時候就需要軟體的版本控管了,而軟體控管又可以分為為中央式系統(例如:SubversionCVS 等)與分散式系統(例如:GitBitKeepermercurial 等)。

  • 中央式系統
    主要在一個伺服器上進行,由中央管理權限進行「上鎖」,一次只能讓一個開發者進行工作。
  • 分散式系統
    讓開發者在沒有網路的情況下也能進行工作,也讓開發者有充分的控制能力,不需經過中央許可,並且也向中央式系統一樣有上鎖的能力,因此相較來說彈性更大。

是一個分散式版本控制的軟體,擁有非常齊全的功能管理好檔案的所有版本,在開發上也提供了可以同時保留不同功能版本,以利於之後的合併,例如:主要的穩定版 、 開發新功能版 、 修 bug 版。

出自:Git 與 Github 版本控制基本指令與操作入門教學

如果想多了解 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
  • 安裝 git 時會附帶一個 config 工具,讓我們可以取得及設定組態參數,會有一個總體設定,而每個專案也有自己的 config。
  • 變化型:
    1. 列出目前設定的參數: git config --list
    2. 設定使用者名稱及信箱(總體):
    git config --global user.namegit 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'
出自:Git 與 Github 版本控制基本指令與操作入門教學

Q:一定要先 add 再 commit 這麼麻煩嗎?能不能快速 commit?

A:可以在執行 commit 時增加 -a $ git commit -am “update”
這樣就可以快速 commit 了。 #此指令對新加入的檔案無效

檢視 commit 紀錄

git log

  • 越新的資訊會在越上面,由上到下的資訊為下圖:
  • 寫法:$ 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>

git reset

  • 將暫存區(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 是一種分散式的版本控管,可以幫助我們清楚的紀錄檔案的所有版本,他的優點在於:

  • 開源免費。
  • 速度快、體積小。
  • 分散式系統,每個人都有一個自己的版本控制。
  1. 本地端又分為:工作目錄(Working Directory)、暫存區(Stating Area)、本地端檔案庫(local repo)
  2. 初始化 git: $ git init
  3. 刪除 .git,讓此資料夾沒有 git :$ rm -r .git
  4. 將檔案加入暫存區(Stating Area): $ git init <file>
  5. 查看狀態: $ git status
  6. 將暫存區(Stating Area)進行版控: $ git commit 'message'
  7. 檢視紀錄: $ git log
  8. 切換版本: $ git checkout <版本號>
  9. 不想要加入版本控制的檔案:將檔案寫入 .gitignore 此檔案也必須 commit
  10. 比較差異: $ git diff

Git 系列文章

  1. [第一週]版本控制與 Git 基本指令
  2. [第二週]Git 進階使用 Branch、Merge
  3. [第二週]Git 本地端連結遠端操作(GitHub)

--

--