第二章 - 率先躬行のサインポスト

Gitとは何かということやGitを使う理由について説明してきました。 ここからGitの操作方法をコマンドラインインタフェース (CLI) のコマンドとForkというソフトウェアを使用して説明します。 なおCLIを使った説明は「Git初心者への道 - お仕事で困らないレベルまでググっとします。1」や「今日からはじめるGitHub 〜 初心者がGitをインストールして、プルリクできるようになるまでを解説2」といったページを見て、なんとなくの雰囲気を掴むのが良いでしょう。

Forkは以下のURLからダウンロードできます。ForkはWindowsとmacOSに対応しています。 https://git-fork.com/

Gitによるバージョン管理を始める git init

git initgit clone は任意のディレクトリでGitによるバージョン管理を始めるためのコマンドです。 いわば未来ガジェット研究所でタイムリープマシンが作られた状態にするものです。

Forkを起動した後、メニューのFileからInit New Repositoryを選びます。

メニューのFileからInit New Repositoryを選択している図

Init New Repositoryを選ぶと、ディレクトリを選択する画面になるのですでにあるディレクトリもしくは新たにディレクトリを作って、そのディレクトリを選びます。 その状態で「フォルダーを選択」を押すと、選択したディレクトリ(フォルダ)がGitのリポジトリとして使えるようになります。

リポジトリが作られた状態

すでにあるリモートリポジトリを使ってバージョン管理を始める git clone

すでにあるリモートリポジトリを自分のPC上へコピーしGitによるバージョン管理を始められるようにします。 その前に、リモートリポジトリについて少し説明をします。リモートリポジトリとは、自分のPC以外にあるリポジトリのことを指します。 「自分のPC以外にあるリポジトリ」ですが「インターネット上や誰かのPC上にあるリポジトリ」を指します。 他の章で「ネットワーク上のリポジトリ」という言葉がありましたが、これは「リモートリポジトリ」と同じ意味です。

このリモートリポジトリを自分のPC上にコピーするのがこれから説明する手順です。 これでたとえばラボメンなど、他の人と共同でタイムリープマシンを使って作業できる体制が整います。

Forkを起動した後、メニューのFileからCloneを選ぶと次の画面になります。

Forkでクローンするときの画面

ここでリポジトリのURLとクローン先のディレクトリを選択しCloneを押すと選択したディレクトリにリポジトリが置かれます。

作業内容を記録する git commit

作業した内容をリポジトリに記録します。たとえるならば、Steins;Gateでストーリーを進めた後、セーブをするようなものです。

リポジトリ内にファイルを新しく作成した場合Fork上ではUnstaged Changesという欄に表示されます。 ファイルがまだバージョン管理されてないことを示しています。

ファイルがUnstaged Changesにある状態

この状態で「Stage」ボタンを押すとStaged Changesという欄へファイルが移動します。 これでコミットするための準備が整うことになります。

ファイルがStaged Changesへ移動した状態

ファイルを移動した状態で、画面の右下部にある「Enter commit subject」と書かれている場所に任意のメッセージを入力します。

コミットメッセージを入力しているところ

入力した後「Commit File」ボタンを押すと作業した内容がリポジトリに記録されます。

コミットした後

なお右上のコミット一覧が表示されている場所に「master」という表記がありますが、これは「現時点でどのブランチにいるかを判別する情報」です。 つまり世界線の観測ができているということです。たとえるならばダイバージェンスメーターです。

作業内容を無かったことにする git checkout -- <ファイル名>

岡部は、ダルにメールを送信した後、秋葉原UPXでタイムマシン理論についての講義を受けましたが、ディスカッションで紅莉栖に完全に論破されてしまいました。 岡部にとって、論破されたということは無くしたい事象ですがGitであればそれができます。

方法としては、作業内容を無かったことにするファイルを右クリックで選択し「Discard changes」を選択します。

作業内容を無かったことにする

変更を本当に破棄していいか確認画面が表示されるので「Discard」を押します。 これで紅莉栖に論破されたという事実は無くなりました。

作業内容の差分を見る git diff

