Git 入門指南
git
是如今最為著名的
DVCS (Distributed Version Control Systems),它是由被稱為「Linux 之父」的
「Linus Torvalds」
先生於 2005 年製作的。git
不但有強大的功能,更是一個不妥協的產物,其誕生的歷史融合了計算機大師的自嘲和自由軟件開發者的反抗精神,令筆者非常敬佩。
下面引用維基百科中文版對這段軼事的描述(原文鏈接這裡,英文版本鏈接這裡):
自 2002 年開始,林納斯·托瓦茲(Linus Torvalds)決定使用 BitKeeper 作為 Linux 內核主要的版本控制系統用以維護程式碼。因為 BitKeeper 為專有軟體,這個決定在社群中長期遭受質疑。在 Linux 社群中,特別是理查德·斯托曼(Richard Stallman)與自由軟體基金會的成員,主張應該使用開放原始碼的軟體來作為 Linux 核心的版本控制系統。林納斯·托瓦茲曾考慮過採用現成軟體作為版本控制系統(例如 Monotone),但這些軟體都存在一些問題,特別是效能不佳。現成的方案,如 CVS 的架構,受到林納斯·托瓦茲的批評。
2005 年,安德魯·垂鳩(Andrew Tridgell)寫了一個簡單程式,可以連接 BitKeeper 的儲存庫,BitKeeper 著作權擁有者拉里·麥沃伊(Larry McVoy)認為安德魯·垂鳩對 BitKeeper 內部使用的協議進行逆向工程,決定收回無償使用 BitKeeper 的授權。Linux 內核開發團隊與 BitMover 公司進行蹉商,但無法解決他們之間的歧見。林納斯·托瓦茲決定自行開發版本控制系統替代 BitKeeper,以十天的時間,編寫出第一個 git 版本。
git
不僅僅是一個為程序員所用的版本控制工具,還受到了廣泛的歡迎,並且成為了一個方便快捷的多人協作工具。很多資料的收集、文章的創作可以使用
git
完成,這讓學習
git
的價值大大增加,是學習與生活的必備良品。
本篇文章延續了筆者一貫的教程風格,旨在幫助大家快速入門。如果想要更深入的學習,筆者還是推薦閱讀官方手冊,關於
git
的資料可以參考以下鏈接:
知名的 git
服務提供網站:
以下是正文,望各位看官品閱,如有錯誤還請郵件指正~
目錄
第一步:創建或獲取 repo
在使用 git
之前,我們首先需要創建或獲取一個
git repository
(以下簡稱
repo
)。我們可以通過以下兩種方式來建立
repo
:
-
本地創建:從零開始,在本地建立一個新的
repo
。 -
網上獲取:從遠程服務中獲取一個已有的
repo
。
本地創建
在本地創建 repo
的方式非常簡單。首先,進入我們希望設置
repo
的目錄:
$ cd /my/git/repo
然後,使用 git init
命令初始化 repo
:
$ git init
執行後,當前目錄下會多出一個名為
.git
的隱藏目錄,這裡存儲了
git
的所有內部數據和版本控制信息。我們通常不需要直接操作這個目錄,而是通過
git
命令來管理 repo
。
網上獲取
如果我們希望使用網路上已有的 repo
,可以從遠程服務
clone
它。首先,導航到我們希望存放
repo
的本地目錄,然後執行:
$ git clone <url>
這條命令會下載遠程
repo
的所有內容,包括歷史記錄,並且自動為我們設置好
remote
(下文會提到)。
使用上述兩種方式建立 repo
後,我們就正式進入
git
的世界,開始版本控制的旅程!
第二步:留名青史
在使用
git
之前,我們首先需要設置個人信息(最重要的兩個信息是姓名和電子郵件)。這樣,當其他人在查看我們的項目時,如果遇到問題,就能夠聯繫到我們。同時,在團隊協作中,這也有助於追蹤每個人的提交記錄,確保責任明確。此外,保留個人信息也有助於保護自身的貢獻權益。尤其是在開源項目中,能夠看到自己的名字被記錄在
git
日誌中,或許還會有些小小的成就感。
更重要的是,個人信息一旦設置,特別是在大型項目或他人的
repo
中,後續修改可能會比較麻煩。對於筆者這樣的強迫症患者來說,這簡直是一場噩夢。筆者剛開始使用
git
時,沒有設置個人信息,結果導致所有的
git log
記錄都顯示的是電腦默認的名稱,看起來相當不美觀。因此,建議在初次使用
git
時,就設置好全局的個人信息,以免日後產生不必要的困擾。
我們可以通過以下命令來設置全局個人信息,使其適用於所有
repo
:
$ git config --global user.name "Your Name"
$ git config --global user.email "your-email@example.com"
當然,如果我們只想在特定
repo
中使用不同的信息,而不影響全局設置,可以使用
--local
參數,方法如下:
$ git config --local user.name "Your Name"
$ git config --local user.email "your-email@example.com"
如果需要查閱更多配置選項,可以參考 git config
手冊:
$ man git config
如果想確認當前的配置信息,可以使用以下命令來列出所有
git
配置:
$ git config -l
當我們確認個人信息設置完畢後,就可以正式開始使用
git
進行版本控制了!
第三步:記錄改變
現在,我們要正式進入
git
的核心功能:版本控制的記錄機制。作為一個版本控制系統
(VCS),git
的主要作用就是追蹤和管理文件的變更。在
git
中,文件主要有兩種狀態:
-
tracked
:git
已經納入版本控制的文件,並可分為unmodified
、modified
、staged
三種狀態。 -
untracked
:git
尚未納入版本控制的文件。
下面這張來自
git 官網
的圖片清晰地展示了 git
如何管理文件的狀態流轉:
檢查文件狀態
我們可以使用以下命令來檢查當前 repo
中的文件狀態:
$ git status
執行該命令後,我們可以看到哪些文件處於 untracked
、modified
或 staged
狀態。這對於掌握當前
repo
的變更情況至關重要。
如果想要深入了解 git
的運作方式,建議參閱官網提供的參考書,本文則專注於幫助讀者快速上手。
追蹤新文件
如果我們在 repo
中新建了一個名為
README
的文件:
$ touch README
此時,該文件處於 untracked
狀態。為了讓
git
追蹤它,我們需要使用以下命令:
$ git add README
這樣,該文件便進入 staged
狀態,等待
commit
。
commit 變更
當文件進入 staged
狀態後,我們可以將其
commit
到 repo
中:
$ git commit
執行此命令後,git
會打開默認的
editor
,讓我們輸入此次提交的描述信息,確保日後能夠清楚回顧每次變更的原因。完成編輯後,該文件便進入
unmodified
狀態。
通常,commit
變更的標準流程如下:
$ git add <file> # 暫存變更
$ git commit # commit 變更
簡化記錄操作
為了提高效率,我們可以使用以下命令一次性
commit
所有變更:
$ git add -A # 添加所有變更的文件(等同於 --all)
$ git commit -m "簡要描述本次 commit 內容" # 直接添加 commit 信息,無需進入編輯器
這樣,我們就成功完成了
git
的基本變更記錄流程,這也是日常使用中最常見的一些操作。
第四步:查看歷史記錄和變更內容
當我們開始使用
git
進行版本控制後,難免會有查看過去修改記錄的需求。前面提到的
git status
只能顯示當前的工作區狀態,而如果想要查閱完整的修改歷史,就需要使用:
$ git log
這條命令會列出所有 commit
記錄,包括
commit
的
hash
、作者、日期和提交信息。有心的讀者可能會注意到,每次提交都對應著一個
hash
值
,這就相當於該次修改的「身份標識」。當我們需要回溯到某個特定的時間點,這串
hash
值就派上用場了。
除了查看
commit
記錄,有時我們還需要檢視具體的變更內容,而不只是知道哪些文件被修改了。這時候,git diff
命令就非常有用。
查看未 staged 的變更
如果想要查看工作目錄中已修改但尚未
git add
的變更,可以使用:
$ git diff
這條命令會顯示具體的變更內容,包括新增 (+
) 和刪除
(-
) 的部分,讓我們能夠清楚地看到修改了哪些行。
如果我們希望以單詞為單位來查看變更,而不是整行對比,可以使用
--word-diff
參數:
$ git diff --word-diff
這將以
[-刪除的內容-]{+新增的內容+}
的格式標示變更,使其更加直觀,特別適用於修改較少但影響較大的情況。
如果想要更加精細的甄別,可以使用:
$ git diff --word-diff-regex=.
這會將每個字符視為單獨的比較單位,對於像中文這樣的語言來說特別有用,因為單個字符就可能具有意義。
查看已經 staged 的變更
如果文件已經 git add
到 staged
階段,但尚未
commit
,想要檢視這部分變更內容,可以使用:
$ git diff --staged
這條命令與 git diff
類似,但它專門顯示已
staged
但尚未
commit
的修改,幫助我們確認即將
commit
的內容是否符合預期。
查看兩次 commit 之間的變更
有時我們需要比較兩個不同的
commit
,了解它們之間的差異,可以使用:
$ git diff <commit-hash-1> <commit-hash-2>
這樣,我們可以清楚地看到兩次
commit
之間的變更內容,方便追蹤修改歷程。
這些
git diff
命令對於版本管理至關重要,能夠幫助我們更清楚地理解變更的細節,使我們在
git
的工作流中更得心應手。
第五步:撤銷變更內容
除了查看歷史記錄和變更的內容,我們經常還需要撤銷變更內容。回溯到某個
commit
的時間點是
git
使用過程中經常遇到的需求。使用以下命令,git
會讓 repo
恢復到指定 commit
的狀態:
$ git reset <commit-hash>
需要注意的是,這個命令主要影響 git
的
commit
記錄,而不會對文件本身進行刪除。例如,如果某個文件在該
commit
之前是 untracked
(未被
git
追蹤),則 reset
後它仍然處於
untracked
狀態,不會自動消失,這個文件會變成
unstaged
的狀態。
--soft 選項:保留修改內容
如果希望回溯 commit
記錄,但仍然保留修改內容在
staged
中,可以使用 --soft
參數:
$ git reset --soft <commit-hash>
這樣,該 commit
之後的修改仍然會保留在
staged
狀態,允許我們進一步修改或重新
commit
。
--hard 選項:完全恢復到指定 commit
如果想要完全清除 commit
之後的所有變更(包括工作區和
staged
狀態的文件),則可使用 --hard
參數:
$ git reset --hard <commit-hash>
這將強制回滾到指定 commit
,所有
commit-hash
之後的變更都會被徹底刪除,無法找回。因此,請務必謹慎操作,確保不會誤刪重要內容。
選擇 git reset
的不同模式取決於你的需求,如果只是想撤銷
commit
但保留修改內容,--soft
會是更好的選擇,而如果確定要回滾所有變更,則
--hard
會提供最徹底的清理方式。
第六步:遠程管理
在 git
的使用過程中,remote repository
(以下簡稱
remote
)的管理是團隊協作和代碼備份的關鍵部分。我們經常需要將本地代碼同步到
remote
,或者從中獲取最新的代碼,以確保開發進度的一致性。
已經存在遠程 repo
假設我們已經有了一個 remote
,那麼在本地我們需要先
init
一個 repo
,然後添加
remote
的鏈接:
$ git remote add origin <URL> # origin 是一個我們可以修改的簡稱
$ git remote -v # 查看鏈接情況
成功鏈接後,我們可以 pull
這個
remote
以獲取最新的代碼:
$ git pull origin master # origin 是 remote 名稱,而 master 則是 branch 名稱
有人可能會問,這與 git clone
有何不同?簡單來說,clone
是直接複製 remote
的內容到本地,而
git remote
命令則是建立本地與遠程的關聯,讓我們可以手動管理 push
和
pull
操作。
當我們完成本地修改後,可以使用以下命令將變更 push
到
remote
:
$ git push origin master
強制從遠程服務器 pull 並覆蓋本地 repo
有時候我們本地的 repo
可能與
remote
的歷史發生衝突,這時可以強制同步遠程版本,覆蓋本地變更。請謹慎使用以下命令,因為它會刪除所有本地的修改(包括已經
commit
的):
$ git fetch --all
$ git reset --hard origin/master
$ git pull origin master
這樣,本地代碼就會與 remote
完全同步。
已經存在本地 repo
如果我們在本地已經有了一個 repo
,並且希望將其上傳到
remote
,那麼我們需要先在
remote
的服務上創建一個新的空
repo
,然後在本地執行以下命令來建立關聯並
push
已有的內容:
$ git remote add origin <URL>
$ git add .
$ git commit -m "Initial commit"
$ git push origin master
由於
git push
是我們最常使用的命令之一,為了方便未來的操作,可以使用
-u
參數來設置默認上傳的 remote
和
branch
:
$ git push -u origin master
這樣,以後只需要簡單執行:
$ git push
就能將本地變更 push
到
remote
,極大地提升了開發效率。
總結
恭喜 :) 本篇文章到此告一段落!我們剛剛介紹了
git
的基礎用法,希望各位看官在瀏覽後能夠快速上手,開始使用
git
進行版本控制。不過,git
的學習之路遠不止於此,即使完全掌握了本文的內容,也只是入門的第一步。
與許多 Unix-like 工具一樣,git
需要通過持續的學習和實踐才能真正熟練運用,並深入理解其中的奧妙。如果你希望進一步探索
git
的進階操作,可以參閱筆者的「Git 進階指南:實用技巧與最佳實踐」。
祝願各位在 git
的學習之路上,一帆風順!