﻿# 不常用 Git 命令整理

我每天都在用 Git 進行版控，有些命令真的是滾瓜爛熟，閉著眼睛都可以打出來。不過，有些命令偶爾會用到，不整理起來每次都要問 AI 也確實有點煩，所以這邊文章我就打算做個筆記，以後有想到就整理到這篇文章來。

### 管理 GitHub 上面某個 Repo 下的 Pull requests 分支

-   快速取得特定一個分支的修改內容
    
    我以 [fix: resolve image paths to absolute paths #1041](https://github.com/openai/codex/pull/1041) 這條分支為例：
    
    > [https://github.com/openai/codex/pull/1041](https://github.com/openai/codex/pull/1041)
    
    這是打算從 `crazywolf132/codex` Repo 下的 `fix/image-flag` 分支合併回 `openai/codex` Repo 的 `main` 分支的 Pull Request。當我想要從本機取得這個分支的修改內容時，可以使用以下命令快速取得，不需要真的去 `git clone` 這個 `crazywolf132/codex` Repo 回來：
    
    ```bash
    git fetch origin pull/1041/head:pr-1041
    ```
    
    執行時會有以下訊息：
    
    ```
    From https://github.com/openai/codex
    * [new ref]           refs/pull/1041/head -> pr-1041
    ```
    
    此時你就會得到一個「本地分支」名為 `pr-1041`，直接切過去就能看到完整的程式碼：
    
    ```bash
    git switch pr-1041
    ```
    
    或者你也可以使用 `git cherry-pick pr-1041` 將該 PR 的最新一個 commit 給「撿」回來使用！
    
    ```bash
    git cherry-pick pr-1041
    ```
    
    實際要怎麼用，就看你當下的需求而定，上述命令看不懂的話，建議你不要用。
    
-   取回所有 Fork 完後發 Pull request 回來的分支
    
    以下命令會將該 Repo 下所有的 PR 分支都取回來，並且存放在本地端的 `refs/remotes/origin/pr/` 目錄下。
    
    ```bash
    git fetch origin '+refs/pull/*/head:refs/remotes/origin/pr/*'
    ```
    
    這個命令所抓回來的，將會包含所有 PR 分支回來，其中也包含別人 Fork 回去再發 PR 回來的這些分支，我有時候需要取得「非專案成員」所開發分支，藉此 Cherry-Pick 回特定幾個變更。
    
    事實上，這些別人 Fork 回去再發 PR 回來的這些分支並不屬於該 Repo 的一部分，所以你用正常的 `git fetch --all` 是不會抓到這些分支的，必須透過這個特殊的命令才能抓到。
    
-   移除不再存在的 PR 分支
    
    透過 `git remote prune origin` 這個命令會移除本地端的 `remote tracking branches` (例如 `origin/feature-xxx` 分支)，這些分支代表遠端主機 (origin) 上的分支。但如果這些分支已經在遠端被刪除，而你的本地還留有這些遠端追蹤分支 (remote tracking branches)，這個指令就會幫你把它們「清掉」，讓你的本地 `remote branch` 列表和遠端實際狀況同步。
    
    ```bash
    git remote prune origin
    ```
    
    這個命令有趣的地方就是，因為這些 Fork 出去再 PR 回來的這些分支，並不是當前 Repo 的一部分，所以這個命令會從本機刪除所有「不屬於該專案」的分支。使用的時機點就是，當我已經 Cherry-Pick 完我需要的分支，我就不再需要看到他了，這時用一個命令就可以清除所有不需要的分支了。
    

### 快速刪除一個資料夾但不要讓 Git 偵測到變更

我最近因為在開發 AI 程式設計代理人，在開發的過程中，我發現有些特定資料夾下的程式碼可能會影響 AI Agent 的判斷，所以我需要快速刪除這個資料夾，但又不想讓 Git 偵測到這個變更，於是我就使用了以下命令：

-   PowerShell
    
    ```powershell
    git clone https://github.com/openai/codex.git && cd codex
    
    # 將整個資料夾下的所有檔案標記為「未變更」
    git ls-files 'codex-rs' | % { git update-index --assume-unchanged $_ }
    
    # 刪除整個資料夾
    Remove-Item -Path 'codex-rs' -Recurse -Force
    ```
    
-   Bash
    
    ```bash
    git clone https://github.com/openai/codex.git && cd codex
    
    # 將整個資料夾下的所有檔案標記為「未變更」
    git ls-files 'codex-rs' | xargs git update-index --assume-unchanged
    
    # 刪除整個資料夾
    rm -rf 'codex-rs'
    ```
    

### 將設定為 `--assume-unchanged` 的檔案都復原 Git 變更追蹤

-   PowerShell
    
    ```powershell
    git clone https://github.com/openai/codex.git && cd codex
    
    # 將整個資料夾下的所有檔案標記為「未變更」
    git ls-files 'codex-rs' | % { git update-index --no-assume-unchanged $_ }
    
    # 刪除整個資料夾
    Remove-Item -Path 'codex-rs' -Recurse -Force
    ```
    
-   Bash
    
    ```bash
    git clone https://github.com/openai/codex.git && cd codex
    
    # 將整個資料夾下的所有檔案標記為「未變更」
    git ls-files 'codex-rs' | xargs git update-index --no-assume-unchanged
    
    # 刪除整個資料夾
    rm -rf 'codex-rs'
    ```
    

### 取消 Shadow Clone 的快速方法

使用 Shadow Clone 時，同時也隱含著只下載一個分支，如果不指定 `-b` 參數的話，就會下載 Repo 的「預設分支」，通常為 `main` 或 `develop` 分支。

```bash
# Shadow Clone
git clone https://github.com/openai/codex.git --depth=1 -b main && cd "codex"

# 取消 Shadow Clone
git fetch --unshallow
```

如果要取得所有遠端分支，可以這樣下指令：

```bash
git config --replace-all remote.origin.fetch "+refs/heads/*:refs/remotes/origin/*"
git fetch --all
```

### 強迫不讓 Git 使用 Pager (輸出分頁) 的方法

Git 預設會自動使用 Pager 來分頁顯示結果，但是當透過「代理人」執行 Git 命令時，可能會遇到輸出結果過長而導致 Terminal 環境會等待使用者互動的情況。這時候可以透過以下命令來強制 Git 不使用 Pager 輸出：

```bash
git config --local core.pager cat
```

> 請記得不要設定到 `--global` 或 `--system`，否則會影響到所有的 Git 專案。
