在上一篇文章中,我們已經成功安裝並設定了 Git。今天,我們要開始實際操作,學習 Git 的核心功能。就像學開車一樣,理論很重要,但真正的技能來自於實際操作。
建立你的第一個 Git 倉庫
方法一:從零開始建立倉庫(git init)
假設你要開始一個新的專案,首先建立一個資料夾:
# 建立專案資料夾
mkdir my-first-project
cd my-first-project
# 初始化 Git 倉庫
git init
執行 git init 後,你會看到類似這樣的訊息:
Initialized empty Git repository in /Users/username/my-first-project/.git/
這就像在你的專案資料夾中設置了一個「監控攝影機」,從現在開始,Git 會開始記錄這個資料夾中所有檔案的變化。
方法二:複製現有的倉庫(git clone)
如果你要參與一個已經存在的專案,可以使用 git clone:
# 複製遠端倉庫到本地
git clone https://github.com/username/repository-name.git
# 複製後進入專案資料夾
cd repository-name
這就像是得到一本書的完整影印本,包含所有的內容和歷史記錄。
理解檔案的生命週期
在 Git 中,每個檔案都有四種可能的狀態,理解這些狀態對於掌握 Git 至關重要:
1. Untracked(未追蹤)
這些是 Git 不知道存在的檔案,就像你桌上有一張新的便條紙,但你還沒有決定要不要把它放進檔案夾。
2. Unmodified(未修改)
這些檔案已經被 Git 追蹤,且內容沒有改變,就像檔案夾中已經歸檔且沒有更動的文件。
3. Modified(已修改)
你已經修改了這些檔案,但還沒有告訴 Git 你想要保存這些變更,就像你在文件上做了筆記,但還沒有正式簽名確認。
4. Staged(已暫存)
你已經告訴 Git 要在下次提交時包含這些變更,就像你已經把要寄出的信件放在桌上的「待寄」區域。
檢查倉庫狀態
在進行任何操作之前,先檢查目前的狀態是個好習慣:
git status
剛初始化的空倉庫會顯示:
On branch main
No commits yet
nothing to commit (create/copy files and use "git add" to track)
這告訴我們:
- 目前在 main 分支上
- 還沒有任何提交記錄
- 沒有檔案需要處理
開始追蹤檔案
讓我們建立第一個檔案:
# 建立一個簡單的文字檔
echo "Hello, Git!" > README.txt
再次檢查狀態:
git status
現在你會看到:
On branch main
No commits yet
Untracked files:
(use "git add <file>..." to include in what will be committed)
README.txt
nothing added to commit but untracked files present (use "git add" to track)
Git 發現了新檔案 README.txt,但它還在 “Untracked” 狀態。
將檔案加入暫存區
git add README.txt
再檢查一次狀態:
git status
現在顯示:
On branch main
No commits yet
Changes to be committed:
(use "git rm --cached <file>..." to unstage)
new file: README.txt
檔案現在已經在暫存區中,準備被提交。
一次加入多個檔案
如果你有多個檔案要加入暫存區:
# 加入特定檔案
git add file1.txt file2.txt
# 加入所有新檔案和修改的檔案
git add .
# 加入所有 .txt 檔案
git add *.txt
# 加入特定資料夾中的所有檔案
git add src/
作為工程師,我建議初學者先習慣明確指定檔案名稱,避免意外加入不想要的檔案。
提交變更
將檔案加入暫存區後,就可以進行提交:
git commit -m "新增 README 檔案"
你會看到類似的輸出:
[main (root-commit) a1b2c3d] 新增 README 檔案
1 file changed, 1 insertion(+)
create mode 100644 README.txt
這表示:
- 在 main 分支上建立了第一次提交
- 提交的 ID 是 a1b2c3d(實際會是不同的數字)
- 有 1 個檔案改變,新增了 1 行內容
提交訊息的最佳實踐
好的提交訊息應該:
- 簡潔明瞭,說明這次改變做了什麼
- 使用現在式動詞(例如:「修復」而不是「修復了」)
- 第一行不超過 50 個字元
- 如需詳細說明,空一行後再寫
# 好的提交訊息範例
git commit -m "修復使用者登入驗證邏輯"
git commit -m "新增產品搜尋功能"
git commit -m "更新使用者介面樣式"
# 不好的提交訊息範例
git commit -m "修復"
git commit -m "更新一些東西"
git commit -m "WIP" # Work In Progress
查看提交歷史
git log
輸出會類似:
commit a1b2c3d4e5f6789... (HEAD -> main)
Author: 張小明 <ming@example.com>
Date: Mon Jan 15 14:30:25 2024 +0800
新增 README 檔案
更簡潔的歷史檢視
# 一行顯示一次提交
git log --oneline
# 顯示最近 3 次提交
git log --oneline -3
# 顯示檔案變更統計
git log --stat
修改檔案並再次提交
讓我們修改 README.txt:
echo "這是我的第一個 Git 專案" >> README.txt
檢查狀態:
git status
你會看到:
On branch main
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: README.txt
no changes added to commit (use "git add" to add changes)
檔案現在處於 “Modified” 狀態。
查看具體的變更內容
git diff
這會顯示檔案的具體變更:
diff --git a/README.txt b/README.txt
index 10ddd6d..e3f5a47 100644
--- a/README.txt
+++ b/README.txt
@@ -1 +1,2 @@
Hello, Git!
+這是我的第一個 Git 專案
符號說明:
+表示新增的行-表示刪除的行- 沒有符號的行表示沒有變更
暫存並提交修改
git add README.txt
git commit -m "在 README 中新增專案描述"
一次性加入和提交
對於已經被追蹤的檔案,你可以跳過暫存步驟:
# 這個指令只對已追蹤的檔案有效
git commit -am "快速提交已追蹤檔案的變更"
注意:這個指令不會處理新檔案(Untracked files)。
.gitignore 的使用
在實際開發中,有些檔案我們不想被 Git 追蹤,例如:
- 編譯產生的檔案
- 暫存檔案
- 包含密碼的設定檔
- 作業系統產生的系統檔
建立 .gitignore 檔案:
# 建立 .gitignore 檔案
touch .gitignore
在檔案中加入要忽略的規則:
# 忽略所有 .log 檔案
*.log
# 忽略特定檔案
secret-config.txt
# 忽略特定資料夾
temp/
build/
# 忽略所有 .tmp 檔案,但保留 important.tmp
*.tmp
!important.tmp
.gitignore 的規則語法
# 註解
# 忽略所有 .a 檔案
*.a
# 但保留 lib.a,即便你已經忽略了 .a 檔案
!lib.a
# 只忽略當前目錄下的 TODO 檔案,而不忽略 subdir/TODO
/TODO
# 忽略任何目錄下名為 build 的資料夾
build/
# 忽略 doc/notes.txt,但不忽略 doc/server/arch.txt
doc/*.txt
# 忽略 doc/ 目錄及其所有子目錄下的 .pdf 檔案
doc/**/*.pdf
復原變更的不同方法
復原工作區的變更(還沒加入暫存區)
# 復原特定檔案
git restore README.txt
# 復原所有變更
git restore .
取消暫存(已經 git add,但還沒 commit)
# 取消特定檔案的暫存
git restore --staged README.txt
# 取消所有檔案的暫存
git restore --staged .
修改最後一次提交
如果你發現最後一次提交有錯誤,可以修改:
# 修改提交訊息
git commit --amend -m "修正後的提交訊息"
# 在最後一次提交中加入忘記的檔案
git add forgotten-file.txt
git commit --amend --no-edit
實用的檢視指令
查看暫存區和工作區的差異
# 查看尚未暫存的變更
git diff
# 查看已暫存的變更
git diff --staged
# 查看特定檔案的變更
git diff README.txt
查看檔案的提交歷史
# 查看特定檔案的修改歷史
git log README.txt
# 查看檔案每一行是誰修改的
git blame README.txt
建立有意義的專案結構
讓我們建立一個更完整的專案結構:
# 建立資料夾結構
mkdir src docs tests
touch src/main.py docs/README.md tests/test_main.py
# 建立 .gitignore
cat > .gitignore << EOF
# Python
__pycache__/
*.pyc
*.pyo
# 編輯器
.vscode/
*.swp
# 作業系統
.DS_Store
Thumbs.db
EOF
# 加入所有檔案並提交
git add .
git commit -m "建立基本專案結構"
常見的新手錯誤與解決方法
錯誤 1:忘記設定使用者資訊
Author identity unknown
解決方法:
git config --global user.name "你的姓名"
git config --global user.email "your.email@example.com"
錯誤 2:提交了不該提交的檔案
如果檔案還沒有 push 到遠端:
# 從最後一次提交中移除檔案,但保留在工作區
git reset --soft HEAD~1
git reset HEAD unwanted-file.txt
git commit -m "修正後的提交"
錯誤 3:提交訊息寫錯
# 修改最後一次提交的訊息
git commit --amend -m "正確的提交訊息"
檢查和維護倉庫健康
定期檢查倉庫狀態是個好習慣:
# 檢查倉庫狀態
git status
# 檢查是否有未追蹤的檔案
git ls-files --others --exclude-standard
# 檢查倉庫的完整性
git fsck
小結
今天我們學習了 Git 的基本操作,這些是你日常開發中最常用的指令:
- 建立倉庫:
git init或git clone - 檢查狀態:
git status(這是最重要的指令之一) - 追蹤檔案:
git add - 提交變更:
git commit - 查看歷史:
git log - 查看差異:
git diff - 復原變更:
git restore
記住這個基本流程:
修改檔案 → git add → git commit → 重複
在下一篇文章中,我們將學習 Git 的分支功能,這是 Git 最強大的特色之一。分支讓你可以同時進行多個功能開發,而不會互相干擾。
練習是掌握 Git 的關鍵。我建議你建立一個練習用的倉庫,嘗試今天學到的所有指令。犯錯是學習的一部分,在練習環境中大膽嘗試,這樣在真正的專案中你就會更有信心。