第1章:はじめに~Motivation~
私はこれまで、Gitの操作は大方 VSCode 上のボタンをポチポチ押して実行していました。
そのため、裏側で起きていることや、複雑なGitコマンドをどのように使用するべきかについて、体系的に学習するタイミングを逃していました。
しかし、インターンシップやチーム開発に参加する機会が増えるにあたり、さすがにGUIの操作だけでは理解が足らないと感じたため、各種コマンドを根本から身に着けたいと考えました。
そこから様々なGitの解説記事を読み漁りましたが、正直よくわかりませんでした。多くの記事は「各種コマンド」と「それの作用」が文章として羅列されているのみであり、直感的に理解ができず、自分のファイルがどのように振る舞うのかがイメージできませんでした。そこで、
「言葉でわからないのであれば、各種コマンドを図解して直感的にわかるようにしよう」
そう思い至ったことが、この記事を書いたモチベーションです。
この記事では、Gitの各種コマンドで起こる状態遷移を「丸」と「箱」と「矢印」と「付箋」のシンプルな図に落とし込み、「コマンドの正式な意味」と「図解でのリアルな動き」をセットで解説する構成にしました。
過去の自分と同じように「GUI操作から抜け出したい」「他の記事を読んでも直感的に理解ができなかった」という方々のお役に立てれば嬉しく思います。
第2章:Gitの図解のルール
具体的なコマンドの解説に入る前に、この記事で登場する図解のテンプレートについて説明します。
図にしてしまえば、Gitは以下の4つのエリアと各種コンポーネントしかありません。
Gitを構成する4つのエリア
- ワークツリー(作業ディレクトリ)
VS Code等のエディタで編集している、手元のファイル置き場。
- ステージ(インデックス)
次のコミットに含めるファイルを一時的に置いておくエリア。
- ローカルリポジトリ
自身のローカル環境に保存された、過去のコミット履歴。
- リモートリポジトリ
GitHubなどのネットワーク上にあるリポジトリ。ローカルとは、"push"や"pull"等で通信しない限り同期されることはない。
図解に登場する各種コンポーネント
- 🔵青い丸 = コミット
特定時点におけるリポジトリの履歴。一度作られたら中身が変化しない。
- 🟩緑の付箋 = ローカルブランチ
特定のコミットを指し示すポインタ。新しいコミットを作成すると、自動的に最新のコミットへ移動する。
- 🟨黄色の付箋 = リモート追跡ブランチ
直近でリモートリポジトリと通信した際の、リモート側のブランチの位置をローカルに記録しておくためのポインタ。ローカルでのコミットによって動くことはない。
- 🟥赤い矢印 = HEAD
現在作業しているローカルブランチを指し示すポインタ。
- 📄ファイル(赤と緑)
各ファイルの状態を表す。赤色のファイルはワークツリー内で変更されたが、ステージに追加されていない状態、緑色のファイルはステージに登録されコミットされる準備が完了した状態を示す。
第3章:Gitのはじめかた(init, clone)
Gitの操作を始めるにあたり、PC内にリポジトリを作り出す必要があります。
init
git init
①コマンドの意味
現在のディレクトリを、空のGitリポジトリとして新規に初期化する。
②図解中での動作
Gitのワークツリー、ステージ、ローカルリポジトリが構築される。
この時点ではまだ青い丸も緑の付箋も存在しない。
git init
[before]
(Git管理されていない、ただのフォルダ)
[after]
③主要なオプション
| オプション | 意味 | 図解中での動作 |
|---|---|---|
| -b <ブランチ名> | 最初のブランチ名を指定して初期化する | 最初の青い丸に貼るための緑の付箋の名前をあらかじめ設定しておく |
clone
git clone <URL>
①コマンドの意味
GitHubなどのリモートリポジトリを、ローカル環境に複製する。
②図解中での動作
リモートリポジトリを、そのままローカルリポジトリへコピーする。
同時に、リモートの現在地を示す黄色の付箋がセットされ、ワークツリーには最新のファイル群が展開される。
git clone https://github.com/user/repo.git
[before]
[after]
③主要なオプション
| オプション | 意味 | 図解中での動作 |
|---|---|---|
| -b <ブランチ名> | 特定のブランチを直接指定してクローンする | クローンしてきたあと、HEADをデフォルトのmainではなく、指定した緑の付箋に合わせた状態にする |
第4章:ローカルでの状態遷移(status, add, commit)
この章では、ローカル環境でファイルを編集し、コミットするまでの基本的な流れを図解します。
status
git status
①コマンドの意味
ワークツリーおよびステージの現在の状態を表示する。
②図解中での動作
図解におけるコンポーネントの移動はありません。
現在どのファイルが赤または緑のファイルとして存在しているかを確認します。
③主要なオプション
| オプション | 意味 | 図解中での動作 |
|---|---|---|
| -s | 状態を短いフォーマットで出力する | 状態確認のみのため、図解の挙動に変化なし |
add
git add <ファイル名>
①コマンドの意味
ワークツリーの変更内容をステージに追加する。
②図解中での動作
ワークツリーにある赤いファイルが、ステージへと移動され、緑のファイルへと変化します。
git add ahoge.html
[before]
[after]
③主要なオプション
| オプション | 意味 | 図解中での動作 |
|---|---|---|
| .(ドット) | カレントディレクトリ配下のすべての変更をステージに追加する | ワークツリーにあるすべての赤いファイルがステージへ移動し、緑のファイルになる |
| -p | ファイル内の変更を部分的に確認しながらステージに追加する | 図解上は通常のaddと同じだが、ファイルの一部だけを切り取って緑のファイルにするイメージ |
commit
git commit
①コマンドの意味
現在のステージの状態を、ローカルリポジトリに新しいコミットとして記録する。
②図解中での動作
ステージにあった緑のファイルがパッケージ化され、グラフに新しい青い丸が生成される。
同時にHEAD(赤い矢印)が指し示しているローカルブランチ(緑の付箋)が、生成した青い丸へと移動する。コミット後、ステージは空になる
git commit -m "upload index.html"
[before]
[after]
③主要なオプション
| オプション | 意味 | 図解中での動作 |
|---|---|---|
| -m "<メッセージ>" | エディタを起動せず、コマンドラインから直接コミットメッセージを指定する | 新しく作られる青い丸に、指定したメッセージのラベルを直接書き込む。 |
| --amend | 現在のブランチの先端のコミットを、現在のステージの内容で上書き(再作成)する | 新しい青い丸は作られません。HEADがいる現在の青い丸そのものを破棄し、中身を書き換えた別の青い丸を同じ位置に置き換えます |
第5章:ブランチの作成・移動(branch, switch)
この章ではGitにおけるブランチの作成と、そのブランチ間の移動を図解します。
branch
git branch <ブランチ名>
①コマンドの意味
ブランチの作成、一覧表示、削除を行う。
②図解中での動作
現在HEADがいる青い丸に対して、新しく指定した名前のローカルブランチ(緑の付箋)を作成する。
この時点では、HEADは元の緑の付箋にとどまったままで、移動はしない。
git branch dev
[before]
[after]
③主要なオプション
| オプション | 意味 | 図解中での動作 |
|---|---|---|
| -d | 指定したブランチを削除する | 指定した緑の付箋を、青い丸から剥がして捨てる。青い丸自体は消えない |
| -a | リモート追跡ブランチを含むすべてのブランチを表示する | 緑の付箋と、黄色の付箋をすべて一覧表示する |
switch
git switch <ブランチ名>
①コマンドの意味
作業するブランチを切り替える。
②図解中での動作
HEADが、指定した別の緑の付箋へと移動する。
git switch dev
[before]
[after]
③主要なオプション
| オプション | 意味 | 図解中での動作 |
|---|---|---|
| -c | 新しいブランチを作成し、そのブランチへ切り替える | 今いる青い丸に新しい緑の付箋を貼り、そこにHEADを移動させる |
第6章:リモートとの通信(fetch, pull, push)
この章ではローカルリポジトリとリモートリポジトリの間で履歴を同期するコマンドを図解します。
fetch
git fetch <リモート名>
①コマンドの意味
リモートリポジトリから最新の履歴をダウンロードする。
②図解中での動作
リモートにある新しい青い丸を、ローカルのグラフにダウンロードします。
それに伴い、ローカルにある黄色の付箋だけが最新の青い丸へと移動します。緑の付箋やHEAD、ワークツリーのファイルは変化しません。
git fetch origin
[before]
[after]
③主要なオプション
| オプション | 意味 | 図解中での動作 |
|---|---|---|
| --prune | リモートで既に削除されたブランチの追跡参照をローカルからも削除する | リモートリポジトリ上で消されたブランチに対応する黄色の付箋を、ローカルからも剥がして捨てる |
pull
git pull <リモート名> <ブランチ名>
①コマンドの意味
リモートリポジトリから最新の履歴を取得し、現在のローカルブランチに統合する。
②図解中での動作
内部的にはfetchを行った後、自分の緑の付箋に統合(merge)する2段階の動作を行います。
まず黄色の付箋が最新の青い丸へ移動し、その後、自分がいる緑の付箋とHEADが、黄色の付箋に移動します。ワークツリーのファイルも最新の状態に書き換わります。
git pull origin main
[before]
[after]
③主要なオプション
| オプション | 意味 | 図解中での動作 |
|---|---|---|
| --rebase | 取得した履歴をマージではなく、リベースで統合する | 黄色の付箋を取得した後、自分が進めていた青い丸を一旦切り離し、黄色の付箋の先に繋ぎ直す |
push
git push <リモート名> <ブランチ名>
①コマンドの意味
ローカルリポジトリの変更をリモートリポジトリにアップロードし、更新する。
②図解中での動作
自分が作成した新しい青い丸を、リモートリポジトリへ送信します。
リモートが更新されると、ローカルにある黄色の付箋が、緑の付箋に移動します。
git push origin main
[before]
[after]
③主要なオプション
| オプション | 意味 | 図解中での動作 |
|---|---|---|
| -f | リモートリポジトリの履歴を強制的にローカルの履歴で上書きする | リモート側の青い丸を強制的にローカルと同じ形に変更する |
第7章:ブランチの合流と再構築(merge, rebase)
この章では、枝分かれして進んだブランチを、1つに統合するためのコマンドを図解します。
merge
git merge <ブランチ名>
①コマンドの意味
指定したブランチの変更履歴を、現在チェックアウトしているブランチに統合する。
②図解中での動作
枝分かれした2つの青い丸を統合し、親を2つ持つ新しい特殊な青い丸(マージコミット)を生成します。
現在HEADがいる緑の付箋が、その新しくできた合流地点の青い丸へと移動します。
git merge dev
[before]
[after]
③主要なオプション
| オプション | 意味 | 図解中での動作 |
|---|---|---|
| --no-ff | Fast-forwardマージが可能な場合でも、必ずマージコミットを作成する | 単純に緑の付箋が前にスライドできる状況でも、親を2つ持つ新しい青い丸を作る |
| --abort | コンフリクトが発生したマージ処理を中断し、マージ前の状態に戻す | 生成途中だった新しい青い丸を破棄し、ワークツリーもマージを実行する前の状態に復元する |
rebase
git rebase <ブランチ名>
①コマンドの意味
現在のブランチのコミット群を、指定した別のブランチの先端に付け替えて履歴を再構築する。
②図解中での動作
現在自分がいるブランチの青い丸を根元から切り離し、対象となる別のブランチの先端に新しく作り直した青い丸として繋ぎ直す。
'merge'のように合流用の新しい丸は作られず、一直線の綺麗なグラフになる。
git rebase main
[before]
[after]
③主要なオプション
| オプション | 意味 | 図解中での動作 |
|---|---|---|
| -i | リベースするコミットの履歴を対話的に編集する | 切り離した青い丸を繋ぎ直す前に、2つの青い丸を1つに合体させたり、メッセージのラベルを書き換えたりする |
| --abort | コンフリクト等で停止したリベース処理を中断し、元の状態に戻す | 新しく作りかけていた青い丸を破棄し、緑の付箋とHEADをリベース実行前の元の青い丸の位置へと戻す |
第8章:復旧と退避(reset, stash)
この章では、間違えてコミットした場合などのイレギュラーな事態に対応するためのコマンドを図解します。
reset
git reset <コミット>
①コマンドの意味
現在のブランチの先端を指定したコミットに移動させ、オプションに応じてステージとワークツリーの状態を書き換える。
②図解中での動作
現在HEADがいる緑の付箋を、過去の青い丸へと戻す。
この時、指定するオプションによって、ワークツリーとステージにあるファイルがそのまま残るか、破棄されるかが変わる。
git reset --hard HEAD^
[before]
[after]
③主要なオプション
| オプション | 意味 | 図解中での動作 |
|---|---|---|
| --soft | ブランチのポインタのみを移動し、ステージとワークツリーはそのまま保持する | 緑の付箋とHEADだけが過去の青い丸へ戻る。ファイルは一切触られないため、「コミットだけを取り消して、すぐに再コミットできる状態」になる |
| --mixed | ブランチのポインタを移動し、ステージをリセットするが、ワークツリーは保持する | 緑の付箋とHEADが戻る。さらに、ステージにあったファイルが、ワークツリーへ戻される(addとcommitを取り消した状態) |
| --hard | ブランチのポインタを移動し、ステージもワークツリーも指定したコミットの状態に上書きする | 緑の付箋とHEADが戻り、追跡されている未コミットのファイルがすべて消滅する。過去の青い丸と全く同じ状態にリセットされる |
stash
git stash
①コマンドの意味
ワークツリーとインデックスの未コミットの変更を一時的に退避し、作業ディレクトリをクリーンな状態に戻す。
②図解中での動作
グラフとは全く別の場所に、一時保存用のスタックが現れます。
ワークツリーとステージにあるファイルがすべてその引き出しの中に収納され、中身が空になります。これで、安全に別のブランチへ switch できるようになります。
git stash
[before]
[after]
③主要なサブコマンド
| サブコマンド | 意味 | 図解中での動作 |
|---|---|---|
| pop | 退避した作業を復元し、stashのリストからその記録を削除する | 引き出しの中からファイルを元の箱(ワークツリー)へ取り出し、引き出しの記録を捨てる |
| apply | 退避した作業を復元するが、stashのリストには記録を残したままにする | 引き出しの中からファイルを元の箱へコピーして戻すが、引き出しの中身はそのまま残しておく |
| list | 現在stashに退避されている作業の一覧を表示する | 引き出しの中に何が入っているか、リストを確認する |
第9章:おわりに
ここまで読んでいただき、ありがとうございました!
今後、この記事もアップデートしていき、より直感的にコマンドを理解する助けになれればと思っています。
もしこの記事が少しでも役に立った、分かりやすかったと思っていただけたら、LGTMやストックをしていただけると嬉しいです!