プルリクはGitの機能じゃない　～技術を分解して理解することの大切さについて～

__「プルリクはGitの機能じゃないよ、GitHubの機能だよ」__というのはGitが僕の職場に普及し始めたときによく聞いた言葉です。

プルリクがGitの機能のうちの一つだと思ってしまっているために、「SVNからGitへ移行すればそれだけでプルリクが使えるようになって、レビューの文化が根付き、万事うまくいくらしい！」という主張をする人に対し、「いや、Git入れただけじゃプルリクできないから。GitHubなりBitbucketなり、何かGitホスティングサービスもセットで導入しないとダメだから。」という指摘です。

この手の勘違いは、ラッパーやクライアントアプリケーションが一つの要素技術とセットになって普及してしまっている（もしくはラッパーやクライアントアプリケーションの方が普及している）場合によく発生します。この記事では、そのような勘違いや理解不足について書いてみたいと思います。

# 戦犯

## IDE（統合開発環境）

まず、この手の理解不足が発生する一番の要因はIDE（統合開発環境）の存在です。

例えばAndroid Studioは、ソースコードを管理するためのVCS（Version Control System、つまりGitやSubversionなど）との連携ができたり、アプリをビルドするためのGradleの実行をメニューから行えたり、ADB（Android Debug Bridge）の操作や情報表示もウィンドウ上でできるようになっています。

この機能自体は開発の効率化のためにとてもうれしい機能です。僕も積極的に利用しています。

しかしここで問題になるのは、「AndroidアプリをビルドしたいからAndroid Studioダウンロードしなきゃ！」「コミットしたいからAndroid Studio開かなきゃ！」という思考をしてしまう開発者が出てきてしまう、ということです。

Androidアプリをビルドするだけであれば、別にAndroid Studioは不要です。適切なタスク（assembleXXXX）を指定してGradleを実行すれば良いだけです。また、ソースコードをコミットしたいのであればターミナルからでも`git`コマンドなり`svn`コマンドなりで事足ります。そのためだけにわざわざ起動に時間のかかるAndroid Studioを立ち上げる必要はないでしょう。

## クライアントアプリケーション

次に大きいのがSourceTreeやTortoiseSVNなど、各種クライアントアプリケーションの存在です。

実際はこのようなクライアントアプリケーションも中で`git`なり`svn`を実行しているだけなのに、これらのソフトがなければGitやSubversionが使えないと思ってしまうパターンです。

また、クライアントアプリケーションが前提となってしまっているため、クライアントアプリケーションの機能で実現できることしかできないと思ってしまうことも少なくありません。Gitの機能としてはあるけれど、SourceTreeにはそれを実行する機能が実装されていないだけ、という発想にたどり着けなくさせています。

# なにが問題なのか

一つ一つの要素技術をちゃんと理解していなくても、確かにその技術を使うことはできます。というか「使いやすくする」のがラッパーやクライアントアプリケーションの役割の一つですので、それを使って使えなかったらこの記事の内容以前の問題です。

しかし、分解して理解しないことは、以下のような誤解、問題を引き起こします。

## 理解不足によって発生する誤解の例

### 「今日からMacでWebアプリ開発の仕事だ。PoderosaとWinSCP入れなきゃ！」

いえ、Macには標準でTerminalというアプリケーションがついています。そこから`ssh`すればサーバーへログインできますし、ファイル転送も`scp`コマンドが使えます。
PoderosaやWinSCPしか実装してくれていないような便利機能があるのであればMac版を探したり代替手段を検討するのもアリですが、単純にサーバーへログインしたりファイル転送したいだけであれば、UNIXコマンドを実行できるTerminalさえあれば十分です。

### 「よし、これからはAndroidアプリのビルドは共通のサーバーでJenkinsでやろう。Android Studioが必要だから、Windowsサーバーが必要かなぁ。。。」

ビルドするだけならGradleとAndroid SDKさえあればAndroid Studioは不要です。CLI環境ではAndroid Studioが使えないからと言ってわざわざGUIのマシンを用意する必要はありません。

JenkinsをインストールしたマシンにLinux用のAndroid SDKをダウンロードし、`android`コマンドからプロジェクトに合わせたバージョンのSDKをダウンロードし、パスを通すなどし、Gradleを使ってビルドすればapkファイルのできあがりです。

### 「SourceTreeからpushしたらエラーメッセージが出た！エラーメッセージでググったら出てきたのは"Git"という単語ばっかりでSourceTreeについての記事じゃないなぁ。別の記事を探すか。」

Git自体が出力しているエラーで、SourceTreeはそれをそのまま画面に出しているだけなので当たり前です。SouceTreeは関係なくエラーになっている可能性が高いので、その記事を参考に、必要に応じてSourceTreeを通さず直接`git`コマンドを使うなりして解決してください。

## ちょっと違う環境になるとダメになる問題

WindowsとMac、GUIとCLI、自分のPCと他人のPC、というように、環境が変わると途端に目的の操作ができなくなってしまう問題です。今まで自分が使ってきた環境をそっくりそのまま整えないと何もできない、もしくは新しく0から調べ直さなければならないと思ってしまうために、ちょっと環境が変わるだけでとたんに生産性が落ちてしまいます。

