SubversionからのGit入門(Gitのメリット、Subversionとの違い)


Gitがよく取り上げられていますので、少し長いですが、概念だけでも簡単に掴みたい方のために資料を作ってみました。

Gitがここまで広がった要因にはGitのみならず、GitHubやそのクローンが持っているPull Requestの仕組みの影響も大いにあると個人的には考えています。が、まずは簡単にGitとはどんなものかをまとめたいと思います。

* どうしてGitなのか、Gitのメリット
* SubversionとGitの違い
* ローカルでGitを使ってみる
* Gitサーバーのある構成管理

## 1.どうしてGitなのか、Gitのメリット

最初にGitのメリットを明確にしておきましょう。Gitは分散型の構成管理システムとよく言われます。この「分散型」「構成管理」の意味を理解するのがGitを使う上で最大のポイントになると思います。

この記事をお読みの方は既にSubversionなどサーバーによる構成管理を導入されていると思いますが、そこに「分散」が加わるのがGitのポイントです。以下で説明しますが、その「分散」によって開発者がソースツリーを思う存分むさぼることができる、それがGitによる分散型構成管理メリットだと私は思います。

Git以前の従来の構成管理は中央集権型です。サーバーにある構成管理されたソースツリーを開発者の環境へ持ってきます。開発者はローカル環境で試行錯誤しながら、開発を行い、その結果を再びサーバーへコミットします。

この従来のやり方は、[開発者の手元にソースコードがある期間]に問題があります。この期間ではローカルのファイル管理に任されたりすることが多くなり、構成管理しきれなかった部分で開発者が試行錯誤した結果が失われることがありました。

一方でGitはサーバーで構成管理していたソースコードを取得するところまでは同じです。ただし、その後は構成管理から外れるのではなく、開発者のPCに[引き継がれます]。開発者PCのGitによって構成管理されます。このように構成管理の主体がサーバーだけでなく、独立して開発者のPCでも行われるため、分散型の構成管理となります。

開発者側で管理されている間はサーバーと同期せずとも、サーバーと独立して開発者のPCの中でしっかり構成管理できていますので、修正にしろ、新機能の追加にしろ、開発者は存分にソースコードを改変できます。改変が終わった後には開発者PCの構成管理内容をサーバー側の構成管理へ反映し、マスターとなるソースツリーを更新をします。

Gitでの作業は上記のような手順になります。開発者に構成管理主体が引き継がれることで、開発者がマスターのソースツリーを気にせず、独立した作業が容易になります。開発者のチャレンジが簡単になります。この「思う存分の開発」を素早くできるようにする、それがGitの分散型の構成管理のポイントです。

| 今の状態 | 提供するメリット |
|:---|:---|
|構成管理未導入|構成管理の提供|
|Git以外の構成管理導入済|開発者が独立した構成管理ができ、修正や機能追加を容易にする|



## 2.GitがSubversionと違う点

後半はGitの使用例を見てみるつもりですが、分散型という構成管理にするためにSubversion等と異なっている点があるので事前に確認しておきましょう。

### 2.1. ステージング状態の存在

Gitは構成管理から取得したファイルを編集し、コミットする中間にステージング状態があるのが特徴です。以下のようなイメージになります。

手元のファイル-(addコマンド)→ステージング状態-(commitコマンド)→構成管理された状態

### 2.2. push / pull

Subversion等ではコミット=サーバーへの反映でしたが、コミットはローカルの構成管理に対してのコミットに相当しますので、別途、ローカルにコミットされた内容を遠隔に送る別のコマンドが必要になります。それがpushとpullです。

| コマンド | 意味 |
|:---|:---|
| push |コミットされた内容を遠隔の構成管理に送る|
| pull |遠隔にpushされている内容をローカルの構成管理に取り込む|

### 2.3.バージョンの識別が連番ではない

バージョンはバージョン識別する文字列であって、連番になっていないので注意する。（分散型なので、あちらのRev.1234がこちらのRev.1234と同一かは確定できない。連番にすることができない。）


## 3.ローカルでGitを使ってみる

