この記事は12/19 の Git Advent Calendarの記事です。
ひょんなことから、リモートの Git サーバにある 4000 個のタグを一括削除することになりました。
タグ消すときはgit push origin :タグ名
でタグを消してたのですが、 4000 個もあると丸一日待っても終わらないので、他に素早く消せる方法はないだろうか、 とコマンドを探していたら良いものを見つけた、という備忘録です。
※タグについて書きますがブランチにおいても同様です。
:は区切り文字に相当しており、おそらく普段使っているように省略すると
git push origin master # 省略前
git push origin master:master # 省略後
のように扱われています。 これを応用すればローカルとリモートで異なるブランチ名に push できるのですが、そんなことする得が無いので基本省略すると思います。
:<dst>
part can be omitted—such a push will update a ref that<src>
normally updates without any<refspec>
on the command line. Otherwise, missing:<dst>
means to update the same ref as the<src>
.
— Git – git-push Documentation
で、:
を付けて左側に何も書かないと、「無と push する」みたいな動作になります。 これに関しては、どこぞの TAS 動画で「無を掴む」とか表現されたりするように、概念的に理解しようとするより、結果論で覚えたほうが早いと思います。
Pushing an empty
<src>
allows you to delete the<dst>
ref from the remote repository.
— Git – git-push Documentation
git push --delete origin hogehoge
のようなコマンドを叩くとリモートブランチが削除されます。
–delete > All listed refs are deleted from the remote repository. This is the same as prefixing all refs with a colon.
— Git – git-push Documentation
ただ、どうにも遅い。なんとかできないか調べてました。
Git-push は複数のブランチを一気に push できます。試したことがなかった。
git push origin :hoge :foo :bar
のようにやれば、複数のブランチ・タグを一括削除できます。 もしくは--delete
オプションをつけても内部挙動としては同じです。 1個ずつ指定していく場合と比べてめちゃくちゃ早いです。
タグを 100 個切ってリモートにあげてから、それを全部削除するまでの時間を図ってみました。 ネットワーク状況の揺れを最小限にするよう有線で試しましたが、それでも誤差はあると思います。
方法 | 時間 |
---|---|
1個ずつ+: |
8m40.951s |
1個ずつ+--delete |
8m35.192s |
一括+: |
0m14.854s |
一括+--delete |
0m4.338s |
はい、結果は歴然です。 一括削除したほうが圧倒的に早いです 。
私は、破壊的な操作をショートハンドでやるのは怖い(1 文字オプションも見間違い・勘違いが怖いので使わない)と思っているので、 セーフティという意味では十分意図通りの挙動と安全性を提供してくれていると思います。
ということで、これからはリモートにあるブランチやタグを一気にを消すときは--delete
オプションを愛用すると思います。