Git のブランチとは?作り方・切り替え(switch と checkout の違い)・削除のしかた

PR
Git のブランチとは?作り方・切り替え(switch と checkout の違い)・削除のしかた
この記事は約31分で読めます。

Git のブランチは、コミット(変更の記録)の 1 つを指す、軽くて動かせる目印です。ブランチを作るのは git branch <名前>、切り替えるのは git switch <名前>、作ってすぐ切り替えるのは git switch -c <名前>、名前を変えるのは git branch -m、消すのは git branch -d <名前> です。git branch は、作るだけで切り替えません。

git switch は Git 2.23 で入ったコマンドで、昔からある git checkout でも同じ切り替えができます。この記事は、Git を使い始めた方に向けて、公式の文書(git-scm.com)に沿って、ブランチの作る・切り替える・名前を変える・消す、リモートのブランチの扱い、git switch と git checkout の違い、Git 2.56 で増えた git branch --delete-merged までを、1 本で引けるようにまとめたものです。

コマンドの出力は、git 2.39.3(Apple Git-145・macOS)のものです(2026年10月時点の最新は 2.56.0 です)。版で文が違うところは、版を添えて両方を載せました。リモートは、同じ PC の中に作った共有用のリポジトリで、alice と bob の 2 人が使う場面を作って流しました。ハッシュ(コミットの名前になる英数字)は、流すたびに変わる例です。

この記事でわかること
  • ブランチとは何か(コミットを指す動かせる目印)と、HEAD(いまいるブランチを指す目印)
  • 作る(git branch)・切り替える(git switch・git checkout)・作って切り替える(-c・-b)・名前を変える(-m)・消す(-d・-D)
  • git switch と git checkout の違い(Git 2.23 で switch が入った。2.51 で試験的の扱いが外れた)
  • リモートのブランチを手元で使う方法と、リモートのブランチを消す方法(git push --delete)
  • Git 2.56 の git branch --delete-merged が消すものと、消さないもの
  1. ブランチとは?
    1. ブランチの一覧を見るには?(git branch)
  2. ブランチを作るには?切り替えるには?
    1. 作る(git branch)
    2. 切り替える(git switch・git checkout)
    3. 作ってすぐ切り替えるには?(switch -c・checkout -b)
    4. 手元の変更があるときは?
  3. git switch と git checkout の違いは?
    1. 試験的の扱いは外れた(2.51 から)
    2. git checkout はなくなる?
  4. ブランチの名前を変えるには?(git branch -m)
  5. ブランチを消すには?(git branch -d と -D)
    1. -d は取り込み済みのブランチだけ消す
    2. 取り込んでいないブランチは断られる
    3. -D で消す
    4. いま開いているブランチは消せない
    5. HEAD に無くても、上流に取り込まれていれば消せる
    6. 消してよいブランチを探すには?
  6. リモートのブランチを使う・消すには?
    1. リモートにあるブランチを手元で使うには?(追跡ブランチと上流)
      1. 同じ名前が 2 つのリモートにあるとき
    2. リモートのブランチを消すには?(git push --delete)
      1. 手元のブランチと、ほかの人の origin/... はどうなる?
      2. GitHub の画面でブランチを消すには?
  7. 新しい版で増えた:git branch --delete-merged は何を消す?(Git 2.56)
    1. 文書は何と言っている?
    2. まず --dry-run で、消すものを見る
    3. 何が消えて、何が残った?
    4. squash で入れたブランチも消えない
    5. push -u で作ったブランチは、どう片付ける?
    6. そのほかの 2.56 の変更
  8. まとめ
  9. 参考資料

ブランチとは?

Pro Git(Git の公式サイトで読める本)は、Git のブランチを「コミットの 1 つを指す、軽くて動かせる目印(ポインタ)」だと説明しています。コミットを重ねるたびに、ブランチの目印は自動で前に進みます。

いま、どのブランチで作業しているかは、HEAD という特別な目印で分かります。HEAD は、いま作業しているローカル(自分の PC の中)のブランチを指します。

最初からあるブランチ(この記事の例では main)も、特別なものではありません。Pro Git は、ほかのブランチとまったく同じで、どのリポジトリにもあるのは git init が最初に作るからだと書いています。

