118

問題: リモートを持たないすべてのローカル ブランチを削除する方法が必要です。ブランチの名前を にパイプするのは簡単git branch -D {branch_name}ですが、そもそもそのリストを取得するにはどうすればよいでしょうか?

例えば:

リモートなしで新しいブランチを作成します。

$ git co -b no_upstream

すべてのブランチを一覧表示しましたが、リモートがあるのは 1 つだけです

$ git branch -a
master
* no_upstream
remotes/origin/HEAD -> origin/master
remotes/origin/master

no_upstream回答を得るために実行できるコマンドは何ですか?

実行するgit rev-parse --abbrev-ref --symbolic-full-name @{u}と、リモートがないことが示されます。

$ git rev-parse --abbrev-ref --symbolic-full-name @{u}
error: No upstream configured for branch 'no_upstream'
error: No upstream configured for branch 'no_upstream'
fatal: ambiguous argument '@{u}': unknown revision or path not in the working tree.
Use '--' to separate paths from revisions, like this:
'git <command> [<revision>...] -- [<file>...]'

しかし、これはエラーであるため、使用したり、他のコマンドにパイプしたりすることはできません。これをシェルスクリプトのエイリアスとして使用するか、次のgit-delete-unbranchedような非常に単純なGemを作成するつもりですgit-branch-delete-orphans

4

10 に答える 10

136

git branch --formatコマンドから必要な正確な出力を指定するために使用することをお勧めしますgit branch。そうすることで、次のように refname とアップストリームだけを引き出すことができます。

git branch --format "%(refname:short) %(upstream)"

ブランチが存在する場合は、リモート ブランチとともにブランチを次の形式で出力します。

25-timeout-error-with-many-targets
31-target-suggestions refs/remotes/origin/31-target-suggestions
54-feedback-link refs/remotes/origin/54-feedback-link
65-digest-double-publish

この適切にフォーマットされた出力が得られたら、それをパイプしてawkリストを取得するのと同じくらい簡単です。

git branch --format "%(refname:short) %(upstream)" | awk '{if (!$2) print $1;}'

次の出力が得られます。

25-timeout-error-with-many-targets
65-digest-double-publish

awk2 番目の列がない場合、この部分は最初の列を出力します。

おまけ: エイリアスを作成する

グローバル.gitconfigファイル (または任意の場所)にエイリアスを作成して、簡単に実行できるようにします。

[alias]
  local-branches = "!git branch --format '%(refname:short) %(upstream:short)' | awk '{if (!$2) print $1;}'"

おまけ: リモートフィルタリング

何らかの理由で、異なるブランチに複数の追跡リモートがある場合、チェックするリモートを指定するのは簡単です。awk パターンにリモート名を追加するだけです。私の場合、それはorigin私がこれを行うことができるようにするためです:

git branch --format "%(refname:short) %(upstream)" | awk '$2 !~/\/origin\// { print $1 }'

重要: バックスラッシュはエイリアスでエスケープする必要があります。エスケープしないと、無効な gitconfig ファイルが作成されます。


前の回答

前の回答は機能的に似ていましたが、出発点として以下を使用しました。時間が経つにつれて、コメンターは、コミットメッセージで起こりうる差異のために正規表現が信頼できないと指摘しているため、この方法はお勧めしません. ですが、参考までに以下に。

私は最近、これがコマンドgit branch -vvの「非常に冗長な」バージョンであることを発見しました。git branch

ブランチが存在する場合は、リモート ブランチとともにブランチを次の形式で出力します。

  25-timeout-error-with-many-targets    206a5fa WIP: batch insert
  31-target-suggestions                 f5bdce6 [origin/31-target-suggestions] Create target suggestion for team and list on save
* 54-feedback-link                      b98e97c [origin/54-feedback-link] WIP: Feedback link in mail
  65-digest-double-publish              2de4150 WIP: publishing-state

この適切にフォーマットされた出力が得られたら、それをパイプしてリストを取得するのと同じくらい簡単ですcutawk

git branch -vv | cut -c 3- | awk '$3 !~/\[/ { print $1 }'
于 2015-08-02T20:24:57.230 に答える
39

git branch(オプションなし)ローカルブランチのみをリストしますが、それらがリモートブランチを追跡しているかどうかはわかりません。