作業内容の差分を見ます。まゆりが死んだ理由を前回死んだ理由と比較し、そこから試行錯誤するようなものです。

Forkでは特定の作業内容を選択した上で、右下のウィンドウのタブの中から「Changes」を選択すると、その作業内容の一つ前の作業内容と比べてどのような変更をしたのか見られます。

Fork で作業内容の差分を見ている例

ブランチの一覧を見たり、新たにブランチを作ったりする git branch

ブランチの一覧を見たり、新たにブランチを作ったりします。 「ブランチ」はたとえるならば「世界線」となり、ブランチを作るということは「世界線の観測」になります。

ではさっそくブランチを作る方法を説明していきます。 現在のブランチは「秋葉原が電気街となり、フェイリスのお父さんが生きている世界線」だとします。 「秋葉原が電気街となり、フェイリスのお父さんが生きている世界線」で鈴羽を引き止めるために岡部がDメールを送信しました。

ここまでの作業内容は次のようになります。

新たなブランチを作る前

ここから「鈴羽を引き止めるためにDメールを送信した後の世界線」というブランチを作ります。 特定のコミットを選択した上で右クリックすると「Create New Branch」というメニューがあるのでこれをクリックします。 するとブランチ名を入力する画面が表示されるので「Branch name」のところに任意の名前を入力します。

ブランチ名を決めているところ]

するとブランチができた状態になります。左メニューから作ったブランチを選択してクリックするとブランチを移動した状態になります。 世界線変動を起こしました。

ブランチを作った後

作業内容を戻す git revert

作業内容を無かったことにします。ただしその無かったことにしたことはログに残ります。 「作業内容を無かったことにする」と似ていますが、違いとしては「すでにリポジトリに追加した作業内容も無かったことにできる」と「作業内容をリセットしたということが履歴に残る」があります。

これをたとえるならば、タイムリープのようなものです。

前に書いた「作業内容を無かったことにする」はリーディング・シュタイナーが働かないので記憶から無くなってしまいます。 しかしこの「作業内容を戻す」はリーディング・シュタイナーが働くため記憶に残ります。このようにたとえれば分かりやすいと思います。 話を戻しますが「鈴羽を引き止めた世界線」でいくつか作業をした結果、履歴が以下のようになりました。 最新の作業内容は「萌郁やラウンダー達の手によりまゆりが死んでしまった」となっています。

鈴羽を引き止めた世界線でいくつか作業した後の状態

ここで最新の作業内容である「萌郁やラウンダー達の手によりまゆりが死んでしまった」という作業を無かったことにして、紅莉栖がタイムリープマシンを完成させたところにタイムリープします。 タイムリープするためには、戻したい作業内容を右クリックで選択し「Revert Commit」を選択した後にでてくる確認画面で「Revert」を押します。 これで履歴から「萌郁やラウンダー達の手によりまゆりが死んでしまった」というのが消えます。

git revertをした後の状態

作業内容を改変する git rebase

作業内容を改変します。

まゆりが死んだと書かれた複数の履歴を1つにまとめてみましょう。 まとめる対象のコミットの1つ前を右クリックで選択し「Interactive Rebase」から「Rebase '<ブランチ名>' to Here Interactively」を選びます。

git rebase squash するべく親となるコミットを選択している状態

今回は4つの作業内容を対象としました。 ここから作業内容をまとめるには「Interactive Rebase」の画面で一番下のコミットを除い他コミットをfixupのモードにする必要があります。 初期状態だと全てのコミットが「Pick」になっていますが、「Pick」と書いている部分をクリックして「Fixup」にする必要があります。

コミットの扱いをどうするかの一覧

一番下のコミットはコミットメッセージを編集するために「Reword」とします。

一番下のコミットをRewordにした状態

編集後に次のような上のコミット3つは「Fixup」が選択されて、一番下のコミットは「Reword」になっていれば問題ないです。 これで右下の「Rebase」を押します。

全ての作業が終わった状態

これで、まゆりが死んだと書かれた複数の履歴がまとめられました。

git rebaseが完了した状態

ブランチを移動する git checkout <ブランチ名>