Pro Git によると、ブランチの中身は、指すコミットの 40 文字のチェックサム(コミットの名前)を書いた小さなファイル 1 つです。そのため、ブランチは作るのも消すのも安く、一瞬で終わります。

ブランチの一覧を見るには?(git branch)

引数なしの git branch は、手元のブランチの一覧を出します。いまいるブランチには * が付きます(色の付く端末では緑色です)。

$ git branch
* main

見る範囲やくわしさは、オプションで変えられます。

コマンド出るもの
git branch手元のブランチ。いまのブランチに *
git branch -rリモート追跡ブランチ(origin/main のような、リモートのブランチの写し。くわしくは後の節)
git branch -a手元のブランチとリモート追跡ブランチの両方
git branch -v各ブランチの最後のコミット(ハッシュと 1 行目)。上流との関係も出る
git branch -vv-v に加えて、上流の名前も出る
git branch --show-currentいまのブランチの名前だけ(detached HEAD のときは何も出ない)
git branch --mergedいまのブランチ(HEAD)に取り込み済みのブランチだけ
git branch --no-mergedまだ取り込んでいないブランチだけ

手元の git 2.39.3 では、-r は origin/main の形、-a は remotes/origin/main の形で出ました。--merged・--no-merged・-v は、次のように出ました(side は、main にまだ取り込んでいないブランチです)。

$ git branch --merged
* main
$ git branch --no-merged
  side
$ git branch -v
* main b72ebf4 first
  side 3e1a3f5 side

--merged と --no-merged は、消してよいブランチを探すときに使います(くわしくは「ブランチを消すには?」の節)。

名前の形(パターン)で絞って一覧を出すときは、--list が要ります。付けないと、その名前のブランチを作る命令と読まれることがあります(公式の文書の注意です)。

Git 2.56.0 で試すと、git init してから git remote add したリポジトリでも、fetch のあとの git branch -a に remotes/origin/HEAD -> origin/main の行が出ました。手元の 2.39.3 では、clone したリポジトリにだけ出ました。

ブランチを作るには?切り替えるには?

作る(git branch)

git branch <名前> は、いまの HEAD が指すコミットを指す、新しいブランチを作ります。起点を書けば(git branch <名前> <起点>)、そのコミットから作ります。作るだけで、切り替えません。 作ったあとも、いるのは元のブランチのままです。

$ git branch feature
$ git branch
  feature
* main
$ git log --oneline --decorate
b72ebf4 (HEAD -> main, origin/main, feature) first

git log --oneline --decorate は、コミットに付いているブランチの名前を並べて見せます。作った直後は、同じコミットに main と feature の 2 つの名前が並びます。HEAD -> main は、HEAD が main を指している(いま main にいる)という意味です。

切り替える(git switch・git checkout)

git switch <ブランチ> が、指定したブランチへの切り替えです。作業ツリー(手元で編集しているファイルが置いてある場所)とステージ(git add したものを置く場所)がそのブランチに合わせて入れ替わり、このあとのコミットはそのブランチの先に足されます。

$ git switch feature
Switched to branch 'feature'
$ git branch --show-current
feature
$ git switch main
Switched to branch 'main'
Your branch is up to date with 'origin/main'.

git checkout feature でも、同じ切り替えができます(出力は Switched to branch 'feature')。2 つの違いは、後の「git switch と git checkout の違いは?」の節にまとめました。

git switch - は、ひとつ前にいたブランチへ戻ります(@{-1} と同じ意味です)。2 つのブランチを行き来するときや、間違えて切り替えたのを戻すときに使えます。

$ git checkout feature
Switched to branch 'feature'
$ git switch -
Switched to branch 'main'
Your branch is up to date with 'origin/main'.

作ってすぐ切り替えるには?(switch -c・checkout -b)

作ってすぐ切り替えることはよくあるので、1 回でできる書き方があります。

$ git switch -c topic
Switched to a new branch 'topic'
# (topic で 1 コミットして、main に戻った)
$ git switch main
Switched to branch 'main'
Your branch is up to date with 'origin/main'.
$ git checkout -b old-style
Switched to a new branch 'old-style'

