GitLFSを導入しようとして心が折れた件

はじめまして、株式会社ORATTAの森と申します。

まず、前置きとしまして、内容が少し古い(2015/11/02時点 GitLFSのVersion1.0.2)です。

現在(2016/02/27)はGitLFSのVersionもだいぶ上がっていたり(Version1.1.1)、SourceTreeがGitLFSに対応したりといろいろ環境が変わっているので、下記するところからだいぶ改善されているのかもしれません。

改善されているといいな。(希望

なので導入のご参考程度に、こんなこともあったんだよと思って読んでいただけたらと思います。

また、改善されているよ!と、いう点ありましたらご教示頂けますと幸いです。


■GitLFSの導入を検討した経緯

弊社では、Gitでソースコード以外の画像やバイナリファイルなども管理してます。

そのため、職掌によっては不要なファイルをfetchするケースがあるのですが、それらが結構な量あるため、fetchに時間がかかるという問題が発生していました。

その問題が解消するのでは!と、いうところからGitLFSの導入を検討してみる運びとなりました。


■導入方法

1.インストール

GitLFSを利用するためには、まず、公式サイトからGitLFSをダウンロードし、利用する端末にインストールする必要があります。

Linux、Windows、Mac用のインストーラは公式サイトからダウンロードすることができます。

1-1.Windows

インストーラを起動して、インストール先にgit.exeと同じディレクトリを指定しインストールを完了させてください。

インストール完了後にGit Bashで「git lfs init」と打ち込んで、initが確認できればインストール完了です。

1-2.Linux

公式サイトからパッケージ(***.tar.gz)を取得しSCPなどでアップロードしてください。

パッケージを解凍後、生成されたディレクトリに移動し、ディレクトリ内のinstall.shを実行してください。

※ユーザごとにGitLFSを初期化する必要があるため、インストールしたユーザ以外でGitLFSを利用する場合は、そのユーザに変更後に「git lfs init」と打ち込んでください。

1-3.Mac

公式サイトからパッケージ(***.tar.gz)を取得してください。

パッケージを解凍後、生成されたディレクトリに移動し、ディレクトリ内のinstall.shを実行してください。

2.トラッキング(GitLFSで管理する)ファイルの設定

GitLFSで管理するファイルを設定する方法について紹介します。

2-1.トラッキング対象にする

Git Bashにて「git lfs track “.拡張子”」と、いうコマンドを実行することで対象ファイルをトラッキング対象にできます。

たとえば、JPGをトラッキング対象にしたい場合は、git lfs track “.jpg”となります。

2-2.トラッキング対象を確認する

Git Bashにて「git lfs track」というコマンドを実行することで、トラッキング対象を確認することができます。

トラッキング対象の追加を行った時点で、.gitattributesファイルができているので、このファイルを開くことでも確認できます。

2-3.トラッキングのタイミング

コミットをトリガにトラッキングが行われます。

具体的に何がトラッキング対象になっているか確認したいときは「git lfs ls-files」コマンドを実行してください。

GitLFSの導入方法については以上です。

トラッキングの設定についても、だれか設定して.gitattributesをpushしてあげればいいです。
簡単ですね♪


では、GitLFSのイケてないところについてです。

ここから私の心が折れた話になります。

1.git cloneがクソ重い

表題の通りでGitLFSインストール済みの端末で、GitLFSを利用しているリポジトリをcloneしようとするとクソ時間がかかります。

どうやら1ファイルずつダウンロードしているためにそんな事態に陥っているようです。(※1.0.1の時はダウンロードでこけていたのでまぁ、改善はされている?)

しかも、ほぼ確実にタイムアウトが発生して処理が途中で中断されます。

現状、git clone後、ダウンロードがはじまったら「ctrl + c」あたりでいったん中断して、対象ディレクトリ内に移動、
「git lfs fetch」→fetch完了後に「git reset -f HEAD」というやり方が一番効率よくcloneできました。

1-1.GitLFS未インストール状態でGitLFSを利用しているリポジトリを引く場合

GitLFSで管理しているファイルがすべてポインタファイル(130バイト程度のテキストファイル)として取得されるため非常に高速です。

GitLFSを利用する場合は、サーバエンジニアなどはGitLFSを端末に入れない(=ファイルの実体を見ない)ことで高速化の恩恵にあずかれます。

1-2.不必要なトラッキング対象だけ取得しない

GitLFSを端末にインストールしている場合でも、実体を引いてくる対象を絞ることで、cloneの高速化ができる場合があります。

つまり、webディレクトリにimageとsoundとあり、imageしか実体は必要ない場合などです。

この場合、「git config –global lfs.fetchexclude “実体を取得しないファイル(カンマ区切り)”」と、いうコマンド実行した後にgit cloneします。

JPG、PNGはほしいが、MP3とCKBはいらないよというような場合は「git config –global lfs.fetchexclude “.mp3,.ckb”」となります。

上記のとおりですので、作業上のメリットはエンジニアにはあるかもしれませんが、デザイナーやアニメータにはほぼないと思われます。(むしろデメリットが大きい?

2.対象の管理が無駄に賢すぎて逆にアホ

GitLFSのファイル引き当てにほとんど不具合と言って良い動作があり、これがGitLFSの導入を見送る決定打となりました。

実体を落としてこない場合に取得できるポインタファイルをテキストエディタで開くとわかるのですが、中にハッシュ値が書いてあります。

どうやらGitLFSはこのハッシュ値で実体を管理しているようです。というか、実体を一本釣りしているようです。

そしてどうやら、このハッシュ値はファイルパスやファイル名を考慮せずに求められているようです。

そのため、まず、a.gitに1.jpgをpushし、次にb.gitにも1.jpgをpushした場合、この2つのリポジトリには同じポインタファイルが置かれることになります。

非常に賢いのですが、ファイル名すら考慮していないようなので(実際に実験して確認してます)、ハッシュ値を求めるロジックを調べ上げないと、全く別のファイルで同じハッシュ値が生成されてしまう可能性を捨てきれないためかなり怖いです。

GitLFSのファイル管理

また、そんな管理をしているくせに、GitHub画面上のa.gitではプレビューを確認できますが、b.gitではプレビューを見ようとするとポインタファイルをテキストエディタで開いた時と同じものが表示されます。

何が言いたいかというと、GitHub側で対応できていない機能があるみたいです(と、いうかあります)。
また、この状態になるとgit lfs fetchでエラー吐いたりしていろいろと不具合が出ます。


以上から、当時開発中だったPJでは、とりあえず導入を見送る運びとなりました。

ですが、前置きにさせていただいた通り、あれから大分更新が行われたようなので、当時よりは使いやすくなっているかもしれません。

もし、機会があれば、再度導入記事を書くことになるやもしれません。。。

コメントを残す