JupyterLab で Jupyter notebook（ipynb）の 差分を見やすく Git管理する

## TL;DR

Jupyter Notebook で分析を進める際、バージョン管理をしたいと思いGitで管理をしてみましたが、普通に進めるとNotebook のメタデータによって差分がとても見づらかったので、JupyterLab の `jupyterlab-git`と `nbdime`エクステンションを利用し、差分を見やすく表示できるようにしてみました。

## JupyterLab 環境を構築

今回の記事では、下記の環境を利用します。

- docker-compose を使用
    - docker-compose のインストールは [こちら](http://docs.docker.jp/compose/install.html) を参照
- コンテナイメージのベースは [kaggle-images](gcr.io/kaggle-images/python) を利用

Jupyter notebook のバージョンコントロールに必要な JupyterLab エクステンションは下記になります。

- [jupyterlab-git](https://github.com/jupyterlab/jupyterlab-git)
- [nbdime](https://github.com/jupyter/nbdime)
   - こちらは jupyterlab-git をインストールすると一緒にインストールされる

### 環境構築

下記２ファイルを作成します。

- Dockerfile
- docker-compose.yml

```dockerfile:Dockerfile
FROM gcr.io/kaggle-images/python:v74

RUN apt-get update && \
    apt-get install -y git \
    curl

RUN curl -sL https://deb.nodesource.com/setup_12.x | bash - &&\
    apt-get install -y nodejs

RUN pip install -U pip \
    jupyterlab && \
    pip install jupyterlab-git

RUN jupyter lab build
```

```yaml:docker-compose.yml
version: "3"
services:
  jupyter:
    build: .
    volumes:
      - $PWD:/tmp/work
    working_dir: /tmp/work
    ports:
      - 8888:8888
    command: jupyter lab --ip=0.0.0.0 --allow-root --no-browser
```

### Docker イメージのビルド

上記２ファイルを作成後、同ディレクトリにてビルドします。

```sh
$ docker-compose build
```

### コンテナを起動

ビルド後コンテナを起動します。

```sh
$ docker-compose up
```

起動後は http://localhost:8888/ にアクセスし、token を入力して JupyterLab にアクセスできます。
token とは起動後に出力される、例：`http://acb729d0c5ce:8888/?token=45d10c660d2e85f0c8d59995a04667c154542ae79f27f65d` の  `45d10c660d2e85f0c8d59995a04667c154542ae79f27f65d` にあたる箇所です。

### Extension Manager を Enable

起動後は Exxtension Manager を Enable します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184983/50ab8e9c-d3cd-7be7-07bc-44b4abf84d2e.png)
２つのエクステンションがインストールされています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184983/3a790193-5b38-b0cc-44ba-b1b8940f9d43.png)

## Notebook を Git でバージョン管理をする

### Git リポジトリ を Clone

必要なリポジトリをクローンします。すでに Notebook などがある場合は git init などをします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184983/e5bddc51-18bc-a05e-35f7-361683ee3a75.png)

リポジトリの URL を入力
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184983/3681b141-b4e9-e878-4d3a-053135579498.png)

Notebook (`test.ipynb`) を作成して first commit します。

```shell
$ git config --global user.email "you@example.com"
$ git config --global user.name "Your Name"
$ git add test.ipynb
$ git commit -m "first commit"
```

first commit 後、 Notebook で分析を進めたとします。例えば df.head() というコードを追加したとします。

### git diff での差分表示

まず、`git diff` コマンドで確認した場合は、下記のように Notebook のメタデータなどの差分が表示されてしまいとてもわかりづらいです。

```shell
# git diff
diff --git a/test.ipynb b/test.ipynb
index f6c1f17..5af6074 100644
--- a/test.ipynb
+++ b/test.ipynb
@@ -2,7 +2,7 @@
  "cells": [
   {
    "cell_type": "code",
-   "execution_count": 1,
+   "execution_count": 6,
    "metadata": {},
    "outputs": [],
    "source": [
@@ -21,7 +21,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 4,
+   "execution_count": 7,
    "metadata": {},
    "outputs": [],
    "source": [
@@ -30,12 +30,164 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 5,
+   "execution_count": 8,
    "metadata": {},
    "outputs": [],
    "source": [
     "df = pd.read_csv(data_dir + \"train.csv\")"
    ]
+  },
+  {
+   "cell_type": "code",
:

```
### JupyterLab nbdime での差分表示

JupyterLab にて nbdime を利用して diff を確認した場合は下記になります。ピンクの左側は変更前、緑の右側は変更後になります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184983/cc755567-9ba9-8df0-3184-9deda81844f5.png)

とても見やすく差分が表示されていると思います。


## 参考

- [Jupyter Notebook Manifesto: Best practices that can improve the life of any developer using Jupyter notebooks](https://cloud.google.com/blog/products/ai-machine-learning/best-practices-that-can-improve-the-life-of-any-developer-using-jupyter-notebooks)