git switch -c <新しいブランチ>(--create)は、起点からブランチを作ってから切り替えます。git branch <名前> と git switch <名前> を 1 つにしたもので、切り替えに失敗したときは、ブランチも作りません。git checkout -b <新しいブランチ> も同じです。Pro Git も、git checkout -b と、2.23 からの git switch -c を並べて紹介しています。

起点を書けば、どのコミットからでも作れます。公式の文書の例は git switch -c fixup HEAD~3(3 つ前のコミットから fixup というブランチを作る)です。起点を書かなければ、いまのコミットから作ります。手元では git switch -c fixup HEAD が、Switched to a new branch 'fixup' と出て作れました。

もうある名前で -c を使うと、止まります(終了コードは 128)。-C(--force-create)なら、そのブランチを起点に付け替えます(-C は流していません)。

$ git switch -c topic
fatal: a branch named 'topic' already exists

無い名前を渡したときの表示は、switch と checkout で違います。

$ git switch nosuch
fatal: invalid reference: nosuch
$ git checkout nosuch
error: pathspec 'nosuch' did not match any file(s) known to git

checkout は、渡された名前を、ファイルの名前として探しにいくためです(くわしくは下の「git switch と git checkout の違いは?」の節)。

手元の変更があるときは?

切り替えるのに、変更の無いきれいな状態である必要はありません。公式の文書は、切り替えると手元の変更が失われる場合にだけ、処理を止める(--discard-changes か --merge を付けたときは止まらない)と書いています。

手元の git 2.39.3 では、移り先のブランチで中身が違うファイルに、まだコミットしていない変更があると、git switch も git checkout も同じ表示で止まりました(終了コードは 1。git 2.56.0 でも同じ文でした)。

$ git switch side
error: Your local changes to the following files would be overwritten by checkout:
	a.txt
Please commit your changes or stash them before you switch branches.
Aborting

案内のとおり、変更をコミットするか、stash(変更を一時的にしまう機能)に入れてから切り替えます。しまい方はgit stash の記事にまとめました。

git switch と git checkout の違いは?

git switch と git restore は、Git 2.23(2019年8月)で入ったコマンドです。リリースノートによると、もとは git checkout 1 つでやっていた、「ブランチを切り替えて履歴を進める」と「ファイルをインデックス(ステージ)やコミットから取り出す」を分けたものです。

今の git checkout の文書も、主な働きを 2 つ挙げています。

  1. ブランチを切り替える(git checkout <branch>)
  2. ファイルを別の版に戻す(git checkout <commit> <filename> や git checkout <filename>)

git checkout <何か> は、それがブランチか・コミットか・ファイルかを Git が推し量って動きます。どちらとも取れるときは、ブランチかコミットとして扱います。ファイルとして扱わせるには -- を付けます(git checkout -- file.txt)。

git switch は、ブランチを切り替える側だけを受け持ちます。手元で流して、違いが出たところを並べました。

渡したものgit switchgit checkout
ブランチの名前切り替える切り替える
無い名前fatal: invalid reference(終了コード 128)error: pathspec … did not match any file(s) known to git(終了コード 1)
ファイルの名前fatal: invalid reference: a.txt で止まる。ファイルに触らないファイルを戻す(Updated 1 path from the index)
コミット--detach を付けないと切り替えないそのまま detached HEAD になる

ファイルの名前を渡した行は、とくに注意が要ります。手元の git 2.39.3 では、a.txt を書き換えてコミットしていない状態で git checkout a.txt を流すと、書きかけの変更が消えました(git 2.56.0 でも同じでした)。git switch a.txt は止まるだけで、ファイルには触りません。

$ git switch a.txt
fatal: invalid reference: a.txt
$ git checkout a.txt
Updated 1 path from the index
$ git status --short

a.txt という名前のブランチもあると、git checkout a.txt はブランチへの切り替えになり(変更は残る)、git checkout -- a.txt と書いたときにファイルが戻りました。ファイルを戻す役目は git restore が受け持ちます(reset・revert・restore の記事を参照)。

