The Will Will Web

記載著 Will 在網路世界的學習心得與技術分享

不常用 Git 命令整理

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

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

  • 快速取得特定一個分支的修改內容

    我以 fix: resolve image paths to absolute paths #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 回來:

    git fetch origin pull/1041/head:pr-1041
    

    執行時會有以下訊息:

    From https://github.com/openai/codex
    * [new ref]           refs/pull/1041/head -> pr-1041
    

    此時你就會得到一個「本地分支」名為 pr-1041,直接切過去就能看到完整的程式碼:

    git switch pr-1041
    

    或者你也可以使用 git cherry-pick pr-1041 將該 PR 的最新一個 commit 給「撿」回來使用!

    git cherry-pick pr-1041
    

    實際要怎麼用,就看你當下的需求而定,上述命令看不懂的話,建議你不要用。

  • 取回所有 Fork 完後發 Pull request 回來的分支

    以下命令會將該 Repo 下所有的 PR 分支都取回來,並且存放在本地端的 refs/remotes/origin/pr/ 目錄下。

    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 列表和遠端實際狀況同步。

    git remote prune origin
    

    這個命令有趣的地方就是,因為這些 Fork 出去再 PR 回來的這些分支,並不是當前 Repo 的一部分,所以這個命令會從本機刪除所有「不屬於該專案」的分支。使用的時機點就是,當我已經 Cherry-Pick 完我需要的分支,我就不再需要看到他了,這時用一個命令就可以清除所有不需要的分支了。

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

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

  • 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

    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

    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

    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 的「預設分支」,通常為 maindevelop 分支。

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

# 取消 Shadow Clone
git fetch --unshallow

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

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

留言評論