簡體   English   中英

刪除所有本地 git 分支

[英]Delete all local git branches

我遵循一個開發過程,為每個新功能或故事卡創建一個新的本地分支。 完成后,我將分支合並到 master 然后推送。

由於懶惰或健忘,隨着時間的推移往往會發生的情況是,我最終得到了大量本地分支,其中一些(例如尖峰)可能尚未合並。

我知道如何列出所有本地分支,也知道如何刪除單個分支,但我想知道是否有 git 命令允許我刪除所有本地分支?

下面是git branch --merged命令的輸出。

user@machine:~/projects/application[master]$ git branch --merged
  STORY-123-Short-Description
  STORY-456-Another-Description
  STORY-789-Blah-Blah
* master

所有嘗試刪除用grep -v \*列出的分支(根據下面的答案)都會導致錯誤:

error: branch 'STORY-123-Short-Description' not found.
error: branch 'STORY-456-Another-Description' not found.
error: branch 'STORY-789-Blah-Blah' not found.

我在用着:

git 1.7.4.1  
ubuntu 10.04  
GNU bash, version 4.1.5(1)-release  
GNU grep 2.5.4  

'git branch -d' 子命令可以刪除多個分支。 因此,簡化@sblom 的答案,但添加一個關鍵的 xargs:

git branch -D `git branch --merged | grep -v \* | xargs`

或者,進一步簡化為:

git branch --merged | grep -v \* | xargs git branch -D 

重要的是,正如@AndrewC 所指出的,不鼓勵使用git branch編寫腳本。 為了避免它使用類似的東西:

git for-each-ref --format '%(refname:short)' refs/heads | grep -v "master\|main" | xargs git branch -D

刪除需謹慎!

$ mkdir br
$ cd br; git init
Initialized empty Git repository in /Users/ebg/test/br/.git/
$ touch README; git add README; git commit -m 'First commit'
[master (root-commit) 1d738b5] First commit
 0 files changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 README
$ git branch Story-123-a
$ git branch Story-123-b
$ git branch Story-123-c
$ git branch --merged
  Story-123-a
  Story-123-b
  Story-123-c
* master
$ git branch --merged | grep -v \* | xargs
Story-123-a Story-123-b Story-123-c
$ git branch --merged | grep -v \* | xargs git branch -D
Deleted branch Story-123-a (was 1d738b5).
Deleted branch Story-123-b (was 1d738b5).
Deleted branch Story-123-c (was 1d738b5).

刪除所有分支但保留“develop”和“master”等其他分支的更簡單方法如下:

git branch | grep -v "develop" | grep -v "master" | xargs git branch -D

很有用 !

在 github 上對此問題的評論中找到了更好的方法:

git branch --merged master --no-color | grep -v "master\|stable\|main" | xargs git branch -d

編輯:添加了無顏色選項並排除了穩定分支(根據需要添加其他分支)

不建議解析git branch的輸出,對於 Stack Overflow 上的未來讀者來說也不是一個好的答案。

  1. git branch是所謂的瓷器命令。 Porcelain 命令不是為機器解析而設計的,輸出可能會在不同版本的 Git 之間發生變化。
  2. 有一些用戶配置選項會以難以解析的方式更改git branch的輸出(例如,着色)。 如果用戶設置了color.branch ,那么您將在輸出中獲得控制代碼,這將導致error: branch 'foo' not found. 如果您嘗試將其通過管道傳輸到另一個命令中。 您可以使用--no-color標志繞過它到git branch ,但誰知道其他用戶配置可能會破壞什么。
  3. git branch可能會做其他令人討厭的解析,比如在當前簽出的分支旁邊放一個星號

git 的維護者對圍繞git branch輸出編寫腳本有這樣的說法

為了找出當前分支是什么,隨意/粗心的用戶可能已經圍繞 git 分支編寫了腳本,這是錯誤的。 我們強烈反對在腳本中使用任何 Porcelain 命令,包括 git 分支,因為命令的輸出可能會更改以幫助人類消費用例。

建議手動編輯.git目錄中的文件(如 .git/refs/heads)的答案同樣有問題(參考可能在 .git/packed-refs 中,或者 Git 將來可能會更改其內部布局)。

Git 提供了for-each-ref命令來檢索分支列表。

Git 2.7.X 將引入--merged選項,以便您可以執行以下操作來查找和刪除合並到HEAD中的所有分支

for mergedBranch in $(git for-each-ref --format '%(refname:short)' --merged HEAD refs/heads/)
do
    git branch -d ${mergedBranch}
done

Git 2.6.X 及更早版本,您將需要列出所有本地分支,然后單獨測試它們以查看它們是否已合並(這將明顯變慢並且稍微復雜一些)。

for branch in $(git for-each-ref --format '%(refname:short)' refs/heads/)
do
    git merge-base --is-ancestor ${branch} HEAD && git branch -d ${branch}
done

嘗試以下 shell 命令:

git branch | grep -v "master" | xargs git branch -D

解釋:

  • 通過git branch | grep -v "master"獲取所有分支(master除外) git branch | grep -v "master"命令
  • 使用xargs命令選擇每個分支
  • 使用xargs git branch -D刪除分支