コミットの名前を渡したときの違いは、次のとおりです。git switch は、--detach を付けないと、ブランチでないものへは切り替えません。git checkout は、そのまま detached HEAD(ブランチを指さずに、特定のコミットに HEAD がある状態)になり、長い案内を出します。

$ git switch b72ebf4
fatal: a branch is expected, got commit 'b72ebf4'
hint: If you want to detach HEAD at the commit, try again with the --detach option.
$ git switch --detach HEAD
HEAD is now at b72ebf4 first

git checkout の案内の中では、ブランチを作って残すなら git switch -c <new-branch-name> を使うように勧められます。

試験的の扱いは外れた(2.51 から)

git switch と git restore は、Git 2.51 で「試験的(experimental)」の扱いが外れました。2.51.0 のリリースノートに、"no longer experimental" とあります。手元の git 2.39.3 に当たる版の文書(2.38.0 の git-switch)には、"THIS COMMAND IS EXPERIMENTAL. THE BEHAVIOR MAY CHANGE." と書いてあり、2.50.0 の文書にもありますが、最新の文書にはありません。

git checkout はなくなる?

Git 3.0 の予定でも、git checkout はなくなりません。公式の文書(BreakingChanges)は、git checkout の働きは git restore と git switch の 2 つでまかなえるが、git checkout を使う人がまだ多いので、3 つとも残る、と書いています(2026年10月時点の予定です。「ずっと残る」と決まったわけではありません)。Git 3.0 で変わる予定のことは、Git 3.0 の記事にまとめました。

2 つの違いのまとめです。切り替えだけなら、どちらでもできます。ファイルの名前を渡したときにファイルを巻き込む失敗が起きないのは、git switch のほうです。

ブランチの名前を変えるには?(git branch -m)

git branch -m <古い名前> <新しい名前> で、名前を変えます。そのブランチの設定と reflog(ブランチが動いた記録)も、いっしょに新しい名前へ移ります。新しい名前のブランチがもうあるときは、-m では止まり、-M を使うと変えられます。

$ git branch -m old-style renamed
$ git branch -m renamed topic
fatal: a branch named 'topic' already exists

古い名前を書かなければ、いまいるブランチの名前を変えます。

$ git switch -c tmp-name
Switched to a new branch 'tmp-name'
$ git branch -m tmp-name2
$ git branch --show-current
tmp-name2

ほかの人がまだ使っているブランチの名前は変えないのが、Pro Git の注意です。変えるときの手順として、Pro Git は次の 3 つを挙げています(リモート側の手順は、手元では流していません)。

  1. 手元で git branch --move <古い名前> <新しい名前>(手元だけの変更です)
  2. git push --set-upstream origin <新しい名前> で、新しい名前をリモートへ送る
  3. git push origin --delete <古い名前> で、古い名前をリモートから消す

ブランチを消すには?(git branch -d と -D)

-d は取り込み済みのブランチだけ消す

git branch -d <名前>(--delete)で、ブランチを消します。一度に何本でも書けます。消すブランチは、上流のブランチに(上流が無ければ HEAD に)全部取り込まれている必要があります。上流は、そのブランチがつながっているリモートのブランチのことで、くわしくは後の「リモートにあるブランチを手元で使うには?(追跡ブランチと上流)」にあります。

main に取り込み済みの feature は、消せました。

$ git branch -d feature
Deleted branch feature (was b72ebf4).

Deleted branch ... (was ...) の was のあとは、消したブランチが指していたコミットです。ブランチを取り込む(merge)ときに衝突が起きて止まったときは、Git のコンフリクトの記事を参照してください。

取り込んでいないブランチは断られる

まだ取り込んでいないコミットがあるブランチを -d で消そうとすると、断られます(終了コードは 1)。表示の文は、Git の版で違います。 小文字で始まる文になったのが 2.43.0、案内が hint: の行になったのが 2.44.0 です。

git 2.39.3(手元の Mac):

$ git branch -d topic
error: The branch 'topic' is not fully merged.
If you are sure you want to delete it, run 'git branch -D topic'.

git 2.56.0:

$ git branch -d topic
error: the branch 'topic' is not fully merged
hint: If you are sure you want to delete it, run 'git branch -D topic'
hint: Disable this message with "git config set advice.forceDeleteBranch false"

