gitコマンドがない環境でjgitの力でgitを使う方法

## モチベーション

とある環境で「sudo権限がない」とか、「`make`でコケる」とかの理由で`git`がインストールできず、
困っていて、それの一つの対処としてやってみて、うまく行ったので紹介します

（頑張ってクロスコンパイルに挑戦したけど駄目だったって人の助けになれば、嬉しいです）

## アイデア

「`git`のJavaの実装である`jgit`を使えば**JVMがある環境ならどこでも動くんじゃないか**」

## やり方

全体の流れとしては、
[eclipse/jgit](https://github.com/eclipse/jgit)を取ってきて、ビルドする感じです。`mvn`コマンドが使える環境ならビルドできると思います。
(`git`を`make`したりするよりも上手くいきやすいと思います)



```bash
# リポジトリを取ってきます
#（適当なgitのある環境でやりました）
git clone git@github.com:eclipse/jgit.git
# (またはwget https://github.com/eclipse/jgit/tree/stable-4.11 でzipをダウンロードしてもいいと思います)

# ディレクトリを移動します
cd jgit/

# 現在の最新の安定版にcheckoutします
git checkout stable-4.11

# インストールします
mvn clean install

# ビルドできたjgitを動かしてみる
./org.eclipse.jgit.pgm/target/jgit --version
```


`./org.eclipse.jgit.pgm/target/`がポータブルで、この`target`ディレクトリを`git`コマンドが欲しい環境に設置すればOKです。

**`jgit`をビルドする環境と`jgit`を設置したい環境は別でも大丈夫**だと思います（**Write once, run anywhere**というJavaのスローガンを信じて...）。

あとは、`./org.eclipse.jgit.pgm/target/jgit`に向かって`"git"`という名前で以下のコマンドでシンボリックリンクを作成します

```bash
# gitという名前でシンボリックを作成する（$PWDに作成される）
ln -s ./org.eclipse.jgit.pgm/target/jgit git
```

ここにパスを通せば、`git`コマンドのように扱えます。


## JGitって何？信頼性あるの？

**JGitはJavaで`git`の実装です。**

公式では以下のように言っているので、裏で`git`とかを叩いている感じのものではないです。
> An implementation of the Git version control system in pure Java.



主な使われ方はJava（もしくはJVM言語）から`git`の`commit`とか`checkout`とかの命令たちをプログラムから扱うことだと思います。以下がその例です。

```java
// git commitの例
Git git = new Git(db);
CommitCommand commit = git.commit();
commit.setMessage("initial commit").call();
```

```java
// git logの例
Git git = new Git(db);
Iterable<RevCommit> log = git.log().call();
```

`system()`みたいなので、`git`コマンドを叩いたりせずに操るのが主な目的だと思います。
今回のようにCLIとして使い方法も公式はドキュメント用意していて、この使い方も全然ありなはずです。

信頼性に関してですが、
Eclipseが開発しているようなので、Eclipseでも使われてでしょうし、
Scalaで書かれている[Gitbucket](https://gitbucket.github.io/)（オープンソース版のGitHubみたいな）でも使われているみたいなので、かなり信頼できると思っています。


## jgitの動作確認

（注意：以下の`git`は`jgit`へのシンボリックリンクです）

```bash
$ git --version
jgit version 5.0.0-SNAPSHOT
```

```bash
$ git
jgit --git-dir GIT_DIR --help (-h) --show-stack-trace --version command [ARG ...]

The most commonly used commands are:
 add              Add file contents to the index
 archive          Zip up files from the named tree
 branch           List, create, or delete branches
 checkout         Checkout a branch to the working tree
 clean            Remove untracked files from the working tree
 clone            Clone a repository into a new directory
 commit           Record changes to the repository
 config           Get and set repository or global options
 daemon           Export repositories over git://
 debug-lfs-store  Run LFS Store in a given directory
 describe         Show the most recent tag that is reachable from a commit
 diff             Show diffs
 fetch            Update remote refs from another repository
 gc               Cleanup unnecessary files and optimize the local repository
 init             Create an empty git repository
 log              View commit history
 ls-remote        List references in a remote repository
 ls-tree          List the contents of a tree object
 merge            Merges two development histories
 push             Update remote repository from local refs
 reflog           Manage reflog information
 repo             Parse a repo manifest file and add submodules
 reset            Reset current HEAD to the specified state
 rm               Stop tracking a file
 show             Display one commit
 status           Show the working tree status
 tag              Create a tag
 version          Display the version of jgit
```

## 参考

* [JGit/User Guide - Eclipsepedia](https://wiki.eclipse.org/JGit/User_Guide#Building_the_JGit_CLI)
* [eclipse/jgit: JGit project repository (jgit)](https://github.com/eclipse/jgit)
* [gitbucket/gitbucket: A Git platform powered by Scala with easy installation, high extensibility & GitHub API compatibility](https://github.com/gitbucket/gitbucket)
* [シンボリックリンクの作成と削除 - Qiita](https://qiita.com/colorrabbit/items/2e99304bd92201261c60)