TL;DR
ローカルにベアレポジトリを作成して、それをcloneした後にlfs.url
を設定すれば帯域使わないので便利!
概要
複数台のビルドマシンで何かをビルドする場合、それぞれのワークスペースへcloneするのが一般的だと思います。
その際に複数のワークスペースが同じレポジトリを参照していることも良くあることだと思います。
そのような場合、同じデータを何度も取得することになってしまい通信帯域がもったいないといったことも多いのではないでしょうか。
特にgit lfs
を使用している場合などは転送料金に悩まされることも多いはず。
そこで今回はgit lfs
を使う際に転送料金をケチる削減する方法を試してみたいと思います。
OSS(別解)
私は使ったことがないのですが、lfscacheといったOSSを導入することも一つの手です。
恐らくは変なことをするよりも躓くことが少なくなるのではないかと思います。
ただ、今回は別の(原始的な)アプローチをしようと思います。
今回のアプローチについて
今回はベアレポジトリを使用する方法を使ってみます。
単なるベアレポジトリに関しては詳しい記事が多く出てきますので詳しいことは省きます。
ビルドマシンから参照する方法についても各システムでアプローチが異なるため省きます。
ではこの記事でどういったことを解説するかというと、ベアレポジトリに対してgit lfs
を使用した際の設定方法などです。
概要
実は私が手元でGIT_TRANSFER_TRACE=1
を付けて試す限りでは、ローカルレポジトリのcloneなら何も設定しなくてもローカルレポジトリを参照しにいっているようでした。つまりは特に何かする必要はなさそうです。
ただ、勝手に調整されるのが個人的に気に入らない不安なので明示的に指定する方法を記載してみます。
git-lfsには挙動を制御するconfigがあります。
この中にlfs.url
というものがあり、今回はこれを使用します。
この時にfile://
を使えるということがポイントです。
マニュアル:
https://github.com/git-lfs/git-lfs/blob/main/docs/man/git-lfs-config.adoc
https://github.com/git-lfs/git-lfs/blob/main/docs/man/git-lfs-standalone-file.adoc
Note
作業中はexport GIT_TRANSFER_TRACE=1
しまってもいいと思いますが、この記事中は必要な部分を明示する意味も兼ねてそうしない状態で解説します。
設定方法
.lfsconfig
で設定する方法といつもながらの .gitconfig
や .git/config
で設定する方法があります。
マニュアル の記載を見ると今回の用途では .git/config
で設定するのが良さそうです。
1. 参照元となるレポジトリをcloneする
こちらは通常通りのcloneで良いと思いますが、前述した通り今回はベアレポジトリにします。
ベアレポジトリの場合、git lfs fetch
は自動で行われないようなので忘れずに手動で実行しましょう。
git clone --bare https://url/to/repository.git
git -C path/to/repository lfs fetch
Note
この時に後述するGIT_TRANSFER_TRACE=1
を設定しておけばgit lfs
がどういう通信を行っているのかを確認することができます。
Note
この時は流石にLFS帯域を使用しますのでご了承ください。
2. 参照先となるレポジトリをcloneする
1で作成したローカルレポジトリから更にレポジトリをcloneします。
この時にgit lfs
が動いてしまわないように GIT_LFS_SKIP_SMUDGE=1
を指定しておきます。
GIT_LFS_SKIP_SMUDGE=1 git clone path/to/repository.git
Note
GIT_TRANSFER_TRACE=1 git clone path/to/repository.git
してみたところ正常にcloneできました。
前述の通り通常は何もしなくても自動で調整してくれるようです。
この時にLFS対象のファイルをcatすると以下のような出力がされると思います。
されなければ GIT_LFS_SKIP_SMUDGE=1
が効いていないのでご注意ください。(帯域を消費しています)
$ cat path/to/file
version https://path.to.lfs/spec/v1
oid sha256:hash
size ????
3. 参照元となるレポジトリをLFSの参照先とする
2でcloneだけしたレポジトリのconfigにlfs.url
を追加します。
vimで編集する場合は以下のような感じです。(emacsなりnanoなりcodeなりとお好きなエディタをご利用ください)
vim path/to/repository/.git/config
[lfs]
repositoryformatversion = 0
# ↓を追加。参照元となるレポジトリへのパスを設定
url = file://path/to/repository.git/
4. git lfs fetchを実行する
これまでで設定ができましたので git lfs fetch
してみましょう。
この時に GIT_TRANSFER_TRACE=1
とすることで転送の様子がログに出てくるので確認するとよいでしょう。
GIT_TRANSFER_TRACE=1 git lfs fetch
以下のようなログが出ていればローカルファイルが参照されていると思われます。
...(前略)...
HH:MM:SS.000000 trace git-lfs: fetch path/to/file [hash]
...(中略)...
HH:MM:SS.000000 trace git-lfs: xfer: Custom adapter worker 0 received response: {"event":"complete","oid":"hash","path":"D:\\path\\to\\repository\\.git\\lfs\\tmp\\lfs-standalone-file-1883205854\\download3252211190"}
...(後略)...
ちなみにgithub.comへアクセスした場合は以下のようなログが出ます。
HTTPという文字が出てしまうと帯域を使用しているという判断で良いと思います。
...(前略)...
HH:MM:SS.000000 trace git-lfs: fetch path/to/file [hash]
...(中略)...
HH:MM:SS.000000 trace git-lfs: HTTP: POST https://github.com/path/to/repository.git/info/lfs/objects/batch
...(中略)...
HH:MM:SS.000000 trace git-lfs: HTTP: {"objects":[{"oid":"hash","size":1193,"actions":{"download":{"href":"https://github-cloud.githubusercontent.com/alambic/media/161987690/94/c3/hash?{何らかのパラメータ}
HH:MM:SS.000000 trace git-lfs: HTTP: {何らかのパラメータ}","expires_at":"YYYY-MM-DDTHH:MM:SSZ","expires_in":3600}}}]}
...(後略)...
5. 完成
後はCIなど各々が必要な箇所で使用してください。