文が版で違うので、not fully merged と出たら、と覚えておくと確かです。

-D で消す

取り込んでいない作業を、本当に捨ててよいときだけ、案内のとおり -D で消します。-D は --delete --force の短い形で、取り込まれているかどうかに関係なく消します。Pro Git は、そうすると、その作業を失うことになると書いています。

$ git branch -D topic
Deleted branch topic (was 370cdb5).

いま開いているブランチは消せない

いまいるブランチは消せません。先に、ほかのブランチへ git switch してから消します。文は版で違い、2.43.0 から新しい文になっています。

# git 2.39.3
$ git branch -d main
error: Cannot delete branch 'main' checked out at '<パス>'

# git 2.56.0
$ git branch -d main
error: cannot delete branch 'main' used by worktree at '<パス>'

worktree は、1 つのリポジトリで複数のフォルダを同時に開く機能です(git worktree の記事を参照)。別の worktree で開いているブランチも、同じように消せません。

HEAD に無くても、上流に取り込まれていれば消せる

-d の条件は「上流に取り込まれている」ことなので、上流(たとえば origin/feature2)に取り込まれていれば、いまのブランチ(HEAD)に取り込まれていなくても消せます。そのときは警告が出ます。

$ git branch -d feature2
warning: deleting branch 'feature2' that has been merged to
         'refs/remotes/origin/feature2', but not yet merged to HEAD.
Deleted branch feature2 (was 1b16631).

消してよいブランチを探すには?

git branch --merged に出て、* の付いていないブランチは、-d で消してたいてい大丈夫、と Pro Git は書いています。作業がもう別のブランチに入っているので、何も失わないからです。--no-merged に出るブランチは、-d では消せません。

git branch -d -r <名前> のように -r を付けると、リモート追跡ブランチ(origin/...)を消します。意味があるのは、リモートにもう無いときか、git fetch でまた取ってこない設定のときだけです。古い origin/... をまとめて片付けるなら、後の「リモートのブランチを消すには?」の節の git fetch --prune が使えます。

リモートのブランチを使う・消すには?

リモートにあるブランチを手元で使うには?(追跡ブランチと上流)

bob が、リモートに新しいブランチ remote-only を push したとします。alice が git fetch で取ってきても、手で直せるローカルのブランチが自動でできるわけではありません。できるのは、origin/remote-only(リモート追跡ブランチ)だけです。これは、リモートのブランチの状態を指す目印で、自分では動かせません。

$ git fetch
From ../remote
 * [new branch]      remote-only -> origin/remote-only
$ git branch
* main
$ git branch -r
  origin/main
  origin/remote-only

このブランチで作業するには、git switch remote-only と名前を書くだけです。手元にその名前のブランチが無く、ちょうど 1 つのリモートに同じ名前のリモート追跡ブランチがあると、Git は git switch -c remote-only --track origin/remote-only と同じことをしてくれます(文書では --guess という動きで、既定で有効です)。

$ git switch remote-only
Switched to a new branch 'remote-only'
branch 'remote-only' set up to track 'origin/remote-only'.
$ git branch -vv
  main        b72ebf4 [origin/main] first
* remote-only 52a6233 [origin/remote-only] add r

2 行目の set up to track は、origin/remote-only を追跡するように設定した、という意味です。git branch -vv の [origin/remote-only] が、その追跡先です。この「追跡するリモートのブランチ」を upstream(上流) といい、上流を持つローカルのブランチを追跡ブランチといいます。追跡ブランチの上で git pull すると、どのリモートから取って、どのブランチを取り込むかを、Git が知っています(git pull はgit pull と git fetch の記事を参照)。手元の git 2.39.3 では、設定の branch.remote-only.remote が origin、branch.remote-only.merge が refs/heads/remote-only になりました。上流を決める git push -u は、Git コマンドの基本の記事にあります。

git checkout remote-only でも、同じことが起きました。この 2 行の並びは、記録の取り方で前後して出ることがあります。この自動の動きを止めたいときは --no-guess を付けます(設定は checkout.guess です)。

同じ名前が 2 つのリモートにあるとき

