ローカル環境のコード差分をリモートで実行する際に再現性を担保できるコマンドラインツール「Git Ghost」公開

Daisuke Taniwaki

2019-05-13 08:00:37

概要

大村谷脇で開発したローカル環境のコード差分をリモートで実行する際に再現性を担保できるコマンドラインツールGit Ghostをオープンソースとして公開しました。このツールを使うことで、試行錯誤しながら実験をするフェーズにおいても、以前修正して実行したローカル環境のコードに簡単に戻ることができます。

開発の動機

機械学習のジョブを実行中に試行錯誤でさらに他のジョブを実行することはよくあります。Git Ghostを作る前では、そのための一番単純な方法として、例えば、ソースコードをgitで管理し、rsyncコマンドでローカル環境での差分をKubernetesクラスターに同期して機械学習ジョブを実行していました。その際、実行したプログラムが良い結果を出した場合に、以前に修正したコードに戻りたいことがよくありましたが、この方法では、gitでソースコードをバージョン管理していても、rsyncで同期したローカル環境での差分についてはバージョン管理がされていないため、以前のコードに戻ることは困難でした。

これに対処するための1つのアイデアとして、ローカル環境での修正を全てコミットしてリモートにプッシュすることがまず考えられます。しかし、たった数文字の変更のためにコミットしてプッシュするのは非常に面倒であり、リモートのレポジトリーがこの細かい修正で汚れてしまうのを好む人はいないでしょう。そこで我々はこのツールを開発することにしました。

使用方法

ローカル環境で行ったfooというファイルの中身をaからbに変更する修正をリモート環境にあるディレクトリーに送りたい場合を考えます。

まず、ローカル環境の差分パッチをGit Ghostで作成します。

$ git ghost push
xxxxxxx yyyyyyy
$ git ghost show yyyyyyy
diff --git a/foo b/foo
index 7898192..6178079 100644
--- a/foo
+++ b/foo
@@ -1 +1 @@
-a
+b

そして、リモート環境に移動し、以下のコマンドを実行しローカル環境の修正を同期します。

$ git ghost diff HEAD
$ git ghost pull yyyyyyy
$ git ghost diff HEAD
diff --git a/foo b/foo
index 7898192..6178079 100644
--- a/foo
+++ b/foo
@@ -1 +1 @@
-a
+b

ローカル環境の修正を簡単にリモート環境に同期することができました。

このようにGit Ghostはすごくシンプルなツールですが、他のツールと連携させることで最大の効果を発揮します。例えば、Kanikoを使ってDocker imageを作成する際にローカル環境の差分を含めることもできます。ローカル環境の差分を含めたDockerイメージを作り、そのイメージを使って再現性のあるジョブを動かすArgo利用例も公開しています。

アーキテクチャ

アイデアは非常にシンプルです。このツールはリモートのレポジトリーに対してローカル環境でのコミットの差分およびコミットされていない差分のパッチを別のリポジトリで管理します。そして、リモート環境でそのパッチを適用することで、ローカル環境を再現します。細かい点ですが、ローカルコミットの差分とコミットしていない差分を別々のパッチで管理することで、ローカルコミットをリモートのレポジトリーにプッシュした際にコミットしていない差分をそのまま使うことができるようになっています。

他のツールや認証情報を不要とするため、Gitレポジトリーをパッチのストレージとして使っています。

我々はこのツールをKubernetesクラスターで使っていますが、その他の環境でも同じように使えるはずです。オンプレミスのサーバーにラップトップでの変更をトラッキングしつつ送りたいという場合でも使えます。

 

是非試しに使っていただいて、GitHubにてフィードバックをよろしくお願いします!