# 前言 何謂版本控制系統? 版本控制系統(Version Control System),主要用於控制與管理程式碼的版本。 為什麼需要版本控制系統? 舉例來說,以往沒有使用版本控制系統時,每次的程式異動,只能以複製專案目錄的方式進行程式備份,但長期下來整個儲存區會過於雜亂,且不易比對版本間的程式碼差異,也不便於多人同時進行開發,整體效率低下且過度消耗儲存空間。  而『版本控制系統』是以快照或差異方式儲存不同版本間的差異,除了不會過度消耗儲存空間外,也可以有效紀錄每次新增、修改、刪除了哪幾行程式碼,進行版本提交時,也能註明修改目的、負責的工程師等資訊。  ## 優點 1. 方便管理程式碼版本,避免傳統雜亂的複製專案目錄控制版本。 2. 可紀錄每次程式異動,是由哪位工程師修改的程式碼 3. 同時接收多個需求時,可建立不同的分支(branch),讓多個工程師同時進行作業,加速整個團隊的開發效率 4. 可快速的比對兩個版本的程式碼差異 ## 缺點 1. 如遇cmd指令較多的版本控制系統,沒有使用其他GUI輔助的話,較難上手 </br> # Git Git是一種分散式的版本控制系統,除了呼叫傳統的遠端儲存庫(Remote Repository)外,分散式架構讓每個工程師可以在自己的PC或NB中,建立本機儲存庫(Local Repository),方便工程師在沒有網路連線的時候,或是多人同時開發時,可以不受外在因素的影響持續進行開發。  # Storage(儲存區) Git的儲存大致可區分為<u>Working Directory</u>、<u>Staging Area</u>、<u>Local Repository</u>、<u>Remote Repository</u>等四個儲存區。 * Working Directory(工作目錄) 工程師平時開發的工作目錄 * Staging Area(暫存區) 暫存欲`commit`檔案的儲存區 * Local Repository(本機儲存庫) 每位工程師NB/PC所儲存的個人儲存庫(.git資料夾) * Remote Repository(遠端儲存庫) 團隊共用儲存於伺服器上的遠端儲存庫,如:GitHub、GitLab等  # Git 常用指令 git的所有指令數量比較多,而實際常用的指令大概只佔其中一部分,簡單列出一些普遍常用的指令 * `git init` 初始化Git * `git remote -v` 查詢所有已配置的Remote Repository及其URL 以下<remoteName>皆為別名,方便使用者操作,非實際Remote Name * `git remote add <remoteName> <remoteUrl>` 新增Remote Repository及其URL * `git clone <remoteUrl>` 將Remote Repository的程式<span style="font-weight: bold;color: red;">複製</span>到Local Repository以及Working Directory。 Clone的Remote Repository,預設會命名為`origin` * `git pull <remoteName> <branchName>` 將Remote Repository的程式<span style="font-weight: bold;color: red;">同步</span>到Local Repository以及Working Directory。 實質為 `git fetch` + `git merge`,`merge`方式為`fast-forward` * `git fetch <remoteName> <branchName>` 將Remote Repository下載至Local Repository * `git checkout <branchName>` or `git checkout <commit-hash>` 將終端機切換至指定Branch或Version * `git add <folderPath>` or `git add <fileName>` 將指定的資料夾或檔案,新增至Staging Area。 通常使用`git add .`將所有異動新增至暫存(含子目錄),舊版Git使用`git add --all` * `git commit -m <message>` 將指定的異動檔案,提交至Local Repository * `git push <remoteName> <branchName>` 將指定的異動檔案,推送至伺服器上的Remote Repository * `git status` 查看目前異動的檔案狀態 * `git log` 查看歷史的異動日誌 * `git reset` 復原`git commit`的提交,可分為<u>mixed</u>、<u>soft</u>、<u>hard</u>三種模式。 * <p>--mixed</p> 預設,刪除暫存區的檔案,工作目錄的檔案不變。原先Commit的檔案會復原至工作目錄。 * <p>--soft</p> 暫存區及工作區的檔案皆不刪除,原先Commit的檔案會復原至暫存區。 * <p>--hard</p> 暫存區及工作區的檔案皆刪除。  * `git branch` 可進行分支相關的操作,如:新增、刪除或查詢分支等。 * `git merge <branchName>` 將指定branch合併到當前分支。 `git branch`與`git merge`指令的基本操作,可以參考[這篇文章](https://hackmd.io/@Lion-Le/rJOHUpXTR) </br> * `git rebase <branchName>` 以類似「移植」的方式合併分支,比較像直接修改分支的歷史提交紀錄。 `git merge`與`git rebase`的差異,可以參考[這篇文章](https://hackmd.io/@Lion-Le/BJCUrBnTC) </br> 若某功能開發到一半時,需緊急修復線上Bug問題,可以使用`git stash`方式保存目前所有的異動內容。 * `git stash` 保存目前暫存目錄(Staging Area)的所有檔案 * `git stash list` 查看已`git stash`的清單 * `git stash pop` 取出保存的檔案 * `git stash drop` 清除最近一次的`git stash` * `git stash clear` 清除所有的`git stash` </br> 如果覺得指令不易熟記或操作不方便,也可以參考Git官方推薦的一系列GUI(圖形化使用者介面)軟體 (https://git-scm.com/downloads/guis) 如:GitHub Desktop、SourceTree等  ## 指令Q&A Q. `git fetch`與`git pull`兩者差在哪? A. `git fetch`是將Remote Repository的程式下載回Local Repoesitory,而 `git pull` 則是 `git fetch` + `git merge`,以`fast-forward`的方式進行`merge`。 如果不想以fast-forward的方式merge,可以先執行`git fetch`指令,再自行處理merge。 </br> Q. `git clone`與`git pull`兩者差在哪? A. `git clone`主要用於本機第一次建立該專案的時候.若本機已有該專案,只是需要同步成Remote Repository的版本,則使用`git pull`進行同步。 </br> Q. 要推送至Remote Repository時,發現Commit太多次,想紀錄乾淨點,可以如何處理? A. `git reset`拆掉重新commit,或是用`git rebase`合併 </br> Q. 一般的merge與使用`fast-forward`的merge差在哪? A. `fast-forward`主要用於指定合併分支是基於當前分支出去的最新提交,並且當前分支也沒有新的提交時,可使用`fast-forward`合併,合併後歷史為線性呈現。 一般方式的合併用於當前分支也有新版本時,會產生一個新的合併提交,合併後仍保留原合併分支的結構,詳細可參考[這篇文章](https://hackmd.io/@Lion-Le/BJCUrBnTC)。 </br> # File LifeCycle(檔案生命週期) 依據上述指令,可將異動的檔案推送至不同階段的儲存區,而不同階段的檔案,也各有不同的狀態,使用`git status`指令可以確認目錄中每個檔案的狀態,主要分為<u>Changes to be committed</u>、<u>Changes not staged for commit</u>、<u>Untracked files</u>等三種狀態。  # 總結 簡單統整了Git的概念、常用指令、儲存流程及檔案生命週期等。 與其他版本控制系統相比,如:TFS、CVS、SVN等。Git最大優勢在於可以很容易的與GitHub、GitLab等系統整合,其過程不需使用其他任何工具。 同時Git的分散式系統架構,可以在本機環境保存一份完整的Repository,並且涵蓋所有歷史版本,讓工程師可以自由在本機進行開發、暫存(commit/stash)、分支或合併等操作,不受任何外在因素的影響。 若使用傳統的集中式架構,則需仰賴Remote Server,本機環境通常只會保留當前的檔案狀態,而歷史版本則保存在Remote Server上,在無法連線至Remote Server的情況下,會大幅度地影響到工程師的開發。 並且集中式的系統架構,通常只能在Working Directory保有一個異動的版本,無法像集中式的系統架構,可以在本機環境做到保有多個異動版本。 </br> # 參考資料 https://git-scm.com/book/en/v2/Getting-Started-What-is-Git%3F https://git-scm.com/book/en/v2/Git-Basics-Recording-Changes-to-the-Repository https://git-scm.com/docs/git-stash https://gitbook.tw/chapters/using-git/working-staging-and-repository https://gitbook.tw/chapters/branch/merge-with-rebase </br> >[!Tip] 文章內容皆為個人整理的觀點,以及整理後的個人想法,如內容有錯誤或疑慮的部分,歡迎提出討論,收到後會盡快修正!
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up