最終的にはサーバーを使って構成管理を行います。が、まずは最初にローカル環境でGitによる構成管理をして少しずつコマンドを覚えていきましょう。

### 3.1.初期化

編集を行うディレクトリで、以下のコマンドを入力します。

```
>git init
```

以降は、このディレクトリ内で編集を続けると思ってください。

### 3.2.ファイルを追加する一連の流れ

Gitの場合、Subversionと異なりステージング状態が存在するのが特徴です。以下のように何かファイルの編集をしたら、編集したファイルをステージング状態にして、その後、コミットする手順になります。コミットコマンドの-mオプションは、コミット時のメッセージの指定を行います。

```
>touch hello.txt　(ファイルの追加）

>git add hello.txt　（ステージングへの追加）

>git commit -m "add hello.txt"　（ステージングからのコミット）
```

### 3.3.ファイルを編集する一連の流れ(ステージングへの追加が必要）

編集時にも同じく、addコマンドが必要です。

```
>vi hello.txt　(ファイルの編集）

>git add hello.txt　（ステージングへの追加）

>git commit -m "modify hello.txt"　（ステージングからのコミット）
```

### 3.4.ブランチの操作

Gitではmasterという全ての中心となるブランチがあり、通常の機能追加などは、そこへ新しくブランチを作成した上で行い、masterブランチへと取り込みます。

ブランチ状態を見る場合、次のようにして一覧や今いるブランチ名を取得できます。以下の場合は2つのブランチがあり、masterブランチにいることがわかります。

```
>git branch

```

ブランチを作成する場合

```

>git branch (ブランチ名)

```

ブランチの移動は以下のように行います。

```

>git checkout (ブランチ名)

```


### 3.5.コミットログを見る

コミットの内容を確認するにはコミットログをみます。

```
>git log

commit 70175e9fd9a36f7aea8af73f18778b7f472a3277
Author: xxxx <xxxx>
Date:   Sat Jan 3 10:53:06 2015 +0900

    modify hello.txt

commit 195066c3c0668ef6629defb2eaef36b2d051cd76
Author: xxxx<xxxx>
Date:   Sat Jan 3 10:50:51 2015 +0900

    add hello.txt

```


コミット内容を1行にし、ブランチのツリー状で見たい場合は

```

>git log --oneline --graph

```


###　3.6. 特定バージョンを取得する

```
>git checkout 19506

commit 70175e9fd9a36f7aea8af73f18778b7f472a3277
Author: xxxx <xxxx>
Date:   Sat Jan 3 10:53:06 2015 +0900

    modify hello.txt

```

##4. Gitサーバーのある構成管理

リモートの場合は次のような作業手順になる。前述の通り、Subversionでのコミット、つまりサーバーへの反映は以下ではpushに相当する。

1. リポジトリをクローンし、ソースコードツリーを取得する。
2. （通常はブランチを作成し、ブランチへ移動する。)
3. リポジトリを編集する。
4. 変更をステージングされた状態にする。
5. 変更をコミットする。
6. 変更をpushする。
(1.の状態に戻る）

ツリーが別の人によって行われた変更を取得するには、pullをします。

(上記の1.の状態で)
2'. 遠隔にpushされている変更をpullする。

以下、およそのコマンドを見てみます。

### 4.1.クローンでソースコードのツリーを取得する

クローンした場合、どこのツリーを取得したかの情報が"origin"として記録されます。

```
>git clone http://*********.git

```

### 4.2.変更をpushする。

変更をサーバーへ送る場合、pushを使います。

originはクローンした際の取得元として記録されていますので、下ではoriginとmasterブランチが自動的に補われます。

```
>git push

```


ブランチ上での開発している場合はoriginにブランチをpushする場合は以下のようになります。

```
>git push origin (ブランチ名)

```

### 4.3.変更をpullする。

変更を取得する場合はpullを使用します。

```
>git pull

```

## 5.まとめ

Gitのイメージを出来るだけ伝えるようにまとめてみましたが、いかがでしたでしょうか。時間があればGitHub(Pull Request)についてもまとめてみたいと思います。