Stories

Detail Return Return

git版控隨筆 - Stories Detail

git 基礎知識

Git 的工作流程涉及多個“空間”或區域,這些空間用於管理文件的狀態和版本。以下是 Git 中主要的空間及其作用:

image.png

1. 工作區(Working Directory / Working Tree)

  • 定義:你當前在項目中編輯的文件所在的目錄。
  • 特點

    • 包含實際的文件內容。
    • 是你進行開發、修改代碼的地方。
  • 狀態

    • 文件可以是 unmodified(未修改)、modified(已修改)或 untracked(未跟蹤)。

2. 暫存區 / 緩存區(Staging Area / Index)

  • 定義:一個臨時存儲區域,用於準備下一次提交的內容。
  • 作用

    • 使用 git add <file> 將修改從工作區添加到暫存區。
    • 提交時 (git commit),Git 會將暫存區中的內容打包成一個新的提交對象。
  • 特點

    • 允許你選擇性地提交部分更改。
    • 是 Git 版本控制的核心機制之一。

3. 本地倉庫(Local Repository)

  • 定義.git 目錄,包含所有 Git 提交歷史、對象、引用等。
  • 特點

    • 所有提交 (commit) 都保存在這裏。
    • 是分佈式版本控制系統的核心,支持離線操作。
  • 查看提交歷史git log

4. 遠程倉庫(Remote Repository)

  • 定義:託管在遠程服務器上的 Git 倉庫,如 GitHub、GitLab 等。
  • 常見操作

    • git push:將本地提交推送到遠程倉庫。
    • git pull:拉取遠程更新併合併到本地分支。
    • git fetch:獲取遠程提交但不自動合併。

5. Git 對象數據庫(Object Database)

  • 定義:位於 .git/objects 目錄,存儲所有 Git 對象(blob、tree、commit、tag)。
  • 類型

    • blob:表示文件內容。
    • tree:表示目錄結構。
    • commit:表示一次提交記錄。
    • tag:表示標籤(輕量標籤或附註標籤)。

6. HEAD 指針

  • 定義:指向當前所在分支或提交的指針。
  • 狀態

    • 正常情況下指向一個分支(如 refs/heads/main)。
    • 如果處於分離 HEAD 狀態,則直接指向某個具體的提交。

常見命令與空間關係

命令 影響的空間
git add . 將工作區的所有修改添加到暫存區
git commit 將暫存區的內容提交到本地倉庫
git status 查看工作區和暫存區的狀態差異
git reset 將暫存區或本地倉庫的內容重置回退
git checkout -- <file> 丟棄工作區的修改,恢復為暫存區或本地倉庫中的版本
git stash 將工作區和暫存區的修改臨時保存

示例流程圖(簡化)

工作區 (Working Directory)
     ↓ git add
暫存區 (Staging Area)
     ↓ git commit
本地倉庫 (.git)
     ↓ git push
遠程倉庫 (Remote Repository)

通過理解這些空間的概念,可以更好地掌握 Git 的版本控制機制,並更有效地使用 git diffgit add -pgit reset 等高級功能。

commit 提交

最佳實踐:commit early,commit often
git提交的兩步流程

## 工作區-->暫存區
git status
git add <file_name>
git add -A
git add .   當前目錄及其子目錄

## 提交文件+提交消息
git commit -m 'comment'

branch 分支

lines of development
截屏2025-07-12 22.54.16.png

分支是指向提交(commit)的可移動指針

HEAD 指向分支的指針

減少對git checkout的使用

Tracked file 1:unmodified 2:modified 通過git status 查看狀態

  1. git branch 查看分支
  2. git branch <branch_name> 創建分支
  3. git switch <branch_name> 切換分支
  4. git switch -c <branch_name> 創建並切換

merge 合併

merge

fast-forward merge(快進合併)

A --- B --- C (main)
               \
                D --- E (feature-branch)
如果目標分支(如 main)是當前分支的直接祖先(即沒有分叉),Git 會直接將指針向前移動(快進),不會創建新的合併提交。
    git switch main    
    git merge feture-branch 後
    A --- B --- C --- D --- E (main)
可作用git merge --no-ff feature-branch 禁用快進合併(no-ff強制創建,即使可以快進),保留完整的路徑
    A --- B --- C ------------ F (main)
               \             /
                D --- E ---- (feature-branch)

three-way merge(三方合併)

   A --- B --- C (main)
       \
        D --- E (feature)

A 是 main 和 feature 的共同祖先(base)。
B 和 C 是 main 的改動(ours)。
D 和 E 是 feature 的改動(theirs)。
git merge 生成一個新的 合併提交(F),

     git switch main
    git merge feature-branch  /git merge --no--ff feature-branch
     
      A --- B --- C ------------ F (main)
       \                      /
        D --- E -- ----------- (feature)

pull

git pull 與 git fetch 選擇問題

1:若本地分枝與遠程分支沒有分叉,git pull進行快速合併

2:否則分兩步走 ,先git fetch,然後視情況做--no-rebase or rebase

變基

Screenshot 2025-07-15 at 13.50.21.png

rebase,變基,可以直接理解為改變基底。feature分支是基於master分支的B拉出來的分支,feature的基底是B。而master在B之後有新的提交,就相當於此時要用master上新的提交來作為feature分支的新基底。實際操作為把B之後feature的提交先暫存下來,然後刪掉原來這些提交,再找到master的最新提交位置,把存下來的提交再接上去(接上去是逐個和新基底處理衝突的過程),如此feature分支的基底就相當於變成了M而不是原來的B了。(注意,如果master上在B以後沒有新提交,那麼就還是用原來的B作為基,rebase操作相當於無效,此時和git merge就基本沒區別了,差異只在於git merge會多一條記錄Merge操作的提交記錄)

如下圖所示,rebase會產生新的提交。會得新生成提交hash值
Screenshot 2025-07-15 at 13.53.17.png

Add a new Comments

Some HTML is okay.