同じ名前のブランチが 2 つ以上のリモートにあると、Git は決められずに止まります(終了コードは 128)。

$ git switch remote-only
(hint の行が続く)
fatal: 'remote-only' matched multiple (2) remote tracking branches

hint: の案内の文は版で違い、2.56.0 では、リモートの名前を並べて、git switch --track <remote>/remote-only を案内します。リモートの名前をはっきり書いて作れば、止まりません。

$ git switch -c remote-only --track origin/remote-only
Switched to a new branch 'remote-only'
branch 'remote-only' set up to track 'origin/remote-only'.

公式の文書によると、設定の checkout.defaultRemote(たとえば origin)があれば、そのリモートを優先して使います(この設定は流していません)。

リモートのブランチを消すには?(git push --delete)

リモートのブランチを消すのは、git push <リモート> --delete <ブランチ>(-d でも同じ)です。名前の前に : を付ける書き方(git push origin :feature2)も同じ意味です。Pro Git のとおり、消えるのはサーバーにあるブランチの目印だけです。サーバーはデータをガベージコレクション(使われなくなったデータの掃除)が走るまでしばらく残すので、間違えて消してもたいてい戻せる、と Pro Git は書いています。

$ git push origin --delete remote-only
To ../remote.git
 - [deleted]         remote-only
$ git push origin :feature2
To ../remote.git
 - [deleted]         feature2

(2 つは別の場面で流しました。上は、bob が作ったブランチ remote-only を alice が消す場面、下は、alice が push -u した feature2 を消す場面です。)

手元のブランチと、ほかの人の origin/... はどうなる?

git push --delete で消えるのは、リモートのブランチです。自分の手元のブランチ(remote-only)は消えません。 git branch -vv には、上流がもう無いことを示す gone が付いて出ました。自分の origin/remote-only は、push のときに消えます。

$ git branch -vv
* main        b72ebf4 [origin/main] first
  remote-only 52a6233 [origin/remote-only: gone] add r

ほかの人の手元の origin/remote-only は、その人が git fetch --prune するまで残ります。 bob の側で試すと、ふつうの git fetch のあとも remotes/origin/remote-only が残り、--prune を付けたときに消えました。

$ git fetch
$ git branch -a
  main
* remote-only
  remotes/origin/HEAD -> origin/main
  remotes/origin/main
  remotes/origin/remote-only
$ git fetch --prune
From <リモートの場所>
 - [deleted]         (none)     -> origin/remote-only
$ git branch -a
  main
* remote-only
  remotes/origin/HEAD -> origin/main
  remotes/origin/main

bob の手元の remote-only(手元のブランチ)は、--prune のあとも残っていて、git branch -vv には [origin/remote-only: gone] と出ました。手元のブランチは、不要なら自分で git branch -d で消します。git fetch --prune の詳しい話(設定 fetch.prune・git remote prune・タグの注意)は、git pull と git fetch の記事にまとめました。

GitHub の画面でブランチを消すには?

GitHub では、書き込み権限があれば、閉じた・マージしたプルリクエストのブランチを消せます。開いているプルリクエストのブランチは消せません。GitHub のドキュメント(英語)によると、プルリクエストの下のほうに出る「Delete branch」で消し、「Restore branch」で戻せます。プルリクエストそのものは、プルリクエストの記事を参照してください。

新しい版で増えた:git branch --delete-merged は何を消す?(Git 2.56)

Git 2.56.0(2026年9月28日公開。2026年10月時点の最新)で、git branch --delete-merged が増えました。リリースノートの一文は、「追跡しているリモート追跡ブランチに、もう取り込まれたローカルのブランチを消す」です。

ただし、この一文だけを読んで「マージしたブランチがまとめて消える」と思うと、外れます。git push -u origin feature で作った、いつものブランチは、(push の設定を変えていなければ)マージ済みでも消えません。 一方で、origin/main から作っただけで、まだコミットしていないブランチは消えます。 消す前に、まず --dry-run で見てください。

手元の Mac の git(2.39.3)には、このオプションがありません(次のように出て、終了コードは 129 でした)。この節の表示は、Docker の公式イメージ(alpine:edge)に入れた git 2.56.0(Linux)で流したものです。

