PIB - 20211021: git - local repos の shallow/unshallow 化

まとめ

local repos の shallow/unshallow 化は以下のようにすれば良い。
# shallow 化
git fetch --depth 1 origin HEAD
git branch | xargs git branch -d
git branch -r | xargs git branch -r -d
git tag | xargs git tag -d
git gc --prune=now
# unshallow 化
git fetch --unshallow

あと remote の branch, tag を知りたい時は --dry-run 付けて fetch
追加で shallow fetch したい場合は <repository> <refspec> ... 明示して --depth 1 で fetch

経緯

の流れで見つけた を見てたんだが、
git fetch --depth 1
で shallow 化
git fetch --unshallow
で unshallow 化
が出来るとのこと。

とりあえず後者はいいとして、
前者は remote の branch と tag が --depth=1 で全部降って来るので、それらの tree と blobs も一緒に拾ってしまい、完全な shallow にならない。

branch や tag を delete した上で gc すればいいのかな?と思ったのだが、tag は消えるのだけれど、
branch は
$ git branch -a
...
  remotes/origin/apt-mark
...
$ git branch -d  remotes/origin/apt-mark
error: branch 'remotes/origin/apt-mark' not found.
$ git branch -d remotes/origin/apt-mark
error: branch 'remotes/origin/apt-mark' not found.
$ git branch -D remotes/origin/apt-mark
error: branch 'remotes/origin/apt-mark' not found.
$ git branch -d origin/apt-mark
error: branch 'origin/apt-mark' not found.
$ git branch -D origin/apt-mark
error: branch 'origin/apt-mark' not found.
$ git branch -r -d remotes/origin/apt-mark
error: remote-tracking branch 'remotes/origin/apt-mark' not found.
$ git branch -r -D remotes/origin/apt-mark
error: remote-tracking branch 'remotes/origin/apt-mark' not found.
みたいな感じで、目の前に branch が確かに存在しているにも関わらず、なぜか git にそれ見つかんねーって言われて消せない。

仕方がないので「git delete error: branch remotes not found」とかでググってみたのだが
出てくるページ、出てくるページ
remote repos 上の branch を消す方法や
repote repos から消された branch を local repos から消す方法
でしばらく途方に暮れてしまった。

違うんだよ。今知りたいのは remote repos の状態は一切知らず触らず、local repos にある remote branch のみを消す方法なんだよ。


そいで、
git remote prune origin
やら
git fetch --prune
やら
git gc --prune
git gc --prune=now
やらいろいろ試した挙げ句に
ふとなんの気なしに
$ git branch -r
...
  origin/apt-mark
...
$ git branch -r -d origin/apt-mark
Deleted remote-tracking branch origin/apt-mark (was ef4b0bd).
みたいなことすると1個消えたので、あれ?っと思い、
$ git branch -r | xargs git branch -r -d
...
とかすると、片っ端から消す事に成功してしまったので、
もう一度 fetch してみると、先ほどと同様
$ git branch -d  remotes/origin/apt-mark
error: branch 'remotes/origin/apt-mark' not found.
みたいに消えてくれなくて、え?、え!?
みたいな感じで、消せた原因が特定できなくて、history に並んだコマンド片っ端から試して周って、しばらく悩む羽目になってしまった。

で、結論としては何のことはない、
git branch -r すると頭に "remotes/" が付かない branch 名が得られるので、それを git branch -r -d に食わせてやればよいというオチ。

fetch する際、余計な branch や tag を拾わないようにするには、
git fetch [<options>] [<repository> [<refspec>...]]
の [<repository> [<refspec>...]] を省略せず、きちんと明示してやればよかった。

あとは、上記まとめの通りで、branch と tag 削除した後、gc 書けてやれば完全に shallow 化出来る。