すべてのローカルgitブランチを削除する


323

私は開発プロセスに従って、新しい機能やストーリーカードごとに新しいローカルブランチを作成します。終了したら、ブランチをマスターにマージしてからプッシュします。

怠惰または物忘れの組み合わせが原因で時間の経過とともに発生する傾向があるのは、ローカルブランチの多数のリストが作成され、その一部(スパイクなど)がマージされていない可能性があることです。

すべてのローカルブランチを一覧表示する方法と単一のブランチを削除する方法を知っていますが、すべてのローカルブランチを削除できる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、バージョン4.1.5(1)-release
GNU grep 2.5.4


7
@Andrewの回答を受け入れてください!
Robert Siemer 2015年


@GiulioCaccinこの質問は、マージされていない可能性のあるブランチにも関連しており、これを明示的に反映するように質問を更新しました。
ラウス2017

回答:


384

'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 | 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).

このコマンドは、以下の回答のコメントに記載されているのと同じエラーを報告します。error:branch 'STORY-123-Short-Description' not found.リストされているブランチごとに。
ラウス

1
私のために働く; 詳細を追加した上記を参照してください。
GoZoner、2012年

1
それで、git 1.7.10を使用して問題を解決しましたか、それとも.gitリポジトリで直接作業する方がいいですか?
GoZoner、2012年

1
error:branch 'STORY-123-Short-Description' not found.エラーが発生した場合は、おそらくgitのカラー設定が原因です。これは私にとっては--no-colorgit branch --no-color --merged | grep -v \* | xargs git branch -D
うまくいき

3
SOについての唯一の答えは、うまくいくことがわかりました。ありがとうございました!
Kevin Suttle

140

はgithubのこの問題に関するコメントでより良い方法を見つけました:

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

編集: no-colorオプションを追加し、stableブランチを除外(必要に応じて他のブランチを追加)


2
最後に、私が必要としていたソリューション
Code Whisperer

1
私はこれを試しましたがerror: branch 'my-branch-name' not found.、すべてのブランチに行き続けます。gitバージョン1.8.3.4(Apple Git-47)を使用します。なぜだろう?
wheresrhys 2014

'git branch --merged master | grep -vマスター| xargs echo 'は、削除しようとしているものを正確にデバッグしますか?より良いアイデアはありません...
mBardos 14

2
そう。git for-each-ref --format '%(refname:short)' refs/heads/ | grep -v master | xargs git branch -d
ПавелТявин

1
これと一緒にxargsの使用法を学びました。ありがとう
Volem 2017

105

の出力を解析することgit branchはお勧めできません。また、Stack Overflowの将来の読者にとっては良い答えではありません。

  1. git branch磁器コマンドとして知られているものです。磁器のコマンドは、マシンで解析されるようには設計されておらず、Gitの異なるバージョン間で出力が変わる可能性があります。
  2. git branch解析を困難にする方法(たとえば、色付け)で出力を変更するユーザー構成オプションがあります。ユーザーが設定した場合、color.branch出力に制御コードが表示されerror: branch 'foo' not found.ます。これを別のコマンドにパイプしようとすると、これが発生します。--no-colorへのフラグを使用してこれをバイパスできますがgit branch、他のユーザー設定が問題を引き起こす可能性があることを誰が知っていますか。
  3. git branch 現在チェックアウトされているブランチの横にアスタリスクを付けるなど、解析が面倒な他のことを行う可能性があります

gitメンテナーはgit branch出力に関するスクリプトについてこれを言っています

現在のブランチが何であるかを調べるために、カジュアル/不注意なユーザーがgitブランチをスクリプト化している可能性がありますが、これは誤りです。コマンドからの出力は人間の消費のユースケースに役立つように変更される可能性があるため、スクリプトでの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

git branch --no-color 2>/dev/null
nobar 2014年

5
それは確かに改善です。*をフィルターで取り除く必要があるという問題が常にあります。誰かが切り離されたヘッドから実行すると、面白いことになります。ただし、主な問題はgit branch磁器コマンドであり、将来のバージョンのgitで出力が変更されないという保証はありません。
Andrew C

@AndrewCに感謝-これは、謎の「ブランチが見つかりません」というエラーに関する質問への回答であり、より適切なコマンドを使用して解決策を提供します。👍
ジェイソン

2
「磁器」および「非磁器」GITコマンドはどのように識別されますか?
GoZoner 2016年

1
おそらくデフォルトで「dev」と「master」を除外するのに役立つ拡張でしょうか?
PandaWood 2017年

66