$ git branch --delete-merged origin
error: unknown option `delete-merged'
(使い方の一覧が続く)

文書は何と言っている?

公式の文書(git-branch)の言い方は、次のとおりです。設定した上流が <pattern> に合うローカルのブランチのうち、先端がその上流から辿れるものだけを消します。つまり、ブランチの作業が、つながっている上流にもう入っているものです。<pattern> には、ref(ブランチの名前)、リモートの名前(そのリモートの HEAD が指すブランチ)、origin/* のような形のどれでも書け、何度でも書けます。後ろに <branch-pattern> を書くと、消す候補のローカルのブランチを絞れます。

git branch [--dry-run] (--delete-merged <pattern>)... [<branch-pattern>...]

文書は、消さないものを 5 つ挙げています。

  1. 上流の ref がもう無いブランチ
  2. どこかの worktree で開いているブランチ
  3. branch.<name>.remote のリモートへ push すると、上流そのものが更新されるブランチ(pull した直後の「取り込み済みに見えるだけ」のブランチと見分けがつかないため。push と fetch の refspec で決まります)
  4. 消さないブランチの上流になっている、ローカルのブランチ
  5. 設定 branch.<name>.deleteMerged が false のブランチ

そして、取り込まれていないブランチは黙って飛ばします。それでも消したいときは -D を使います。

まず --dry-run で、消すものを見る

--dry-run を付けると、消すブランチを出すだけで、何も消しません。--dry-run は --delete-merged といっしょでないと使えません(fatal: --dry-run requires --delete-merged)。

下の表の 9 本のブランチがあるリポジトリで、--dry-run を流しました。値は、2 通りの書き方を見比べます。

$ git branch --dry-run --delete-merged origin
Skipping 'topicE' (branch.topicE.deleteMerged is false)
Would delete branch topicA (was 245c263).
Would delete branch topicG (was 371e68e).
$ git branch --dry-run --delete-merged 'origin/*'
Skipping 'topicE' (branch.topicE.deleteMerged is false)
Would delete branch topicA (was 245c263).
Would delete branch topicG (was 371e68e).
Would delete branch topicH (was 55fd2d7).

origin/* のように * を含む形は、引用符で囲んで 'origin/*' と打ちます(文書の例も同じです)。zsh を使っているなら、引用符が無いと no matches found: origin/* という文が出て、コマンドが git に届きません(手元の Mac の zsh 5.9 で、合うファイルが無いフォルダで確かめました。このとき git は動かしていません)。

書き方で、対象の範囲が変わります。

  • origin(リモートの名前だけ): そのリモートの HEAD が指すブランチ(この例では origin/main)を上流にするブランチだけが対象です
  • 'origin/*': origin/develop のように、origin の別のブランチを上流にしていても対象になります

上の例では、topicH(上流が origin/develop)が、この違いで現れました。

何が消えて、何が残った?

ブランチ上流状態origin で'origin/*' で
topicAorigin/mainマージ済み消える消える
topicGorigin/mainorigin/main から作っただけ(コミットなし)消える消える
topicHorigin/developdevelop にマージ済み(main には入れていない)対象外で残る消える
topicCorigin/mainまだマージしていない残る(黙って飛ばす)残る(黙って飛ばす)
topicDorigin/mainマージ済みだが、いま開いている残る残る
topicEorigin/mainマージ済みだが、deleteMerged が false残る(Skipping と出る)残る(Skipping と出る)
featureBorigin/featureBマージ済み(push -u で作った形)対象外で残る残る
featureForigin/featureFマージ済み。リモートで消して、git fetch --prune した対象外で残る残る(上流が無い)
mainorigin/mainいつもの main残る残る

--dry-run を外して、同じ 'origin/*' で流すと、Would delete と出た 3 本だけが消えました。

$ git branch --delete-merged 'origin/*'
Skipping 'topicE' (branch.topicE.deleteMerged is false)
Deleted branch topicA (was 245c263).
Deleted branch topicG (was 371e68e).
Deleted branch topicH (was 55fd2d7).

理由は、次のとおりです。

  • featureB が残る理由('origin/*' で流したとき): push の設定を変えていないと、push 先は同じ名前のブランチとみなされます。featureB を push すると origin/featureB が更新され、それが上流そのものです。文書の 3 つめ(pull した直後に取り込み済みに見えるだけのブランチと区別できない)に当たるため、消しません。
  • featureF が残る理由('origin/*' で流したとき): GitHub でブランチを消して git fetch --prune したあとは、上流が無くなっています。文書の 1 つめに当たります。
  • 消える主役は、上流を origin/main のように別の名前にしたブランチです(たとえば git switch -c topic origin/main で作ったもの)。
  • topicG が消える理由: コミットしていないブランチは、先端が上流から辿れる(取り込み済みとみなされる)ためです。作ったばかりのブランチを、うっかり消さないように、先に --dry-run で見てください。

branch.<name>.deleteMerged を false にしたブランチは、--delete-merged で消えません(既定は true です)。最初の分がマージされたあとも育てたいブランチ向けの設定で、git branch -d での削除には効きません。

squash で入れたブランチも消えない

GitHub の squash merge の代わりに、git merge --squash でまとめて main に入れたブランチも、残りました。ブランチの先端が上流から辿れないためで、--delete-merged が何も出さないだけでなく、git branch -d でも断られます(-D が要ります)。

$ git branch --dry-run --delete-merged origin
$ git branch -d topicS
error: the branch 'topicS' is not fully merged
hint: If you are sure you want to delete it, run 'git branch -D topicS'
hint: Disable this message with "git config set advice.forceDeleteBranch false"

push -u で作ったブランチは、どう片付ける?

git push -u で作ったブランチは、git branch -d で消します。リモートでブランチを消した場合は、先に git fetch --prune をします。(この出力は、同じ形で前に作った組で流したものです。ハッシュが上の例と違います)main を origin/main まで進めてから、featureB と featureF が、次のように消せました。

$ git branch -d featureB
Deleted branch featureB (was 85ed4de).
$ git branch -d featureF
Deleted branch featureF (was 551e9a5).

まだマージしていない topicC は、-d では断られました(文は上の「取り込んでいないブランチは断られる」のとおりです)。

そのほかの 2.56 の変更

ブランチに近い変更として、リリースノートには、git branch -d が、bisect(不具合の入ったコミットを探る機能)の途中で使われているブランチを消せないときに、その理由を出すようになったことと、git branch origin main のような打ち間違いを見つけて案内するようになったことも載っています。この 2 つは、流していません。

まとめ

  • ブランチは、コミットの 1 つを指す動かせる目印。いまいるブランチは HEAD が指す。作るのも消すのも安い
  • 作るのは git branch <名前>(切り替えない)、切り替えるのは git switch <名前>(git checkout <名前> でも可)、作って切り替えるのは git switch -c <名前>(git checkout -b <名前>)。ひとつ前に戻るのは git switch -
  • 切り替えは、手元の変更が失われるときだけ止まる。止まったらコミットか stash
  • git switch は 2.23 で入り、2.51 で試験的の扱いが外れた。git checkout <ファイル名> は書きかけの変更を消すことがあるが、git switch <ファイル名> は止まるだけ。Git 3.0 の予定でも git checkout は残る
  • 名前を変えるのは git branch -m。ほかの人が使っているブランチの名前は変えない
  • 消すのは git branch -d(取り込み済みだけ)。取り込んでいない作業を捨ててよいときだけ -D。「not fully merged」の文は版で違う。いまいるブランチは消せない
  • リモートのブランチは、git switch <名前> で追跡ブランチができる。リモートのブランチは git push origin --delete <名前> で消し、ほかの人の origin/... は git fetch --prune するまで残る
  • Git 2.56 の git branch --delete-merged は、push -u で作ったいつものブランチを(push の設定を変えていなければ)消さない。origin/main から作っただけのブランチは消える。先に --dry-run で見る

参考資料

※この記事は、公式の資料をもとに AI(Claude)で下書きし、2026年10月19日時点の公式の資料と照らして確かめてから公開しています。誤りに気づいたらお問い合わせからお知らせください。

PR
PR
タイトルとURLをコピーしました