2309

多くの Git ブランチがあります。すでにマージされているブランチを削除するにはどうすればよいですか? それらを1つずつ削除する代わりに、それらをすべて削除する簡単な方法はありますか?

4

48 に答える 48

3605

アップデート:

ワークフローに master や dev などのブランチが可能な祖先として含まれている場合は、除外する他のブランチを追加できます。通常、私は「sprint-start」タグから分岐し、master、dev、qa は祖先ではありません。

まず、リモートでマージされたローカル追跡ブランチを一覧表示します (他の回答で提案されているように、-r フラグを使用してすべてのリモート追跡ブランチを一覧表示することを検討できます)。

git branch --merged

削除したくないブランチがいくつか表示される場合があります。マスターや開発など、削除したくない重要なブランチをスキップする引数をいくつか追加できます。次のコマンドは、master ブランチと dev を含むブランチをすべてスキップします。

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

スキップしたい場合は、以下のように egrep コマンドに追加できます。ブランチskip_branch_nameは削除されません。

git branch --merged| egrep -v "(^\*|master|main|dev|skip_branch_name)"

現在チェックアウトされているブランチに既にマージされているすべてのローカル ブランチを削除するには:

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

master と dev が祖先の場合は除外されていることがわかります。


マージされたローカル ブランチは次の方法で削除できます。

git branch -d branchname

マージされていない場合は、次を使用します。

git branch -D branchname

リモート使用から削除するには:

git push --delete origin branchname

git push origin :branchname    # for really old git

リモートからブランチを削除したら、次のコマンドでプルーニングしてリモート追跡ブランチを取り除くことができます。

git remote prune origin

または、他の回答が示唆するように、次のように個々のリモート追跡ブランチを整理します。

git branch -dr branchname
于 2011-05-25T16:40:19.447 に答える
538

すでにマージされているリモート上のすべてのブランチを削除するには:

git branch -r --merged | grep -v master | sed 's/origin\//:/' | xargs -n 1 git push origin

Git の最近のバージョンでは

git branch -r --merged | grep -v master | sed 's/origin\///' | xargs -n 1 git push --delete origin

UPDATE (by @oliver; コメントに収まらないため、すでに十分な回答があります) : ブランチ ABC を使用している場合git branch -r --merged、ブランチが指定されていないため、ABC が結果に表示されます。したがって、ブランチはデフォルトで現在のブランチになり、ブランチは常にそれ自体にマージされたものと見なされます (ブランチとそれ自体の間に違いがないためです!)。

したがって、ブランチを指定します。

git branch -r --merged master | grep -v master ...

または最初のチェックアウト マスター:

git checkout master | git branch -r --merged | grep -v ...
于 2013-08-09T08:45:25.933 に答える
252

Adamの答えを少し拡張するだけです:

実行して、これをGit構成に追加しますgit config -e --global

[alias]
    cleanup = "!git branch --merged | grep  -v '\\*\\|master\\|develop' | xargs -n 1 -r git branch -d"

そして、単純なgit cleanup.

于 2014-02-18T15:08:26.177 に答える
116

masterこれらのコマンドから, main&developブランチを除外する必要があります。

ローカル git クリア:

git branch --merged | grep -v '\*\|master\|main\|develop' | xargs -n 1 git branch -d

リモート git クリア:

git branch -r --merged | grep -v '\*\|master\|main\|develop' | sed 's/origin\///' | xargs -n 1 git push --delete origin

リモート ブランチのローカル レジストリを同期します。

git fetch -p
于 2014-07-03T16:18:34.963 に答える
91

これは、マスターを除くすべてのマージされたブランチを削除する場合にも機能します。

git branch --merged | grep -v '^* master$' | grep -v '^  master$' | xargs git branch -d
于 2013-02-07T01:06:16.157 に答える
17

--merged オプションに commit を追加できます。このようにして、オリジン/マスターにマージされたブランチのみを削除するようにすることができます

次のコマンドは、オリジンからマージされたブランチを削除します。

