10年前のGitはどんな感じだったか？

# Git界の #10YearChallenge

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35712/a2fc35a8-01b7-b4f2-e19c-657dccd66337.png)
photo by [Chad Horwedel](https://www.flickr.com/photos/chorwedel/)

少し前にSNSで話題になっていた`#10YearChallenge`。この言葉を見て思った。…ちょっと、プログラミング界隈のタイムマシンことGitの存在を忘れてもらっちゃ困りますぜ！と。というわけで、`#10YearChallenge`にGitも挑戦。10年前のGitがどんな様子だったか見に行ってみよう！

## どうやって10年前に戻るの？

え、どうやって10年前に戻るのかって？Gitがどんなだったか知りたければ、もちろんまずはGitのソースコードをcloneすることから始めよう：

    $ git clone git@github.com:git/git.git

見ておわかりのように、Git自体もGitによってバージョン管理されている！さて、次にこのソースコードの中から10年前のコミットのSHA1ハッシュ値を探し出してこなければ。というわけで、今しがたcloneしてきたプロジェクトを開いて次のコマンドを実行：

    $ cd git
    $ git rev-list master -n 1 --before="2009-01-18"

このコマンドの`-n 1`というのは、結果を一つだけ表示するように指定している。`--before`の部分で時間を指定。今回は、10年前の今日以前の日付になされたコミットの中から（※訳者注：この日付は原文の中国語版の記事が書かれた日付に基づいています）、しかも一つだけ探しだしてくればいいわけだ。コマンド実行後に得られたSHA1ハッシュ値は`a83c88525ed6d8d940f8cf7f21e92b189f7844e3`だった。もし`--before`に続く時間を変えると得られるSHA1ハッシュ値も違ってくるので注意が必要だ。

さて、SHA1ハッシュ値が見つかったので続いてはルーラを…じゃない、じゃない。`git checkout`コマンドで過去へ遡ってみることにしよう：

    $ git checkout a83c88525ed6d8d940f8cf7f21e92b189f7844e3

ちなみに、もし2行かくのが面倒くさければ、このように1行に短縮することも出来る：

    $ git checkout `git rev-list master -n 1 --before="2009-01-18"`

## 10年前のGitはどんな感じだった？

Gitのソースコードが取得出来たのであれば、buildしてみよう！（インストールは必要なし、ソースコードのディレクトリからbuildすればOKだ）：

    $ make configure
    $ ./configure
    $ make

makeが成功していれば、当該ディレクトリには沢山の`git-`から始まる実行ファイルが作り出されているはずだ。（もしmakeが失敗した場合はエラーメッセージをStackoverflowに投げて解決方法を探してみよう）

### バージョン

2009 年：

    $ git --version
    git version 1.6.1.203.ga83c8

2019 年：

    $ git --version
    git version 2.19.1

バージョン番号のメジャーバージョンが1から2になっている、とは言っても10年も経っているのでメジャーが1から2になっていても何ら不思議なことはないのだけれど。

### ソースコード行数

2009 年：

```
$ cloc *

github.com/AlDanial/cloc v 1.80  T=1.12 s (785.9 files/s, 272731.4 lines/s)
--------------------------------------------------------------------------------
Language                      files          blank        comment           code
--------------------------------------------------------------------------------
C                               241          12701          11220          82408
Bourne Shell                    416          12474           5956          73787
Perl                             39           5598           4755          35831
PO File                          17           5420           5772          15236
Tcl/Tk                           38           1422            322           9433
Gencat NLS                       13              0              0           5178
C/C++ Header                     82            990           1206           3814
Python                            5            670            272           2939
make                              9            293            263           1881
Lisp                              3            241            206           1808
Bourne Again Shell                1            105             65           1626
ASP.NET                           8            114              0            799
CSS                               2            142             15            655
m4                                1             30              7            574
Assembly                          2             51            158            198
XSLT                              3              5              4             47
JSON                              1              0              0             39
JavaScript                        1              2              2             30
YAML                              1              0              0             21
DOS Batch                         1              0              0              1
--------------------------------------------------------------------------------
SUM:                            884          40258          30223         236305
--------------------------------------------------------------------------------
```

プロジェクト全体のコード行数は23万行、大部分はC、Shell ScriptそれにPerlで、全体の8割を占めている。

2019 年：

```
$ cloc *

github.com/AlDanial/cloc v 1.80  T=2.91 s (667.0 files/s, 303302.0 lines/s)
-----------------------------------------------------------------------------------
Language                         files          blank        comment           code
-----------------------------------------------------------------------------------
C                                  443          31960          27293         193716
Bourne Shell                      1030          31560          12338         190348
PO File                             48          58088          63656         166792
Perl                                80           5251           4956          29710
C/C++ Header                       209           4239          10230          16966
Tcl/Tk                              40           1537            409          10444
Python                               7           1603           1581           5985
make                                24            715            782           3565
Bourne Again Shell                   1            241            332           2489
m4                                   2            123             14           1161
ASP.NET                              9            141              0            942
CSS                                  2            169             30            783
JavaScript                           7            203            649            761
Go                                   4             53             84            421
sed                                  1             22            158            189
zsh                                  1             37             17            189
PHP                                  2             44             82            123
XSLT                                 8             19             33             98
Assembly                             1             26            115             83
Markdown                             2             14              0             64
diff                                18              0             36             64
C Shell                              1             18             63             45
Ruby                                 1              4              0             24
Windows Resource File                1              1              0             21
Lisp                                 2              0              0             12
-----------------------------------------------------------------------------------
SUM:                              1944         136068         122858         624995
-----------------------------------------------------------------------------------

```

目につくのはプロジェクト全体をやはりC言語とShell Scriptが占めていてコード行数が約2倍に膨れ上がっていること、それに対してPerlのコード行数は少なくなっていることだろうか。これがPerlは書きにくかったせいなのかはわからないのだが…。

付け加えておくとGitバージョン１は全てC言語で書かれていて、しかもたったの848行のソースコードだけだった：

```
$ cloc *

github.com/AlDanial/cloc v 1.80  T=0.02 s (625.0 files/s, 67245.9 lines/s)
-------------------------------------------------------------------------------
Language                     files          blank        comment           code
-------------------------------------------------------------------------------
C                                8            115             59            769
C/C++ Header                     1             17             23             53
make                             1             14              0             26
-------------------------------------------------------------------------------
SUM:                            10            146             82            848
-------------------------------------------------------------------------------
```

### Git コマンド数

Gitにどんなコマンドがあるのか知りたければ、`git help –a`を使って調べることが出来る：

2009 年

```
add                    fast-import            merge-resolve          rev-parse
add--interactive       fetch                  merge-resolve.sh       revert
add--interactive.perl  fetch--tool            merge-subtree          rm
am                     fetch-pack             merge-tree             send-email
am.sh                  filter-branch          mergetool              send-email.perl
annotate               filter-branch.sh       mergetool.sh           send-pack
apply                  fmt-merge-msg          mktag                  sh-setup
archimport             for-each-ref           mktree                 sh-setup.sh
archimport.perl        format-patch           mv                     shell
archive                fsck                   name-rev               shortlog
bisect                 fsck-objects           pack-objects           show
bisect.sh              gc                     pack-redundant         show-branch
blame                  get-tar-commit-id      pack-refs              show-index
branch                 grep                   parse-remote           show-ref
bundle                 hash-object            parse-remote.sh        stage
cat-file               help                   patch-id               stash
check-attr             http-fetch             peek-remote            stash.sh
check-ref-format       http-push              prune                  status
checkout               imap-send              prune-packed           stripspace
checkout-index         index-pack             pull                   submodule
cherry                 init                   pull.sh                submodule.sh
cherry-pick            init-db                push                   svn
clean                  instaweb               quiltimport            svn.perl
clone                  instaweb.sh            quiltimport.sh         symbolic-ref
commit                 log                    read-tree              tag
commit-tree            lost-found             rebase                 tar-tree
config                 lost-found.sh          rebase--interactive    unpack-file
count-objects          ls-files               rebase--interactive.sh unpack-objects
cvsexportcommit        ls-remote              rebase.sh              update-index
cvsexportcommit.perl   ls-tree                receive-pack           update-ref
cvsimport              mailinfo               reflog                 update-server-info
cvsimport.perl         mailsplit              relink                 upload-archive
cvsserver              merge                  relink.perl            upload-pack
cvsserver.perl         merge-base             remote                 var
daemon                 merge-file             repack                 verify-pack
describe               merge-index            repack.sh              verify-tag
diff                   merge-octopus          repo-config            web--browse
diff-files             merge-octopus.sh       request-pull           web--browse.sh
diff-index             merge-one-file         request-pull.sh        whatchanged
diff-tree              merge-one-file.sh      rerere                 write-tree
export                 merge-ours             reset
fast-export            merge-recursive        rev-list
```

表示上は166個あるように見えるのだが、実際のところは140個前後だ。

2019 年：

```
add                       diff                      merge-octopus             reset
add--interactive          diff-files                merge-one-file            rev-list
am                        diff-index                merge-ours                rev-parse
annotate                  diff-tree                 merge-recursive           revert
apply                     difftool                  merge-resolve             rm
archimport                difftool--helper          merge-subtree             send-email
archive                   fast-export               merge-tree                send-pack
bisect                    fast-import               mergetool                 serve
bisect--helper            fetch                     mktag                     sh-i18n--envsubst
blame                     fetch-pack                mktree                    shell
branch                    filter-branch             mv                        shortlog
bundle                    fmt-merge-msg             name-rev                  show
cat-file                  for-each-ref              notes                     show-branch
check-attr                format-patch              p4                        show-index
check-ignore              fsck                      pack-objects              show-ref
check-mailmap             fsck-objects              pack-redundant            stage
check-ref-format          gc                        pack-refs                 stash
checkout                  get-tar-commit-id         patch-id                  status
checkout-index            grep                      prune                     stripspace
cherry                    gui                       prune-packed              submodule
cherry-pick               gui--askpass              pull                      submodule--helper
citool                    hash-object               push                      subtree
clean                     help                      quiltimport               svn
clone                     http-backend              range-diff                symbolic-ref
column                    http-fetch                read-tree                 tag
commit                    http-push                 rebase                    unpack-file
commit-graph              index-pack                rebase--helper            unpack-objects
commit-tree               init                      receive-pack              update-index
config                    init-db                   reflog                    update-ref
count-objects             instaweb                  remote                    update-server-info
credential                interpret-trailers        remote-ext                upload-archive
credential-cache          log                       remote-fd                 upload-pack
credential-cache--daemon  ls-files                  remote-ftp                var
credential-netrc          ls-remote                 remote-ftps               verify-commit
credential-osxkeychain    ls-tree                   remote-http               verify-pack
credential-store          mailinfo                  remote-https              verify-tag
cvsexportcommit           mailsplit                 remote-testsvn            web--browse
cvsimport                 merge                     repack                    whatchanged
cvsserver                 merge-base                replace                   worktree
daemon                    merge-file                request-pull              write-tree
describe                  merge-index               rerere
```

コマンド数は163個に増えた。

2019年と2009年を付け合わせて新しく増えたものだけ抽出してみよう：

```
bisect--helper           check-ignore               check-mailmap             citool
column                   commit-graph               credential                credential-cache
credential-cache--daemon credential-netrc           credential-osxkeychain    credential-store
difftool                 difftool--helper           gui                       gui--askpass
http-backend             interpret-trailers         notes                     p4
range-diff               rebase--helper             remote-ext                remote-fd
remote-ftp               remote-ftps                remote-http               remote-https
remote-testsvn           replace                    serve                     sh-i18n--envsubst
submodule--helper        subtree                    verify-commit             worktree
```

これらが新しく追加されたコマンド。まあ、ぶっちゃけてしまえばこの中で比較的よく使うのは`worktree`くらいのものなのだけれど。

## ルーラについて

ドラクエのルーラは中学生の時に（つまり中二病を患っていたあの時期に）最も習得したい呪文だった。ドラえもんの“どこでもドア”と孫悟空の“瞬間移動”以外で一番便利なのはルーラだと思っていたからだ。

[![IMAGE ALT TEXT HERE](http://img.youtube.com/vi/1ZYKQRb4Pvs/0.jpg)](http://www.youtube.com/watch?v=1ZYKQRb4Pvs)

Gitの世界では、時間をかけてその仕組みを理解しさえすれば、コミットというのはセーブポイントと同じようなもので、ルーラのように行きたい場所に行けるようになり、道に迷うこともなくなる。ただし、基本的なスキルをきちんと身につけていないと、いくらセーブポイントがどこか分かっていても、いくらどうやって呪文を使えばいいかわかっていたとしても、天井に頭をぶつけて頭をこぶだらけにしてしまうだけなので、是非しっかりと基本を身につけておこう！

（オタクなのでオタクっぽい例えしか出てこなくて、すみません orz）