すべてのブランチを削除するより簡単な方法ですが、 "develop"や "master"などの他のブランチを維持する方法は次のとおりです。

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

非常に便利 !


8
古くなったスレッドを復活させ、既存のスレッドとほぼ同じ回答を投稿しました。バグがあり、安全性の変更がありません。これは良い答えではありません。
Andrew C

6
この答えは、gitブランチからの出力をパイプし、それを変更し、gitブランチ-Dに渡すことで明確になります。卑劣である必要はありません。
2015

この解決策は私にとってうまくいきました。ローカルブランチをすべて削除しました。
プラッド

1
これは、 'develop_feature'や 'master_feature'のような単語「develop」または「master」を含むブランチを削除しません。
django

これは私が👆🏻を探していた答えである
コンラッド・G

62

現在チェックアウトしているブランチ以外のすべてのブランチを削除するには:

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

最初の数回に変更git branch -D $bしてecho $b、意図したブランチが確実に削除されるようにすることをお勧めします。


1
このコマンドで私はerror:branch 'a_branch_name' not found.あなたが何をしようとしているのかを見ることができ、コマンドをいじってみましたが、なぜかgitは提供されたブランチ名が好きではないようです...
Louth

うーん。トラブルシューティングを行うために、git branch --merged
sblom

私のブランチ名は次の形式ですSTORY-123-Short-Description
Louth

を実行するとgit branch --merged、各行に1つずつリストが表示されますか?
sblom

1
それは文字通り言うのerror:branch 'a_branch_name' not found.ですか?または、git branch上記の出力からのブランチ名の1つについて文句を言っていますか?
sblom

52

以下のコマンドは、マスターブランチを除くすべてのローカルブランチを削除します。

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

上記のコマンド

  1. すべてのブランチをリストする
  2. リストからマスターブランチを無視し、残りのブランチを取る
  3. ブランチを削除する

4
git branch | grep -v "master" | xargs git branch -d安全のために、最初に使用するので、マージされていないブランチは削除しません。しかし、いい答えです!
Jonas Lomholdt、2018

3
これがpowershellバージョンです,@(git branch | Select-String -Pattern "[^(*?)\s? master]") | ForEach-Object{$_.Line.Trim()} | %{git branch -D $_}
Jonas Lomholdt

1
@baklazanこれは、いくつかのツールがインストールされている場合、Windows 10コマンドラインでのみ機能します。あなたはおそらくMINGWまたは他のそのようなものを持っていて、あなたはそれを知りません。
KthProg

42

ただのメモ、git 1.7.10にアップグレードします。ここでは、ご使用のバージョンでは機能しない回答を取得している可能性があります。私の推測では、ブランチ名の前にを付ける必要がありますrefs/heads/

注意:作業フォルダーと.gitディレクトリのコピーを作成した場合のみ、次の手順に進んでください。

たまに先に進み、不要なブランチを直接削除することもあり.git/refs/headsます。これらのブランチはすべて、それらが指すコミットの40文字のsha-1を含むテキストファイルです。.git/configそれらのいずれかに特定のトラッキングを設定している場合は、無関係な情報が含まれます。これらのエントリは手動で削除することもできます。


ついにシンプルで実用的なオプションが追加されました。気に入った:D
Melvyn

2
これは、参照をパックした場合、またはリモートサーバーから複製した場合(パックされたファイルを提供する場合)でも機能しません。refがパックされている場合、refは.git / refs / headsに保存されず、「packed-refs」と呼ばれるファイルに保存されます。git-scm.com/docs/git-pack-refsを参照してください。
Alexander Bird

1
現在チェックアウトしているブランチを削除するのは悪い考えのようです
Moberg

@Moberg事前にコミットをチェックアウトするだけで、切り離されたHEADは大丈夫です。
RomainValeri

34

次のシェルコマンドを試してください。

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

説明:

  • command git branch | grep -v "master"コマンドですべてのブランチを取得する
  • command xargsコマンドですべてのブランチを選択
  • withブランチを削除 xargs git branch -D

3
これは正解かもしれませんが。1行のコードは、何がどのようにして元の質問を解決するかを説明しないと、あまり役に立ちません。回答の詳細を記入してください。
RyanNerd

28

現在のブランチ以外Linuxのすべてのローカルブランチを削除するには

// hard delete

git branch -D $(git branch)

2
これは.gitにアクセスしてコンテンツを削除するよりも安全だと感じています。
nelsontruran

25