git branch -r --merged origin/master | grep -v "^.*master" | sed s:origin/:: |xargs -n 1 git push origin --delete 

git push origin --delete を echo に置き換えて、どのブランチが削除されるかをテストできます

git branch -r --merged origin/master | grep -v "^.*master" | sed s:origin/:: |xargs -n 1 echo
于 2014-07-08T06:28:02.473 に答える
13

次の Ruby スクリプトを使用して、既にマージされているローカル ブランチとリモート ブランチを削除します。複数のリモートを持つリポジトリに対して実行していて、そのうちの 1 つだけを削除したい場合は、select ステートメントをリモート リストに追加して、必要なリモートのみを取得します。

#!/usr/bin/env ruby

current_branch = `git symbolic-ref --short HEAD`.chomp
if current_branch != "master"
  if $?.exitstatus == 0
    puts "WARNING: You are on branch #{current_branch}, NOT master."
  else
    puts "WARNING: You are not on a branch"
  end
  puts
end

puts "Fetching merged branches..."
remote_branches= `git branch -r --merged`.
  split("\n").
  map(&:strip).
  reject {|b| b =~ /\/(#{current_branch}|master)/}

local_branches= `git branch --merged`.
  gsub(/^\* /, '').
  split("\n").
  map(&:strip).
  reject {|b| b =~ /(#{current_branch}|master)/}

if remote_branches.empty? && local_branches.empty?
  puts "No existing branches have been merged into #{current_branch}."
else
  puts "This will remove the following branches:"
  puts remote_branches.join("\n")
  puts local_branches.join("\n")
  puts "Proceed?"
  if gets =~ /^y/i
    remote_branches.each do |b|
      remote, branch = b.split(/\//)
      `git push #{remote} :#{branch}`
    end

    # Remove local branches
    `git branch -d #{local_branches.join(' ')}`
  else
    puts "No branches removed."
  end
end
于 2012-09-27T23:41:23.850 に答える
9

Git には、これを自動的に行うコマンドはありません。ただし、Git コマンドを使用して必要なものを提供するスクリプトを作成することはできます。これは、使用している分岐モデルに応じてさまざまな方法で実行できます。

ブランチが master にマージされているかどうかを知る必要がある場合、myTopicBranch がマージされている (つまり、削除できる) 場合、次のコマンドは出力を生成しません。

$ git rev-list master | grep $(git rev-parse myTopicBranch)

Git branch コマンドを使用して、Bash のすべてのブランチを解析し、すべてのブランチに対してforループを実行できます。このループでは、ブランチを削除できるかどうかを上記のコマンドで確認します。

于 2011-05-26T07:41:46.640 に答える
8

git branch --merged | grep -Ev '^(. master|\*)' | xargs -n 1 git branch -dは、現在チェックアウトされているブランチおよび/または を除くすべてのローカル ブランチを削除しますmaster

これらのコマンドを理解しようとしている人には、次の記事が役立ちます: Git Clean: Delete Already Merged Branches, by Steven Harman

于 2014-10-23T21:06:52.557 に答える
7

私は git-flow 風の命名スキームを使用しているため、これは非常に安全に機能します。

git branch --merged | grep -e "^\s\+\(fix\|feature\)/" | xargs git branch -d

fix/基本的に、文字列またはで始まるマージされたコミットを探しますfeature/

于 2016-08-23T01:15:30.287 に答える
6

Adam の更新された回答のエイリアス バージョン:

[alias]
    branch-cleanup = "!git branch --merged | egrep -v \"(^\\*|master|dev)\" | xargs git branch -d #"

また、複雑なエイリアスをエスケープするための便利なヒントについては、この回答を参照してください。

于 2016-09-30T19:54:55.880 に答える
6

現在のブランチに既にマージされているすべてのローカル ブランチを削除したい場合は、以前の回答に基づいて、そうするための安全なコマンドを考え出しました。

git branch --merged | grep -v \* | grep -v '^\s*master$' | xargs -t -n 1 git branch -d

このコマンドは、現在のブランチまたはマスター ブランチには影響しません。また、xargs の -t フラグを使用して、実行前に何をしているかを通知します。

于 2014-01-23T16:24:57.327 に答える
5

受け入れられた解決策は非常に優れていますが、まだリモートにマージされていないローカル ブランチも削除するという 1 つの問題があります。

の出力を見ると、次のようなものが表示されます

$ git branch --merged master -v
  api_doc                  3a05427 [gone] Start of describing the Java API
  bla                      52e080a Update wording.
  branch-1.0               32f1a72 [maven-release-plugin] prepare release 1.0.1
  initial_proposal         6e59fb0 [gone] Original proposal, converted to AsciiDoc.
  issue_248                be2ba3c Skip unit-for-type checking. This needs more work. (#254)
  master                   be2ba3c Skip unit-for-type checking. This needs more work. (#254)

ブランチblaissue_248は、サイレントに削除されるローカル ブランチです。

しかし[gone]、リモートにプッシュされたブランチ (現在は削除されている) を示す という単語も表示されるため、ブランチを削除できることを示します。

したがって、元の回答は次のように変更できます (行の長さを短くするために複数行に分割)

git branch --merged master -v | \
     grep  "\\[gone\\]" | \
     sed -e 's/^..//' -e 's/\S* .*//' | \
      xargs git branch -d

まだマージされていないブランチを保護します。また、マスターがそれを保護するための grep は必要ありません。

于 2018-06-15T08:53:22.640 に答える
4

これらの回答のいくつかに基づいて、独自の Bash スクリプトも作成しました

git branch --mergedおよびを使用git branch -dして、マージされたブランチを削除し、削除する前に各ブランチについてプロンプトを表示します。

merged_branches(){
  local current_branch=$(git rev-parse --abbrev-ref HEAD)
  for branch in $(git branch --merged | cut -c3-)
    do
      echo "Branch $branch is already merged into $current_branch."
      echo "Would you like to delete it? [Y]es/[N]o "
      read REPLY
      if [[ $REPLY =~ ^[Yy] ]]; then
        git branch -d $branch
      fi
  done
}
于 2013-10-15T17:13:00.160 に答える
4

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

git branch -d $(git branch --merged | grep -vw $(git rev-parse --abbrev-ref HEAD))

を使用すると、現在のブランチ名git rev-parseを取得して除外します。エラーが発生した場合は、削除するローカル ブランチがないことを意味します。

リモート ブランチで同じことを行うには (originリモート名で変更します)、次を試してください。

git push origin -vd $(git branch -r --merged | grep -vw $(git rev-parse --abbrev-ref HEAD) | cut -d/ -f2)

複数のリモコンがある場合は、grep origin |beforecutを追加してorigin.

上記のコマンドが失敗した場合は、最初にマージされたリモート追跡ブランチを削除してみてください。

git branch -rd $(git branch -r --merged | grep -vw $(git rev-parse --abbrev-ref HEAD))

次にgit fetch、リモートを再度使用して、前のgit push -vdコマンドを再度使用します。

~/.gitconfig頻繁に使用する場合は、エイリアスとしてファイルに追加することを検討してください。

誤っていくつかのブランチを削除した場合はgit reflog、失われたコミットを見つけるために使用します。

于 2016-12-17T12:17:56.727 に答える
2

master 以外のブランチから誤ってコマンドを実行しないようにするために、次の bash スクリプトを使用します。そうgit branch --merged | grep -v "\*" | xargs -n 1 git branch -dしないと、マスターからマージされたブランチから実行すると、マスター ブランチが削除される可能性があります。

#!/bin/bash

branch_name="$(git symbolic-ref HEAD 2>/dev/null)" ||
branch_name="(unnamed branch)"     # detached HEAD
branch_name=${branch_name##refs/heads/}

if [[ $branch_name == 'master' ]]; then
   read -r -p "Are you sure? [y/N] " response
   if [[ $response =~ ^([yY][eE][sS]|[yY])$ ]]; then
       git branch --merged | grep -v "\*" | xargs -n 1 git branch -d
   fi
else
   echo "Refusing to delete branches that are not merged into '$branch_name'. Checkout master first."
fi
于 2014-01-20T17:05:13.130 に答える
1

git cleanupgit-toolbeltのスクリプト

マスターまたは開発に既にマージされているすべてのブランチを削除します。他の枝を横に保ちます。削除に関して最も保守的になります。

ローカルとオリジン リモートの両方でブランチを削除します。

于 2021-02-17T12:52:05.007 に答える
0

私の Bash スクリプトへの貢献は、大まかにmmrobin's answerに基づいています。

インクルードとエクスクルードを指定したり、両方ではなくローカルブランチまたはリモートブランチのみを調査/削除したりするために、いくつかの便利なパラメーターが必要です。

#!/bin/bash

# exclude branches regex, configure as "(branch1|branch2|etc)$"
excludes_default="(master|next|ag/doc-updates)$"
excludes="__NOTHING__"
includes=
merged="--merged"
local=1
remote=1

while [ $# -gt 0 ]; do
  case "$1" in
  -i) shift; includes="$includes $1" ;;
  -e) shift; excludes="$1" ;;
  --no-local) local=0 ;;
  --no-remote) remote=0 ;;
  --all) merged= ;;
  *) echo "Unknown argument $1"; exit 1 ;;
  esac
  shift   # next option
done

if [ "$includes" == "" ]; then
  includes=".*"
else
  includes="($(echo $includes | sed -e 's/ /|/g'))"
fi

current_branch=$(git branch --no-color 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/\1/')
if [ "$current_branch" != "master" ]; then
  echo "WARNING: You are on branch $current_branch, NOT master."
fi
echo -e "Fetching branches...\n"

git remote update --prune
remote_branches=$(git branch -r $merged | grep -v "/$current_branch$" | grep -v -E "$excludes" | grep -v -E "$excludes_default" | grep -E "$includes")
local_branches=$(git branch $merged | grep -v "$current_branch$" | grep -v -E "$excludes" | grep -v -E "$excludes_default" | grep -E "$includes")
if [ -z "$remote_branches" ] && [ -z "$local_branches" ]; then
  echo "No existing branches have been merged into $current_branch."
else
  echo "This will remove the following branches:"
  if [ "$remote" == 1 -a -n "$remote_branches" ]; then
    echo "$remote_branches"
  fi
  if [ "$local" == 1 -a -n "$local_branches" ]; then
    echo "$local_branches"
  fi
  read -p "Continue? (y/n): " -n 1 choice
  echo
  if [ "$choice" == "y" ] || [ "$choice" == "Y" ]; then
    if [ "$remote" == 1 ]; then
      remotes=$(git remote)
      # Remove remote branches
      for remote in $remotes
      do
        branches=$(echo "$remote_branches" | grep "$remote/" | sed "s/$remote\/\(.*\)/:\1 /g" | tr -d '\n')
        git push $remote $branches
      done
    fi

    if [ "$local" == 1 ]; then
      # Remove local branches
      locals=$(echo "$local_branches" | sed 's/origin\///g' | tr -d '\n')
      if [ -z "$locals" ]; then
        echo "No branches removed."
      else
        git branch -d $(echo "$locals" | tr -d '\n')
      fi
    fi
  fi
fi
于 2016-06-23T19:13:31.167 に答える
0

HubFlow や GitFlow などの分岐モデルを使用している場合は、このコマンドを使用してマージされた機能分岐を削除できます。

git branch --merged | grep feature.* | grep -v "\*" | xargs -n 1 git branch -d
于 2015-02-26T14:02:42.217 に答える
0

マージされたローカルブランチを削除し、それらのリモートを削除したい場合は、私が好むワンライナーを次に示します。

git branch --merged | xargs -I_br -- sh -c 'git branch -d _br; git push origin --delete _br'
于 2016-04-20T14:29:01.527 に答える