中で何が起こっているのかを理解していれば、例えば、「なんかクライアントアプリケーション違うけど、要はGitなんだからこうすればきっとできるでしょ」というスタンスでソース管理アプリケーションに接することができれば、0からそのアプリケーションの使い方を身につけなくても、なんとなく推測であたりを付けることができます（そしてだいたいの場合、それは正しいです）

「じゃあいつも同じ環境で仕事してればいいじゃん」と思われるかもしれませんが、仕事をしていると、効率化や安全性の問題で環境自体を変える（改善する）必要に迫られることは少なくありません。そんなときにすぐに対応できるか、何がなんだか分からない状態になってしまうか、差が出るところだと思います。

## 問題の切り分けができない問題

この記事の内容に限らず、何か問題が起きた場合はどれだけ素早く問題の切り分けができるかで、その解決までの時間や精度が変わってきます。

例えばGitの実行でエラーが出ているのに、いつまでもSourceTreeを調べていたのでは根本的な対処は難しく、時間を無駄に消費する結果につながってしまいます。

SourceTreeがエラーを表示しているのであれば、SourceTreeを経由せずGitをターミナルで直接実行して結果を見てみる、TortoiseGitなど他のクライアントアプリケーションに変えてみる、等いろいろと試してみることで問題の切り分けができるのですが、「SourceTreeを使わなければPushできない」と誤解していると、そのような行動を起こすことができない、という問題が発生します。

# じゃあどうすれば良いのか

では、この問題を解消するためにはどうすれば良いのか、ということなのですが、一つ一つの要素技術について根本からもっと勉強してね、ということになってしまいます。

しかしそれでは漠然としすぎていて何のアドバイスにもならないので、ここでは「僕はこんなことしてみています」を紹介したいと思います。

## IDEを使わずにコーディングしてみる

「戦犯」で紹介したものをあえて使わずにやってみる、という方法です。原因と対策が直接結びついているので分かりやすいですね。

文章で説明するよりも実際に僕が過去にやったことを紹介するのが早そうですので、いくつか以前投稿した記事のリンクを張っておきます。

* [ゲームっぽい何かを作りながらRubyを勉強する　その１　〜ディレクトリ構成とかtest-unitとかRakeとか〜](http://qiita.com/chooyan_eng/items/c85466d0a744161a5a2e)

これはRubyプログラムを、何のフレームワークもツールも使わずVimだけで書き進めてみる、という試みです。途中で必要性が分かってきたところでRakeなどのツールを導入しています。

* [gradle initもEclipseも使わずJavaプロジェクトを作成する](http://qiita.com/chooyan_eng/items/206713bbf98d15c82c51)

Gradleの理解のため、Eclipseなどの統合開発を使わず、ターミナル上で、Gradleのリファレンスだけを見てJavaのプロジェクトを作ってみた記事です。なぜEclipseでGradleプロジェクトを作ると`src/main/java`のようなフォルダ構成になるのか、なぜGradleが実行できるのか、が良く分かりました。

* [JDKのbinフォルダに入っているツールをまとめてみた](http://qiita.com/chooyan_eng/items/d0e99ba49affce0cbb93)

Javaのプログラムをコーディングしてからデバッグする、コンパイルする、JARに固める、などの一連の作業をEclipseを使わずにやってみる、という試みです。記事の趣旨は若干違いますが、記事を書く上でそのようなことをやってみています。

他にも、この記事で頻繁に例で出しているGitについては、割と多くのエンジニアがターミナル上でコマンドで利用しているような気がしています。Qiitaの記事を見ていても`git`コマンドの使い方自体の記事がよく流れてきますので、クライアントアプリケーションなんて使わずに直接叩いた方が良いよね、という方が少なくないのだと思います。

## 公式トップページをよく読む

もう一つは、公式ページの最初の紹介文を読む、ということです。誰かがまとめた紹介記事ではありません、あくまで一次情報です。

公式ページの最初には、ほぼ必ず「その技術は何か」という説明が一言でまとまっています。Gitのクライアントアプリケーションなのか、バージョン管理システムそのものなのか、それとも統合開発環境なのか。その点がはっきりと書かれているのが公式サイトのトップです。

使い慣れたツールや技術であっても、一度ググって公式ページを最初だけでも読んでみると良いでしょう。英語だから読めない？そんなことありません、世界中で広く使われている技術ほど、英語話者以外でも読みやすいよう極力簡単な言葉で書かれています。最悪Google翻訳先生もついています。とにかく読んでみてください。きっと役に立ちますから。

# まとめ

というわけで、特に新入社員が陥りがちな誤解について、キーボードの赴くままに書いてみました。

僕も2, 3年目あたりまではこれでだいぶ苦労した記憶があります。（Linux上のJenkinsを使ったAndroidアプリのビルドの例などは、僕の実体験そのものです）

しかし、一度調べ方、勉強のしかたを覚えてしまえば、それまでとは比べ物にならない効率で一つ一つの技術の理解を進めることができるのも確かです。

無駄だと思ってもまずは騙されたと思って、VimだけでJavaのソースコードを書いてJARファイルにしてみる、というような原始的な作業をしてみると、きっと何かの役に立つときがくるはずです。

そしてそれが極まるとより低レベルな言語、つまりマシン語の理解やパソコンそのものの仕組みの理解まで行きつくのですが、そのあたりは僕もまだまだ知らない世界ですので割愛します。でもきっと知っていると何かあったときの発想が違ってくるのではないかと思っています。漠然とですが。