通常、これらのローカル ブランチは、マージ後に削除する必要があります( git-sweep のこの問題にmaster見られるように)。

git branch --no-contains master --merged master | xargs git branch -d

これはあなたが望むほど完全ではありませんが、スタートです。

を使用--mergedすると、名前付きコミットにマージされたブランチ (つまり、名前付きコミットから先端コミットに到達できるブランチ) のみが一覧表示されます。

于 2013-03-27T15:02:36.627 に答える
25

同様の問題があります。現在削除されているリモート ブランチを追跡していたすべてのローカル ブランチを削除したいと考えています。git remote prune origin削除したいブランチを削除するには不十分であることがわかりました。リモートが削除されたら、ローカルも削除します。これが私のために働いたものです:

私から~/.gitconfig

[alias]
  prune-branches = !git remote prune origin && git branch -vv | grep ': gone]' | awk '{print $1}' | xargs -r git branch -d

git config --global ...これを次のように簡単に追加するコマンドを次に示しますgit prune-branches

git config --global alias.prune-branches '!git remote prune origin && git branch -vv | grep '"'"': gone]'"'"' | awk '"'"'{print $1}'"'"' | xargs -r git branch -d'

: Git がマージされていないブランチについて文句を言うのを聞きたくないので、実際の構成でを に変更-dしました。-Dこの機能も必要になる場合があります。その場合は、単にそのコマンドの最後に-D代わりに使用します。-d

また、FWIW、グローバル構成ファイルはほとんどの場合~/.gitconfig.

(OS X修正)

xargs -r書かれているように、これは(thanks, Korny )を使用しているため、OS X では機能しません。

は、ブランチ名なしで実行すると、エラー メッセージ " " が表示されるの-rを防ぐためのものです。エラー メッセージが気にならない場合は、引数を削除するだけで準備完了です。xargsgit branch -dfatal: branch name required-rxargs

ただし、エラー メッセージを表示したくない場合 (そして誰があなたを責める可能性があるか) は、空のパイプをチェックする別のものが必要になります。moreutilsからifneを使用できる場合。ifne前に挿入すると、空のデータでの実行xargsが停止します。:空ではないと見なされます。これには空白行が含まれるため、そのエラー メッセージが引き続き表示される場合があります。私はこれを OS X でテストしていません。xargsifne

これがそのgit configifneです:

git config --global alias.prune-branches '!git remote prune origin && git branch -vv | grep '"'"': gone]'"'"' | awk '"'"'{print $1}'"'"' | ifne xargs git branch -d'
于 2016-01-23T22:31:57.510 に答える
20

後期編集:

ベターは

git for-each-ref  --format='%(refname:short) %(upstream)'  refs/heads \
| awk '$2 !~/^refs\/remotes/'

GNU/なんでも

for b in `git branch|sed s,..,,`; do
    git config --get branch.$b.remote|sed Q1 && echo git branch -D $b
done

少数のブランチよりも多くの可能性がある場合はcomm -23、出力でgit branch|sed|sortandを使用して、より良い方法がありgit config -l|sed|sortます。

于 2013-03-27T23:02:45.330 に答える
0

既存の答えはどれも私にはうまくいかないようです。

リモートでもないローカルブランチをリストする私の解決策は次のとおりです

comm -13 <(git branch -r | sed 's/origin\/\(.*\)/\1/g' | cut -c 3-) <(git branch | cut -c 3-)

そして、これがどのように機能するかの説明です:

  1. すべてのリモート ブランチのリストを検討してください (「origin/」または先行スペースなし)。 git branch -r | sed 's/origin\/\(.*\)/\1/g' | cut -c 3-

  2. すべてのローカル ブランチのリストを検討してください (アスタリスクや先行スペースなし)。 git branch | cut -c 3-

  3. これらの 2 つのリストを比較して、リスト 1 (リモート ブランチのリスト) にないリスト 2 (私のローカル ブランチ) のすべてを表示してください。 comm -13 <(git branch -r | sed 's/origin\/\(.*\)/\1/g' | cut -c 3-) <(git branch | cut -c 3-)

comm は、フラグ -1、-2、および -3 の組み合わせを使用して、行を非表示にするファイルを示します (ファイル 1 に固有、ファイル 2 に固有、または両方に共通)

于 2020-12-18T18:48:45.977 に答える