web-dev-qa-db-ja.com

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

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

怠惰や物忘れの組み合わせが原因で時間の経過とともに起こりがちなのは、私がローカルブランチの大規模なリストになってしまうことです。

すべてのローカルブランチを一覧表示する方法と単一のブランチを削除する方法はわかっていますが、すべてのローカルブランチを削除できるようにする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) - リリース
GNU grep 2.5.4

227
Louth

'git branch -d'サブコマンドは、複数のブランチを削除することができます。それで、@ sblomの答えを単純化しますが、重要なxargsを追加します:

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

または、さらに単純化して、

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

重要なのは、@ Andrew Cが指摘したように、スクリプトに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).
282
GoZoner

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

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

edit:色なしオプションを追加し、安定版ブランチを除外しました(必要に応じて他のブランチを追加します)。

127
mBardos

git branchの出力を解析することはお勧めできません。また、スタックオーバーフローに関する将来の読者にとっては良い答えではありません。

  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 branchを含むPorcelainコマンドをスクリプトで使用することは積極的に推奨されていません。コマンドからの出力は、人間が消費するユースケースを助けるために変更される可能性があるためです。

手動で.gitディレクトリ内のファイルを編集することを提案する回答(.git/refs/headsのような)も同様に問題があります(代わりにrefは.git/packed-refsにあるかもしれません。

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
74
Andrew C

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

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

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

55
sblom

ちょっと注意してください、私はgit 1.7.10にアップグレードするでしょう。あなたのバージョンではうまくいかないでしょう。私は、ブランチ名の前にrefs/heads/を付ける必要があると思います。

注意、作業フォルダと.gitディレクトリのコピーを作成した場合のみ、以下の手順に従ってください。

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

40
Adam Dymitruk

すべてのブランチを削除し、他のブランチを "Develop"や "master"のようにする簡単な方法は次のとおりです。

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

非常に便利 !

38
geoom

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

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

上記のコマンド

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

テキストエディタとシェルを使うほうが簡単だとわかりました。

  1. シェルにgit checkout <TAB>と入力します。すべての地元の支店を表示します。
  2. それらをテキストエディタにコピーして、必要なものを削除します。
  3. 改行をスペースに置き換えます。 (SublimeTextでは、とても簡単です。)
  4. シェルを開き、git branch -D <PASTE THE BRANCHES NAMES HERE>と入力します。

それでおしまい。

23
culebrón

私は似たような状況があり、最近以下のコマンドが役に立つことがわかりました。

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

これが誰かに役立つことを願っています。

11
4u.Ans

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

検索ソリューションはおそらくもっと移植性がありますが、パスとファイル名の刈り込みは注意が必要で、潜在的により間違いが起こりやすくなります。

7
Todd A. Jacobs

答えのどれも私の必要性を完全には満たさなかった、それでここに行く:

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

これにより、マージされてfeature/bugfix/またはhotfix/で始まるすべてのローカルブランチが削除されます。その後、アップストリームのリモートOriginが整理されます(パスワードを入力する必要があるかもしれません)。

Git 1.9.5で動作します。

4
user4401817

すべて削除するにはLinuxのローカルブランチを除くあなたがいるものを削除する

// hard delete

git branch -D $(git branch)
4
ashish yadav

ここにいくつかの答えの組み合わせに基づいて - あなたがしたい場合リモートに存在するすべてのブランチを残して残りを削除する、次の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
3

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

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

すべてのブランチにコマンドを入力しなくても、削除したいブランチをすばやく確認し、残したいブランチを思い出すことができるので、UIはこの問題を解決します。

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

GitUI: delete local branches

2
Dane Bouchie

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

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

上記の答えはうまくいきます。ローカルリポジトリにたくさんのブランチがあり、ローカルマシンにある少数のブランチを除いて多数のブランチを削除しなければならない場合、これは別のアプローチです。

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

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

そして走る
git branch -D branch_name(s)
これはlocalに存在する全てのリストされたブランチを削除します

0
Deepak G

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

0
Patrick Sanan

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
nhp

以下のスクリプトはブランチを削除します。それをあなた自身のリスクなどで使って修正してください。

この質問の他の答えに基づいて、私は自分のために簡単な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] 
0
dherman

PowerShellの場合、これは動作します:

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

あなたが最初にこれをするようにしてください

git fetch

すべてのリモートブランチ情報を入手したら、次のコマンドを使用してmaster以外のすべてのブランチを削除します。

 git branch -a | grep -v "master" | grep remotes | sed 's/remotes\/Origin\///g' | xargs git Push Origin --delete
0
Meng