要刪除除您當前已簽出的分支之外的每個分支:

for b in `git branch --merged | grep -v \*`; do git branch -D $b; done

我建議在前幾次將git branch -D $b更改為echo $b以確保它刪除了您想要的分支。

以下命令將刪除除 master 分支之外的所有本地分支。

git branch | grep -v "master" | xargs git branch -D

上面的命令

  1. 列出所有分支
  2. 從列表中忽略主分支並獲取其余分支
  3. 刪除分支

請注意,我會升級到 git 1.7.10。 您可能會在這里得到不適用於您的版本的答案。 我的猜測是你必須在分支名稱前加上refs/heads/

注意,僅當您制作了工作文件夾和 .git 目錄的副本時,才繼續執行以下操作。

有時我會直接從.git/refs/heads中刪除我不想要的分支。 所有這些分支都是文本文件,其中包含它們指向的提交的 40 個字符的 sha-1。 如果您為其中任何一個設置了特定的跟蹤,您的.git/config中將包含無關信息。 您也可以手動刪除這些條目。

刪除linux 中的所有本地分支,除了你所在的分支

// hard delete

git branch -D $(git branch)

我發現只使用文本編輯器和 shell 更容易。

  1. 在 shell 中輸入git checkout <TAB> 將顯示所有本地分支機構。
  2. 將它們復制到文本編輯器,刪除您需要保留的那些。
  3. 用空格替換換行符。 (在 SublimeText 中非常簡單。)
  4. 打開外殼,輸入git branch -D <PASTE THE BRANCHES NAMES HERE>

而已。

在 Windows 命令行中,使用以下命令刪除除當前簽出分支之外的所有內容:

for /f "tokens=*" %f in ('git branch ^| find /v "*"') do git branch -D %f

如果要刪除所有本地分支,請使用以下簡單命令:

git branch -D `git branch`

注意:這將刪除除當前簽出分支之外的所有分支

我有類似的情況,最近發現以下命令很有用。

git branch -D `git branch | awk '{ if ($0 !~ /<Branch_You_Want_to_Keep>/) printf "%s", $0 }'`

如果你想保留多個分支,那么

git branch -D `git branch | awk '{ if ($0 !~ /<Branch_You_Want_to_Keep1>|<Branch_You_Want_to_Keep2>/) printf "%s", $0 }'`

希望這可以幫助某人。

這是適用於在 Windows 機器上運行的任何人的 Powershell 解決方案

git checkout master # by being on the master branch, you won't be able to delete it
foreach($branch in (git branch))
{
    git branch -D $branch.Trim()
}

如果你使用 NodeJS,我寫了這個命令

npx git-clear-branch

該命令清除除 master 和 current 分支之外的所有本地分支。

git branch -l |grep -v master | xargs git branch -D

但是在乎刪除分支; 如果它是一個小存儲庫,只需刪除工作區並重新克隆它!

如果您不需要通過 Git 本身,您也可以手動或以編程方式刪除.git/refs/heads下的頭。 以下內容應在 Bash 下進行最少的調整:

shopt -s extglob
rm -rf .git/refs/heads/!(master)

這將刪除除您的主分支之外的每個本地分支。 由於您的上游分支存儲在.git/refs/remotes下,它們將保持不變。

如果您不使用 Bash,或者想一次遞歸大量 Git 存儲庫,您可以使用 GNU find 執行類似的操作:

find . \
    -path remotes -path logs -prune -o \
    -wholename \*.git/refs/heads/\* \! -name master -print0 |
xargs -0 rm -rf

find 解決方案可能更便攜,但修剪路徑和文件名很棘手,並且可能更容易出錯。

沒有一個答案完全滿足我的需求,所以我們開始吧:

git branch --merged | grep -E "(feature|bugfix|hotfix)/" | xargs git branch -D && git remote prune origin

這將刪除所有合並並以feature/bugfix/hotfix/開頭的本地分支。 之后上游遠程origin被修剪(您可能必須輸入密碼)。

適用於 Git 1.9.5。

盡管這不是命令行解決方案,但我很驚訝尚未建議使用Git GUI

我 99% 的時間都使用命令行,但在這種情況下,它要么太慢(因此是原始問題),要么在訴諸冗長但巧妙的 shell 操作時,您不知道要刪除什么。

UI 解決了這個問題,因為您可以快速檢查要刪除的分支,並提醒您要保留的分支,而無需為每個分支鍵入命令。

從 UI 轉到Branch --> DeleteCtrl+單擊要刪除的分支,以便突出顯示它們。 如果您想確保將它們合並到一個分支中(例如dev ),請在“僅在合並到時刪除”下將Local Branch設置為dev 否則,將其設置為Always以忽略此檢查。

GitUI:刪除本地分支

基於此處的多個答案的組合-如果您想保留遠程上存在的所有分支但刪除其余分支,則以下 oneliner 可以解決問題:

git for-each-ref --format '%(refname:short)' refs/heads | grep -Ev `git ls-remote --quiet --heads origin | awk '{print substr($2, 12)}'| paste -sd "|" -` | xargs git branch -D

