Git入門 - 3

## 1. はじめに

当記事は全5回（+α）からなる **Git入門シリーズ** の第3回です。

今回は **Gitにデータを保存する操作** について説明します。

- [1回: 概要](https://qiita.com/AGadget/items/a5f3addbe334db97d990)
- [2回: 導入手順とGitコマンド](https://qiita.com/AGadget/items/24c655fcbf9fc58625f0)
- **3回: データの保存**
- [4回: データの活用と便利な操作](https://qiita.com/AGadget/items/fbc2f67e8d6e3143d620)
- [5回: ブランチ](https://qiita.com/AGadget/items/b48983b7da16099eeba0)
- [番外編: GitHub](https://qiita.com/AGadget/items/1edc9f1f5da1dafe8325)





## 2. バージョン情報保持構造

Gitではバージョン情報を保持するのに **リポジトリ** ・ **インデックス** ・ **ワークツリー** の3つのエリアを利用します。具体的な操作方法を知る前に、まずは、この3つの用語について、しっかりと理解してください。





### 2-1. リポジトリ

**リポジトリ** はバージョン情報を保存する場所のことです。「バージョンデータベース」とか「データディレクトリ」といった分かりやすい名前だったらよかったのですが、何故かGitを始めとする多くのVCSではリポジトリと呼びます。

リポジトリの正体は **.git** という名前の隠し属性付きディレクトリです。詳しくは後述しますが、以下のようなコマンドを実行することで、カレントディレクトリにリポジトリが作成されます。

```
PS C:\Users\AGadget> git init
```





### 2-2. インデックス

**インデックス（ステージングエリアとも）** はリポジトリに保存したいファイルを一旦配置しておく場所のことです。言い換えるならば **仮登録エリア** あるいは **仮保存エリア** といった感じでしょうか。

リポジトリに保存する前に、ここに保存したいファイルをまとめておくことで「保存するファイルに漏れがないか」「保存予定にないファイルまで保存しようとしていないか」といった最終確認を行うのに使います。

インデックスの存在を初めて知った人は「インデックスって要る？」「正直無くてもいいんじゃ？」と思われるでしょう。正直、私も必須の機能ではないと考えています。インデックスがあるためにGitの敷居が上がっているのは間違いありません。ただ、操作に慣れてくると色々と便利な側面が見えてくるので頑張って付き合っていきましょう。

ちなみに、このインデックスの実態も、先ほど紹介した「.git」というディレクトリのなかにあります。





### 2-3. ワークツリー

**ワークツリー（ワーキングツリー、作業ディレクトリとも）** はリポジトリに保存したいファイルを配置する場所のことです。難しく考える必要はありません。単に、ソースファイル等を置いておく場所に、ワークツリーというお洒落な名前を付けただけのことです。

ワークツリーがどこを指すかはリポジトリが配置されたパスに応じて変化します。ワークツリーは **リポジトリが配置されたディレクトリのなか** かつ **リポジトリ以外の場所** を指します。

以下例をご覧ください。以下例には「file-1.ps1」から「file-7.ps1」までの7つのファイルと、リポジトリが1つだけあります。このうち、ワークツリーに配置されているファイルはどれでしょうか。正解は「file-3.ps1」「file-5.ps1」「file-6.ps1」の3つです。

```
■ .\
├ file-1.ps1
│
├■ app
│├ file-2.ps1
││
│└ ■ src
│  ├ file-3.ps1
│  │
│  ├■ .git
│  │└ file-4.ps1
│  │
│  └■ lib
│   ├ file-5.ps1
│   │
│   └■ lib-main
│    └ file-6.ps1
│
└■ test
 └ file-7.ps1
```





## 3. データ保存の流れ

リポジトリにファイルを保存するまでは、ざっくりと以下のような流れになります。

1. リポジトリを新規作成
2. 保存処理に先んじて、Gitの設定が正しいかチェック
3. 保存したいファイルをワークツリーに配置
4. ワークツリーにあるファイルをインデックスに保存
5. インデックスに保存されたファイルに誤りがないか確認
6. リポジトリに保存

あくまでも、ざっくりとした目安ですので、この通りに行う必要はありません。





## 4. リポジトリを新規作成

最初に行うのはリポジトリを新規作成することです。

「データを保存する場所を自分で作成する」ということに違和感を覚える人は少なくないと思います。多くのアプリ・システムではデータを保存する場所は予め用意されており、そこにデータを保存するのが一般的だからです。とはいえ、結局のところは予め用意されているか、自分で作るかだけの違いなので慣れていきましょう。

リポジトリを配置したいディレクトリに移動して **initコマンド** を実行してください。カレントディレクトリにリポジトリ、つまり「.git」というディレクトリが配置されます。

例として、デスクトップ上にリポジトリを作ってみます。

```
PS C:\Users\AGadget> Set-Location ".\Desktop"
PS C:\Users\AGadget\Desktop> git init
Initialized empty Git repository in C:/Users/AGadget/Desktop/.git/
```

ちなみに、既にリポジトリが存在する場所でinitコマンドを実行しても何も起こりません。表示されるメッセージが多少変わるくらいです。

```:リポジトリが存在しない場合
PS C:\Users\AGadget\Desktop> git init
Initialized empty Git repository in C:/Users/AGadget/Desktop/.git/
```

```:リポジトリが存在する場合
PS C:\Users\AGadget\Desktop> git init
Reinitialized existing Git repository in C:/Users/AGadget/Desktop/.git/
```





### 4-1. リポジトリ作成の目安

リポジトリは自分で作ることができますし、好きな数だけ作ることができます。では、どのように、どれくらい作るべきなのでしょうか。
　
これは私個人の考えになりますが、基本的に **1つのアプリ・システムにつき、リポジトリは1つ** というのが基本になるかと思います。そのため、例えば、電卓アプリと家計簿アプリを作るとしたら、それぞれに1つずつリポジトリを用意するべきと考えます。





## 5. Gitの設定

これからの操作のために、事前に、いくつかの設定を済ませておくとよいでしょう。

Gitでは設定情報を3箇所で管理しています。システム全体で有効となる **system** 、ユーザーごとに有効となる **global** 、そしてリポジトリごとの固有設定となる **local** です。

同じ設定項目でも3箇所にそれぞれ異なる値を指定することができます。例えば、systemに「a」、globalに「bb」、localに「ccc」といった具合にです。このように重複が生じた場合はlocal・global・systemの順に優先されます。ですので、先の例ではlocalに設定された「ccc」が有効となります。

基本的にsystemを触ることはなく、設定を弄るとしたらglobalかlocalのどちらかとなります。とりあえずglobalに設定を入れておくと、リポジトリを新規作成するたびに再設定する手間が省略できるので便利です。





### 5-1. 設定を確認

設定を確認したり変更したりするには **configコマンド** を使用します。

**--listオプション** を指定することで、全ての設定項目を確認することができます。system・global・localに重複して値が指定されていた場合は、そのうちで有効となる値が表示されます。

```
PS C:\Users\AGadget> git config --list
```

特定の設定項目だけ確認するならば引数に設定項目を指定します。こちらもsystem・global・localに重複して値が指定されていた場合は、そのうちで有効となる値が表示されます。

```:文法
PS C:\Users\AGadget> git config [設定項目]
```

```:例文
PS C:\Users\AGadget> git config user.email
```

有効な値ではなく、system・global・localのいずれかの設定項目を確認したいときは、それぞれ **--systemオプション** ・ **--globalオプション** ・ **--localオプション** のいずれかを指定します。

```:文法
PS C:\Users\AGadget> git config [設定場所] [設定項目]
```

```:例文
PS C:\Users\AGadget> git config --system user.email
```

--listオプションを用いることもできます。

```
PS C:\Users\AGadget> git config --system --list
```





### 5-2. 設定を変更

設定を変更するには、system・global・localのいずれの場所の値を変更するかをオプションで指定し、加えて、第1引数に変更する設定項目、第2引数に新たに設定する値を指定します。

```:文法
PS C:\Users\AGadget> git config [設定場所] [設定項目] [値]
```

```:例文
PS C:\Users\AGadget> git config --global user.email AGadget@gmail.com
```

ちなみに、変更する場所を指定する--systemオプション・--globalオプション・--localオプションを省略した場合、--localオプションが指定されたものとして処理されます。

```:--localオプション付きと見做される
PS C:\Users\AGadget> git config user.email AGadget@gmail.com
```





### 5-3. 代表的な設定項目

いくつか代表的な設定項目を紹介します。

まずは **user.email** です。連絡先を表しています。この設定項目に有効な値が入っていないと、リポジトリにデータを保存することができませんので注意してください。「連絡先を入力するのはちょっと……」という方は適当な値を入れておいても大丈夫です。

```:例文
PS C:\Users\AGadget> git config user.email AGadget@gmail.com
```

```:テキトーな値でもOK
PS C:\Users\AGadget> git config user.email xxx
```

**user.name** は名前を表します。user.nameに有効な値がない場合は **unknown** という値がuser.nameに入っているものとして処理されます。

```
PS C:\Users\AGadget> git config user.name AGadget
```

インストール時に指定した標準のテキストエディタを表すのが **core.editor** です。Gitではリポジトリにデータを保存するときにコメントを添えることが求められます。「何故保存したのか？」「何を保存したのか？」といったことを書くのですが、このcore.editorに設定されたテキストエディタが起動します。

```
PS C:\Users\AGadget> git config core.editor code
```





## 6. ワークツリーの使い方

**リポジトリに保存したいファイルを配置する場所** と説明したワークツリーですが、このように説明されると「アプリ・システムを構成するソースファイルだけど、保存する予定のファイルはどこに置いておくの？」「保存処理が実行できたら、ワークツリーに配置していたソースファイルはどうしたら良いの？」と疑問に思われるかもしれません。

多くの場合、リポジトリは1つのアプリ・システムと紐づくように作られます。そのアプリ・システムを構成するソースファイル等は常にワークツリーに置いておき、ワークツリーに置いたままテキストエディタ等で編集するのが一般的です。

もちろん、リポジトリに保存したいときだけワークツリーに配置し、保存後はワークツリーから削除するという運用でも問題はありませんが、かなり特殊な運用だと思います。





## 7. インデックスとステージング

リポジトリにファイルを保存したくなったら、まずはインデックスにファイルを保存・登録しましょう。この操作を **ステージング** と言います。

ステージングするには **addコマンド** を使用します。

```
PS C:\Users\AGadget> git add [ステージングしたいファイルパス]
```

複数のファイルをステージングするときは、ファイルパスを半角空白で区切るか、正規表現を使用してみてください。

```
PS C:\Users\AGadget> git add .\file-1.ps1 .\file-2.ps1 .\file-3.ps1
```

```
PS C:\Users\AGadget> git add .\*.ps1
```

変更のあったファイルの全てをステージングしたいときは **--allオプション** が便利です。

```
PS C:\Users\AGadget> git add --all
```





## 8. ワークツリーとインデックスの状態を確認

リポジトリに保存したいファイルはステージングする必要があるわけですが、リポジトリへの保存処理を実行する前に、本当にステージングできたか確認しておくのがベターです。

確認には **statusコマンド** を使います。

```
PS C:\Users\AGadget> git status
```

statusコマンドを使うことで――

- ステージングされていない新規ファイル
- ステージングされた新規ファイル
- ステージングされた変更のあったファイル
- ステージングされていない変更のあったファイル
- ステージングされていない削除されたファイル
- ステージングされた削除されたファイル

――など、ほとんどのファイルの状態が確認できます。ただし、リポジトリに最後に保存されたときから変更が加えられていないファイルなどはstatusコマンドに表示されないので注意してください。何度か使ってみれば挙動がよく分かると思います。

挙動や表示内容が理解できるようになったら **--shortオプション** を試してみましょう。--shortオプションを付けると、通常の表示メッセージよりも短い内容で出力されます。

```
PS C:\Users\AGadget> git status --short
```





## 9. コミット

initコマンドでリポジトリを用意し、configコマンドで設定を済ませ、addコマンドでファイルをステージングし、statusコマンドでステージングされたかどうかを確認できましたら、リポジトリへのファイル保存処理を実行することができるようになります。

**commitコマンド** を使うことでリポジトリにファイルを保存することができます。この保存処理のことを **コミットする** と言い、commitコマンドを実行するたびに作られるデータ単位（ゲームでいうセーブデータのことです）を **コミット** と言います。

commidコマンドの引数に指定されたファイルがコミットの対象になります。正規表現も使用できます。


```:文法
PS C:\Users\AGadget> git commit [ファイルパス]
```

```:例文1
PS C:\Users\AGadget> git commit .\main.ps1
```

```:例文2
PS C:\Users\AGadget> git commit .\file-1.ps1 .\file-2.ps1 .\file-3.ps1
```

```:例文3
PS C:\Users\AGadget> git commit .\*.ps1
```

全てのファイルをコミットしたいときは **--allオプション** を使用すると便利です。

```
PS C:\Users\AGadget> git commit --all
```





### 9-1. コミットメッセージ

commitコマンドを実行すると **コミットメッセージ** を入力するために、設定項目 **core.editor** に登録されたテキストエディタが起動します。

コミットメッセージとは各コミットに付ける説明文のことです。 **コミットした理由** ・ **コミットの概要および詳細** ・ **このコミットがどういう結果を及ぼすか** などをコミットメッセージに入力します。コミットメッセージがあるおかげで、後からコミット履歴を読み返したときに「ここで○○を実装したのか」「こういう流れで開発されたのか」「バグ修正に随分と時間がかかっているな」みたいなことが分かるのです。

テキストエディタが起動しましたら、1行目からコミットメッセージを入力してください。途中に改行を入れても問題ありません。

入力が完了しましたら上書き保存してテキストエディタを閉じてください。テキストエディタが閉じられたタイミングで、コミットメッセージの登録が完了します。

コミットメッセージの入力をコマンドライン上から行いたいという場合は **--messageオプション** を使用してください。

```
PS C:\Users\AGadget> git commit --message="main.ps1をコミットします。" .\main.ps1
```





### 9-2. コミットメッセージは必須

コミットメッセージを入力しない――コミットメッセージを空のまま登録することは、原則として許可されませんので注意してください。入力せずにテキストエディタを閉じるとエラーになり、コミット処理が無効になります。

どうしても入力したくない（そんなケースあるか？）という場合は **--allow-empty-messageオプション** を付けてください。テキストエディタは起動しますが、空のまま閉じてもエラーにならず、コミット処理が正常終了します。

```
PS C:\Users\AGadget> git commit --allow-empty-message .\main.ps1
```





## 10. 履歴を確認

コミットの記録を確認するには **logコマンド** を使用します。

```
PS C:\Users\AGadget> git log
```

実行すると新しいコミットから順に表示されます。コンソールに表示されるメッセージの量はコミットの数に比例しますので、コミットの数があまりに多いと以前の記事で触れました **Vi/Vimモード** になります。

新しいコミットから任意の数だけ表示したいという場合は **--max-countオプション** が使えます。

```:文法
PS C:\Users\AGadget> git log --max-count=[表示件数]
```

```:例文
PS C:\Users\AGadget> git log --max-count=5
```