[英]Batch file that will delete all local branches (git) in each subfolder of a directory
[英]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 上的未來讀者來說也不是一個好的答案。
git branch
是所謂的瓷器命令。 Porcelain 命令不是為機器解析而設計的,輸出可能會在不同版本的 Git 之間發生變化。git branch
的輸出(例如,着色)。 如果用戶設置了color.branch
,那么您將在輸出中獲得控制代碼,這將導致error: branch 'foo' not found.
如果您嘗試將其通過管道傳輸到另一個命令中。 您可以使用--no-color
標志繞過它到git branch
,但誰知道其他用戶配置可能會破壞什么。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
上面的命令
請注意,我會升級到 git 1.7.10。 您可能會在這里得到不適用於您的版本的答案。 我的猜測是你必須在分支名稱前加上refs/heads/
。
注意,僅當您制作了工作文件夾和 .git 目錄的副本時,才繼續執行以下操作。
有時我會直接從.git/refs/heads
中刪除我不想要的分支。 所有這些分支都是文本文件,其中包含它們指向的提交的 40 個字符的 sha-1。 如果您為其中任何一個設置了特定的跟蹤,您的.git/config
中將包含無關信息。 您也可以手動刪除這些條目。
刪除linux 中的所有本地分支,除了你所在的分支
// hard delete
git branch -D $(git branch)
我發現只使用文本編輯器和 shell 更容易。
git checkout <TAB>
。 將顯示所有本地分支機構。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()
}
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 --> Delete並Ctrl+單擊要刪除的分支,以便突出顯示它們。 如果您想確保將它們合並到一個分支中(例如dev
),請在“僅在合並到時刪除”下將Local Branch設置為dev
。 否則,將其設置為Always以忽略此檢查。
基於此處的多個答案的組合-如果您想保留遠程上存在的所有分支但刪除其余分支,則以下 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.