現在のブランチから別のブランチへ移動します。 あらためてですが、Gitのブランチは「世界線」です。 Dメールによる世界線変動は世界の状況に影響を及ぼしてましたが、Gitではそういった副作用が無く世界線の移動ができます。

ブランチ移動の方法は簡単です。 画面左端に表示されているブランチ一覧から、移動したいブランチの名前をクリックすることでブランチを移動できます。 以下の図では「鈴羽を引き止めた世界線」から「萌郁がIBN 5100を手に入れた世界線」へ移動しています。

ブランチを移動した後

リモートリポジトリに作業内容を送る git push

自分がした作業内容をリモートリポジトリに送ります。

岡部が紅莉栖にまゆりを助けるべくあれこれしてきたことを共有する感じです。 今まで、岡部はまゆりを助けるために何度もタイムリープをおこなって奮闘してきましたが、そのことを他のラボメンは知りません。 奮闘していることを知られないままタイムリープマシンを壊そうとしても、紅莉栖に止められるのはしかたないです。

なので、他のラボメン(今回の場合だと紅莉栖)に今まで岡部がしてきた作業内容を伝える必要があります。 左サイドバーの「Branches」からプッシュしたいブランチ名の上で右クリックをすると「Push '<ブランチ名>' to 'origin'」というメニューが出てくるのでそれを押します。 そうするとプッシュ時の確認画面が次のように表示されます。

git push 前

プッシュが終わり、作業内容の一覧に「origin/ブランチ名」という文字が表示されるようになりました。 なお「origin」というのは、リモートリポジトリを指しています。 これで作業内容をリモートリポジトリに送り、紅莉栖に今までの作業内容が伝わりました。

git push 後

リモートリポジトリの変更内容を自分のPC上のリポジトリに取り込む git pull

他人がした変更をリモートリポジトリから取得し、自分のPC上のリポジトリに取り込みます。

リモートリポジトリでは岡部以外にもラボメンが作業しています。 たとえば紅莉栖を見てみると、岡部の様子がおかしいのでタイムリープしてきたのか聞いていたり、マイフォークが欲しいと言ったことを記録していたりします。

紅莉栖が作業している

これらの記録を手元に持ってきて作業ログを同期する必要があります。 では同期してみましょう。画面上部の「Pull」を押します。確認画面が表示されるので「Pull」を押します。

pull してくるブランチを選んでいる状態

これで自分のPC上とリモートのリポジトリの作業内容が同期します。

自分の PC 上のリポジトリとリモートリポジトリの同期をとった

別のブランチでの作業内容を取り込む git merge

別ブランチの作業内容を現在のブランチに取り込みます。

「鈴羽を引き止めた世界線」というブランチで作業をした結果、鈴羽がタイムトラベルを失敗して「失敗した失敗した失敗した失敗した失敗した」と何度も書いた手紙を書き残して自殺してしまいました。 その結果、岡部は天王寺裕吾から鈴羽が書いた手紙を受け取ることになります。

鈴羽を引き止めた世界線でいくつか作業をした例

それを無かったことにするためDメールを送って世界線を変動させ、鈴羽を引き止めないようにします。 その為には「秋葉原から萌えが消えた世界線」のブランチへ移動します。

秋葉原から萌えが消えた世界線に移動した

移動した後は鈴羽を引き止めるためにDメールを送った状態が最新の状態となっています。 この状態から「鈴羽を引き止めた世界線」でしてきた作業を「秋葉原から萌えが消えた世界線」へ統合します。 方法としては、統合したいブランチの名前を右クリックして「Merge int '<統合したいブランチ名>'」を選択します。

マージ対象のブランチを選択している状態

選択すると、確認ウィンドウが表示されるので「Merge」を押します。

マージする際の確認メッセージ

すると「秋葉原から萌えが消えた世界線」に「鈴羽を引き止めた世界線」でしてきた作業内容が統合された状態になります。 これで世界が収束しブランチ同士を統合できました。

マージが完了した状態

1. https://gist.github.com/yatemmma/6486028
2. https://eh-career.com/engineerhub/entry/2017/01/31/110000