共用リポジトリ内で自分専用の名前空間を使う: Git namespaces

Posted on 2021/03/01 in tech

独自の名前空間に push できる機能、gitnamespaces を紹介します。

基本的な使い方

オプション

--namespace オプションを git コマンドの直後に付与します。

$ git --namespace=me push origin main
$ git --namespace=me fetch origin

上記例では、名前空間 me に push しています。

環境変数

GIT_NAMESPACE 環境変数を利用します。

$ GIT_NAMESPACE=me git push origin main
$ GIT_NAMESPACE=me git fetch origin

名前空間の仕組み

名前空間 me に push されたリモートリポジトリ上では、ブランチ [1] はどのように管理されるのでしょうか。git ls-remote コマンドで見てみます。

$ git --namespace=me push origin main                                                                                   [git][blog/.][main]
$ git --namespace=me ls-remote                                                                                          [git][blog/.][main]
From /home/user/git/nicerepo.git
fa41c76047cf0c65736be4687804c187d1c58b64        refs/heads/main

名前空間 me を指定すると通常通り refs/heads/ 配下にブランチ HEAD が作成されているように見えます。
しかし、名前空間を指定しないで git ls-remote すると、

$ git ls-remote
From /home/user/git/nicerepo.git
fa41c76047cf0c65736be4687804c187d1c58b64        refs/heads/main
fa41c76047cf0c65736be4687804c187d1c58b64        refs/namespaces/me/refs/heads/main

me という名前空間が refs/namespaces/ 配下に作成され、 その中で refs/heads/mainmain のブランチ HEAD )が管理されていることがわかります。

注意点

名前空間はリモートリポジトリ のみ に作成される

ドキュメントの Description 上に

Git can expose each namespace as an independent repository to pull from and push to
(意訳)
Git はそれぞれの名前空間を pull 元と push 先のリポジトリが独立したリポジトリとして公開できます

とあるように、リモートリポジトリ のみ に名前空間を作成し、 ローカルリポジトリ 上へは、名前空間が作成されません。

つまり、

git fetch origin main

git --namespace=xxx fetch origin main

fetch 元は別 だが 保存先の(ローカルの) refs は同じ になります。

環境変数に設定して別の名前空間を使いたくなった場合

GIT_NAMESPACE を設定した場合、その名前空間内へ 常に push し、また pull / fetch も常にこの名前空間から行われることになります。

これを一時的に変更・無効化したい場合は --namespace オプションで指定する名前空間を上書きできます。

例えば通常の(名前空間のない)main ブランチから fetch したい、という場合は以下のようにします。

$ git --namespace= fetch origin main

ネストした名前空間

--namespace=foo/bar のように名前空間を階層化することもできます。

この場合リモートリポジトリ上で管理される refs は

refs/namespaces/foo/refs/namespaces/bar/refs/…​

のようになります。名前空間内で別の名前空間を作成する ということですね。


いまでこそ ブラウザ上でフォークしてプルリクエストしてブラウザ上でマージしてもらう、ということが当たり前のようになりましたが、 特に OSS の分散開発では、各自が各自で管理するリポジトリをもつ ことが想定されています。
(「うちのリポジトリから pull してよ!」という意味合いで プルリクエスト、という名前なわけですね)

その延長で 1 つのリポジトリを複数人で共有したい と考えたときに gitnamespaces を利用するのは理に適っている言えそうです。

事故防止にも役立つ機能かと思うので、ぜひご活用ください。


1. ブランチに限らずタグや notes などの refs 全般

git