テキストエディタとシェルを使用する方が簡単だと思いました。

  1. git checkout <TAB>シェルを入力します。すべてのローカルブランチを表示します。
  2. それらをテキストエディターにコピーし、保持する必要があるものを削除します。
  3. 改行をスペースに置き換えます。(SublimeTextでは非常に簡単です。)
  4. シェルを開き、と入力しgit branch -D <PASTE THE BRANCHES NAMES HERE>ます。

それでおしまい。


あなたが立っている枝を取り除くことはできないと思います。
ドンタン2018

@Dongそのブランチの横に*があるので、コピーしたリストから削除するだけです!
メラニー

12

私も同様の状況で、最近次のコマンドが便利だとわかりました。

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 }'`

これが誰かを助けることを願っています。


1
素敵なものですが、機能させるためにバックgit branch -D `git branch | awk '{ if ($0 !~ /master/) printf "%s", $0 }'` ティックが必要でした- 実際には、元々は持っていたと思いますが、SOの書式設定で失われていました。
tassinari 2014

10

Windowsコマンドラインから、次のコマンドを使用して、現在チェックアウトされているブランチ以外をすべて削除します。

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

7

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

検索ソリューションはおそらくより移植性がありますが、パスとファイル名の整理はトリッキーであり、潜在的にエラーが発生しやすくなります。


涼しい。ビジュアル削除:)
Sandalone 2017

5

答えのどれも私のニーズを完全に満たしていなかったので、ここに行きます:

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

これによりfeature/、マージされ、bugfix/またはで始まるすべてのローカルブランチが削除されますhotfix/。その後、上流のリモートoriginが整理されます(パスワードの入力が必要になる場合があります)。

Git 1.9.5で動作します。


5

ここでのいくつかの回答の組み合わせに基づいて- リモートに存在するすべてのブランチ保持し、残りを削除する場合は、次のワンライナーがうまくいきます:

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

3

これはコマンドラインソリューションではありませんが、Git GUIに驚いていますはありませんががまだ提案されていないいます。

私は99%の時間でコマンドラインを使用していますが、この場合はかなり遅くなる(つまり、元の質問になる)か、長いが巧妙なシェル操作に頼るときに何を削除しようとしているのかわかりません。

UIはこの問題を解決します。ブランチごとにコマンドを入力しなくても、削除したいブランチをすばやくチェックして、保持したいブランチを思い出させることができるからです。

UIからブランチ->削除に移動し、削除するブランチCtrl +クリックして強調表示します。それらがブランチ(などdev)に確実にマージされるようにするには、[マージ先の場合のみ削除][ ローカルブランチ]をに設定しdevます。それ以外の場合は、常にチェックを無視するように設定します。

GitUI:ローカルブランチを削除する


1

powershellの場合、これは機能します。

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

0

次のスクリプトはブランチを削除します。使用、自己責任等で変更してください。

この質問の他の回答に基づいて、私は自分用の簡単なbashスクリプトを作成することになりました。私はそれを「gitbd」(gitブランチ-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] 

0

を除くすべてのローカルブランチを削除するためにシェルスクリプトを書きました 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

0

上記の回答は問題なく機能します。ローカルリポジトリに多くのブランチがあり、ローカルマシンにあるブランチを除いて多くのブランチを削除する必要がある場合の別のアプローチを次に示します。

最初 git branchにすべてのローカルブランチをリストします。

unixコマンドを実行して、ブランチ名の列をファイルの単一行に転置するには、
git branch > sample.txt
これをsample.txtファイルに保存します。そして走る
awk 'BEGIN { ORS = " " } { print }' sample.txt
シェルでコマンドをします。これにより、列が行に変換され、ブランチ名のリストが1行にコピーされます。

そして、実行し
git branch -D branch_name(s)ます。
これにより、ローカルに存在するすべてのリストされたブランチが削除されます


0

最も実用的な方法:でコミットされていない作業がないことを確認し、必要に応じてmasterコミット/プッシュし、リポジトリの新しいコピーを複製して、古いものを削除します。



0

私のボックスにはgrepまたは他のunixがありませんが、これはVSCodeのターミナルから機能しました:

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

小文字のdを使用して、マージされていないブランチを削除しないようにします。

私はそれを行ったときもマスターでしたので、マスター* masterが存在しないためマスターを削除しようとしませんでした。


確認済み:オンmasterでない場合、このコマンドは削除しmasterます。
ブレット

-1

最初にこれを行うことを確認してください

git fetch

すべてのリモートブランチ情報を取得したら、次のコマンドを使用して、マスター以外のすべてのブランチを削除します

 git branch -a | grep -v "master" | grep remotes | sed 's/remotes\/origin\///g' | xargs git push origin --delete
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.