Help us understand the problem. What is going on with this article?

Git LFSが1.0になってGitHubで使えるようになったので試してみた

More than 3 years have passed since last update.

先日GitHub Universeをダラダラと聞いてたら、Git LFSの1.0がリリースされてGitHub上で使えるようになったらしいので試してみました。

  • 追記
    • 2016/8/20: まだベータでしたがBitbucketでも使えるようになってました。試したら詳しく追記します。
    • 2017/5/20: git lfs initgit lfs installrenameされていたのでその旨追記しました。

概要

Git LFSはGitHubが中心となって開発しているラージファイル(画像・音声・映像等)を扱うための拡張機能です。gitレポジトリにはテキストファイルのポインタを保存しておいて別の場所にラージファイルの実態を保存しておくことができます。これによって不要なファイルのpullやfetchをすることなくgitレポジトリの最新化ができるようになったりします。
先日のGitHub UniverseでLFS1.0のリリースとGitHub上でのLFS対応が発表されたので試してみました。

今回試した環境

  • 前提条件 - Git v1.8.2以上が必要
  • 試した環境 - Fedora22(x64)

インストール

  • 公式サイトからインストーラを入手。
    • 公式サイトにはインストーラを使う方法の他にrpmやdebによるインストールも記載されていましたが、自分の環境ではできませんでした。
  • インストーラを実行
インストール
tar xfz git-lfs-linux-amd64-1.0.0.tar.gz
cd git-lfs-1.0.0
sudo bash install.sh

独自のインストーラは使いたくなかったんですが、中身を見たら/usr/local/binにgit-lfsのバイナリを一つコピーしてgit lfs initするだけだったので気にせずインストーラを使いました。

ただ、少しだけ罠がありました。
git lfs initすると~/.gitconfgに以下のエントリを追加するんですが、sudo付けて実行するとrootユーザの.gitconfigに追加するので、インストール後に手動でgit lfs initを実行する必要があります。
(sudo付けないと/usr/local/binに書き込めない)

~/.gitconfigに追記される内容
[filter "lfs"]
        required = true
        clean = git-lfs clean %f
        smudge = git-lfs smudge %f

また、git lfs initするとカレントディレクトリに.git/hooks/pre-pushを作りますが、gitレポジトリ以外で打った場合は削除してしまってOKです。gitレポジトリではgit lfs initを毎回手動で打つ必要はなく、あとで出てくるgit lfs track等のコマンド実行時にpre-pushは自動で追加されます。

追記(2017/5/20)

久しぶりに使ったらfedoraでもdnf install git-lfsで入りました。またgit lfs initコマンドはgit lfs installrenameされてました。

使ってみる

pushする側

  • まず、ネットで拾ってきたパブリックドメインの画像ファイルを以下のように配置します。 images/1以下はpng、images/2、images/3以下はjpgがいくつか入ってます。
フォルダの中身
$ ls -lh images/1/ images/2/ images/3/
images/1/:
total 34M
-rw-rw-r-- 1 dk dk 1.8M Oct  3 07:17 abstract-20650.png
(以下略)

images/2/:
total 34M
-rw-rw-r-- 1 dk dk 2.3M Oct  2 21:21 garda-202068.jpg
(以下略)

images/3/:
total 35M
-rw-rw-r-- 1 dk dk 110K Oct  2 21:25 sun-49143_1280.jpg
(以下略)
  • 現在lfsの対象になっているファイルはtrackサブコマンドで確認します。
trackでlfsの対象を確認
$ git lfs track
Listing tracked paths
  • jpgをtrackするようにします。
jpgをtrackする
$ git lfs track "*.jpg"
Tracking *.jpg
  • track対象になったか確認します。
再度trackを実行
$ git lfs track
Listing tracked paths
    *.jpg (.gitattributes)
  • ここでカレントディレクトリに以下の内容の.gitattributesが出来上がっていました。
$ cat .gitattributes
*.jpg filter=lfs diff=lfs merge=lfs -text
  • また、track後に.git内にlfsフォルダが配置されました。
track前
$ ls .git/
branches  config  description  FETCH_HEAD  HEAD  hooks  index  info  logs  objects  refs
track後
$ ls .git
branches  COMMIT_EDITMSG  config  description  HEAD  hooks  index  info  lfs  logs  objects  refs
  • さらにpre-pushフックも自動で追加されました。
pre-push
$ cat .git/hooks/pre-push
#!/bin/sh
command -v git-lfs >/dev/null 2>&1 || { echo >&2 "\nThis repository is configured for Git LFS but 'git-lfs' was not found on your path. If you no longer wish to use Git LFS, remove this hook by deleting .git/hooks/pre-push.\n"; exit 2; }
git lfs pre-push "$@"
  • add、commit、pushは通常通りに行います。 commitまでするとls-filesサブコマンドで対象のファイルを確認できます。
ls-filesで対象のファイルを確認
$ git lfs ls-files
72efd47286 * images/2/garda-202068.jpg
f9a9d2f678 * images/2/golden-sunset-173594.jpg
(省略)
ecbaed3ab4 * images/3/sun-49143.jpg
699ef8586d * images/3/sun-49143_1280.jpg
(省略)

途中省略してますが、track対象をjpgのみにしたので、pngの画像ファイルは含まれていないことが分かります。

  • ここでpushしたらエラーになってしまいました。
pushでエラー
$ git push origin master
(21 of 21 files) 33.09 MB / 33.09 MB
Post https://api.github.com/lfs/daikikohara/lfs-test/objects/5e17ac7d1353e297e821eb4b49a54eb9db53b95b19ddccf6b324fdb4aea30453/verify: EOF
error: failed to push some refs to 'git@github.com:daikikohara/lfs-test.git'
  • が、再実行したら問題なく終わりました。
push再実行したら無事完了
$ git push origin master
(1 of 21 files, 20 skipped) 1.10 MB / 33.09 MB, 31.99 MB skipped
Counting objects: 25, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (23/23), done.
Writing objects: 100% (25/25), 3.45 KiB | 0 bytes/s, done.
Total 25 (delta 0), reused 0 (delta 0)
To git@github.com:daikikohara/lfs-test.git
 * [new branch]      master -> master
  • 念の為再度キレイな状態にしてやり直したら、今度は一発で大丈夫でした。ネットワークが不安定だったとかAPIがまだ不安定とかかもしれません。
キレイにして再実行したら一発でOKだった
$ git push origin master
(19 of 16 files) 40.43 MB / 34.85 MB
Counting objects: 20, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (19/19), done.
Writing objects: 100% (20/20), 2.71 KiB | 0 bytes/s, done.
Total 20 (delta 0), reused 0 (delta 0)
To git@github.com:daikikohara/lfs-test.git
   09eb0ff..ece1774  master -> master

pullする側

  • pullは普通に行なえます。
pullする
$ git pull origin master
remote: Counting objects: 25, done.
remote: Compressing objects: 100% (23/23), done.
remote: Total 25 (delta 0), reused 25 (delta 0), pack-reused 0
Unpacking objects: 100% (25/25), done.
From github.com:daikikohara/lfs-test
 * branch            master     -> FETCH_HEAD
 * [new branch]      master     -> origin/master
  • この状態だとファイルの中身はテキストファイルのポインタになっているためpullは一瞬で終わります。
中身がテキストなのでファイルサイズが小さい
$ ls -lh images/2
total 84K
-rw-rw-r--. 1 dk dk 132 Oct  3 14:42 garda-202068.jpg
(以下略)
  • ファイルの中身を見てみるとテキストなのが分かります。
jpgの中身を見てみる
$ cat images/2/garda-202068.jpg
version https://git-lfs.github.com/spec/v1
oid sha256:72efd472864c7faccdbbf832a4b63e7c2faff150eab3ad5ffc8c1df091084575
size 2402319
  • ファイルの実態をpullするにはgit lfs pullを使います。 lfs pullするとファイルの中身が画像ファイルとして見れるようになります。
ファイルの実態のpull
$ git lfs pull origin master
(21 of 21 files) 32.97 MB / 33.09 MB
  • ちなみに、includeやexcludeをすることもできるので、git pullは普通にしてラージファイルは必要なファイルのみlfs pullすればローカルは軽いままにしておけるし、pullやfetchで長時間待つこともないですね。 また、git pullすればgitレポジトリ自体は最新にできるので、チーム内等でlfs使ってない人がいても問題ないです。
includeとexclude
$ git lfs pull origin master --include=images --exclude=images/3
  • なお、GitHubのUI上ではファイルはテキストファイルのポインタじゃなくて普通に画像ファイルとして見れます。

以上。
簡単ですが使い方でした。
機能はもっと色々あるようなので詳細は公式サイトを見てもらえればと思います。

kiida
San Joseの教育系スタートアップ(YC W18)でCTO兼フルスタックソフトウェアエンジニアしてます。その前は同じくSan Joseの採用系スタートアップ、その前は日本のITコンサル(SIer?)的なところにいました。気軽に絡んでください。
https://daikikohara.github.io/about/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした