Sketch ファイルのバージョン管理

![sketch-on-git.png](https://qiita-image-store.s3.amazonaws.com/0/17936/79985247-fd50-656f-f8e3-c9c393fc384c.png)

## TL;DR

- [justInCase](https://justincase.jp) で使われている Sketch ファイル管理手法を紹介します
- この管理手法は [github で公開されています](https://github.com/justincase-jp/design_assets_template)
- 非エンジニアでも使えるように工夫していますが、まだ改善余地があります

## 前口上

BitBucket にはリポジトリの許容容量が 2GB という制限があり、それを超えるとリモートへの操作が激しく制限されます。

```sh
remote: Repository is in read only mode (over 2 GB size limit).
remote:
remote: Learn how to reduce your repository size: https://confluence.atlassian.com/x/xgMvEw.
```

バージョン管理システムの性質上、「ファイルの削除」しても履歴から消えるわけではなく、削除の操作が即リポジトリサイズの減少に繋がらない（むしろ増える）というのもあって、サイズリミットに達してしまうと管理が難しくなります。

バージョン管理システムで一般的に管理されるソースコード類は基本テキストファイルで、差分だけ保存していれば、それだけで 2GB を超えるのには相当な期間が必要です。

ところが、 Sketch ファイルを始めとするバイナリファイルをバージョン管理システムで管理すると案外あっさりリポジトリは肥大化します。

実際、 [justInCase](https://justincase.jp) で作成したデザイナー用のリポジトリは半年であっさり上限に達してしまいました。

これはその問題に敢然と立ち向かうエンジニアとデザイナーの戦いの記録（継続中）です。

## そもそも Sketch ファイルって……

[justInCase](https://justincase.jp) ではデザインツールに Sketch を利用しています。 Photosop や Illustrator など他のツールももちろん使っていますが、ことエンジニアとファイルを共有するという目的については Sketch を利用しています。

これまでも Sketch で利用されているファイル形式については[調べたことがあります](https://qiita.com/takkyun/items/b8c302674dc3223af0b1)。

Sketch は完全独自なバイナリフォーマットではなく、汎用的なファイル形式を利用する傾向にありましたが、[Sketch 43 からフォーマットが大幅に変更されました](https://sketchplugins.com/d/87-new-file-format-in-sketch-43)。

簡単にまとめると

- ファイルそのものは単なる zip
- 内部で利用さているビットマップイメージはオリジナルのものをそのまま保持
- json 形式 (つまり、テキスト) のメタデータでベクター情報を記録

ということになります。

### Sketch ファイルをバージョン管理する

つまることろ、ビットマップイメージを除いてはテキスト形式で保持されるというところが肝です。

これを受けて、[Real Design Version Control & Collaboration For Sketch Is Finally Here](https://blog.blended.io/how-to-use-sketch-with-git-the-right-way/) などを筆頭に Sketch ファイルをバージョン管理システム上で「正しく」扱う手法についての解説があります。

つまるところ

1. sketch ファイルを unzip
2. 各リソースを git などで管理
3. 使う前に sketch ファイルに戻す

ということをしましょうってことです。

この仕組を応用した専用 GUI ツールも登場してきています。

- [Abstract](https://www.goabstract.com/)
- [Kactus](https://kactus.io/)

などがありますが、調べたところ、内部でやっている操作は基本的に一緒で、

1. sketch ファイルを unzip
2. 各リソースを個別管理
3. sketch に渡す前にリソース群を zip して sketch ファイルに戻す

という操作を GUI でラッピングしているようです。

## justInCase 方式 Sketch ファイル管理手法

先にご紹介した[記事](https://blog.blended.io/how-to-use-sketch-with-git-the-right-way/)では、簡単なシェルスクリプトを使って、Sketch ファイルを unzip したものを git で管理します。同様に用意した簡易なシェルスクリプトを使って、 zip して sketch ファイルに戻してから利用します。

コマンドライン利用前提で、また管理するファイルをシェルスクリプトに追加する必要あったりして、若干利用に対する敷居が高い印象があります。

[記事](https://blog.blended.io/how-to-use-sketch-with-git-the-right-way/)でもその辺は触れられていて、 ["what to improve"](https://blog.blended.io/how-to-use-sketch-with-git-the-right-way/#whattoimprove) では改善案なども提示されています。例えば、 git-hook などを利用してシェルスクリプトの実行を自動化するなどですね。実際に [git-hook を利用する手法を公開している方もいらっしゃいます](https://medium.com/cloudaper/simple-git-versioning-for-sketch-5d77df01571e)。

[justInCase](https://justincase.jp) で行っている手法も基本的には git-hook を利用した自動化に当たるのですが、ちょっとだけアレンジしている部分があります。

- 非エンジニアが利用することを前提なので、セットアップを簡単に行えるように
- 非エンジニアが利用することを前提なので、ターミナル知らなくても利用できるように
- 普段は git で管理していることを意識しないで済むように

という部分に少し気を使っています。

### 準備

1. [design_assets_template](https://github.com//justincase-jp/design_assets_template) をチェックアウトする
2. `tools` ディレクトリ内にある `setup.command` をダブルクリックする

`setup.command` を実行すると、ターミナルが立ち上がり、 git-hook を所定の場所にセットアップしてくれます。利用するための準備はこれだけです。

`setup.command` を実行すると、 `_workspace` というディレクトリが作られるので、この中で全ての作業を行います。git で管理されているファイル群は `source` の中にあるのですが、普段は意識する必要はありません。

### 利用方法

そのままではローカルの `_workspace` にファイルを置くだけになってしまうので、git に反映させたいタイミングで `to_git.command` を実行します。すると、 `_workspace` の中の `sketch` ファイルが `source` にコピーされるので、それをコミット・プッシュしてもらいます。

サーバ側にプッシュされた内容はプルすると、自動的に `_workspace` に反映されるようになっています。なので作業を始める前にはプルしてサーバの最新情報を取得してから行うようにします。

つまり、まとめると

1. リポジトリを **pull** して、最新状態にする
2. `_workspace` の中に git で管理したいファイルを置く
3. `tools` ディレクトリ内にある `to_git.command` をダブルクリック
4. 更新されたファイルを git ツールで **push** する

という形で利用していくことになります。

### 利点と思われる点

- コマンドをダブルクリックするだけなので、ターミナルを知らなくても使える
- `_workspace` には Sketch ファイルだけじゃなく、他のファイルを置いてもらっても構わない
- 好きな git クライアントが使える

### 欠点と思われる点

- 手動操作 (コマンドのダブルクリック) が必要
- プルのたびに `source` から `_workspace` へのコピー操作が走るため、ちょっと重い
- `source` の内容を `_workspace` にコピーするためストレージ容量がその分必要になってしまう

## 今後の改善に向けて……

[justInCase](https://justincase.jp) では、この仕組みを導入後、

- 2GB 超えだったリポジトリ容量は（管理しているファイルが増えたのにも関わらず） **1/3 以下に削減**

できています。

仕組み上、「`source` の内容を `_workspace` にコピーするためストレージ容量がその分必要」な点は改善が若干難しいかもしれませんが、

- `sketch` プラグインなどを利用して、コマンドのダブルクリックの手間をなくす
- `source` にあるビットマップを git lfs などで管理するようにしてより git スペースを圧迫しないようにする
- プルした際には更新のあったファイルだけ `_workspace` にコピーするようにする

などの点が今後の課題としてあります。

[github でも公開しているので](https://github.com/justincase-jp/design_assets_template)、皆様のフィードバックもお待ちしています。