如果您想保留 master、develop 和所有遠程分支。 刪除 Github 上不再存在的所有本地分支。

$ git fetch --prune

$ git branch | grep -v "origin" | grep -v "develop" | grep -v "master" | xargs git branch -D

1] 它將刪除遠程存儲庫中不再使用的遠程引用。

2] 這將獲得所有分支的列表。 從列表中刪除包含 master、develop 或 origin(遠程分支)的分支。 刪除列表中的所有分支。

警告 - 這也會刪除您自己的本地分支。 因此,當您合並分支並在合並、刪除后進行清理時,請執行此操作。

刪除所有本地 git 分支但保留 main

git branch | grep -v "main" | xargs git branch -D 

git branch -d [branch name]用於本地刪除

git branch -D [branch name]也用於本地刪除但強制它

對於 powershell,這將起作用:

git branch --format '%(refname:lstrip=2)' --merged `
    | Where-Object { $_ -ne 'master' } `
    | ForEach-Object { git branch -d $_ }

我的盒子上沒有 grep 或其他 unix,但這在 VSCode 的終端上有效:

git branch -d $(git branch).trim()

我使用小寫的 d 所以它不會刪除未合並的分支。

當我這樣做時,我也在 master 上,所以* master不存在,所以它沒有嘗試刪除 master。

我建議一個更溫和的答案。 這里的許多答案都使用-D強制刪除,無論更改是否已合並。 這是一個單一的襯里,它使具有未合並更改的分支保持不變。

git branch --merged | egrep -v "(^\*|master|dev)" | xargs git branch -d

或者您可以嘗試列出的其他示例,但只需將-D更改為-d 我知道 OP 詢問如何刪除,但在大多數用例中,使用-d更安全。

為此,您可以使用git-extras

$ git delete-merged-branches
Deleted feature/themes (was c029ab3).
Deleted feature/live_preview (was a81b002).
Deleted feature/dashboard (was 923befa).

一次刪除多個本地分支

# delete all local unmerged branches
git branch --no-merged | egrep -v "(^\*|master|dev)" | xargs git branch -D
# delete all local branches (merged and unmerged).
git branch | egrep -v "(^\*|master|dev)" | xargs git branch -D  

刪除遠程分支

# Deleting non-existent tracking branches
git remote prune <remote> --dry-run
# Deleting a single remote branch
git push <remote> --delete <branch>
# Deleting many remote branches at once
git branch -r --merged | egrep -v "(^\*|master|dev)" | sed 's/origin\///' | xargs -n 1 git push origin --delete

資源

以下腳本刪除分支。 使用它並自行承擔修改等風險。

基於這個問題的其他答案,我最終為自己編寫了一個快速的 bash 腳本。 我稱它為“gitbd”(git branch -D),但如果你使用它,你可以將它重命名為你想要的任何名稱。

gitbd() {
if [ $# -le 1 ]
  then
    local branches_to_delete=`git for-each-ref --format '%(refname:short)' refs/heads/ | grep "$1"`
    printf "Matching branches:\n\n$branches_to_delete\n\nDelete? [Y/n] "
    read -n 1 -r # Immediately continue after getting 1 keypress
    echo # Move to a new line
    if [[ ! $REPLY == 'N' && ! $REPLY == 'n' ]]
      then
        echo $branches_to_delete | xargs git branch -D
    fi
else
  echo "This command takes one arg (match pattern) or no args (match all)"
fi
}

它將提供刪除與模式參數匹配的任何分支(如果傳入),或者在不帶參數調用時刪除所有本地分支。 它還會為您提供確認步驟,因為您知道,我們正在刪除內容,這很好。

這有點愚蠢——如果沒有與模式匹配的分支,它就不會意識到這一點。

示例輸出運行:

$ gitbd test
Matching branches:

dummy+test1
dummy+test2
dummy+test3

Delete? [Y/n] 

我寫了一個 shell 腳本來刪除除develop之外的所有本地分支

branches=$(git branch | tr -d " *")
output=""
for branch in $branches 
do
  if [[ $branch != "develop" ]]; then
    output="$output $branch"
  fi
done
git branch -d $output

以上答案工作正常。 這是另一種方法,當我們在本地倉庫中有很多分支並且我們必須刪除許多分支,除了少數位於本地機器中的分支。

第一個git branch將列出所有本地分支。

通過運行 unix 命令將分支名稱列轉換為文件中的單行
git branch > sample.txt
這會將其保存在sample.txt文件中。 並運行
awk 'BEGIN { ORS = " " } { print }' sample.txt
shell中的命令。 這會將列轉換為行並將分支名稱列表復制到單行中。

然后運行
git branch -D branch_name(s)
這將刪除本地存在的所有列出的分支

最實用的方法:確保您沒有在master上提交未提交的工作,如果需要則提交/推送,克隆存儲庫的新副本,以及刪除舊的副本。

確保先執行此操作

git fetch

獲得所有遠程分支信息后,使用以下命令刪除除master之外的每個分支

 git branch -a | grep -v "master" | grep remotes | sed 's/remotes\/origin\///g' | xargs git push origin --delete

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM