初めてGitを使う人向けに情報をまとめてみた(基本編)

最近社内で「今までSubversionしか使ったことない人」を対象に、Git研修をやったので、情報をまとめてみました。

# 目的
* GitとSubversionでの構成管理方法の違い
* Gitの基本的な操作の理解

# 1. 構成管理の基本編
そもそも構成管理(この場合はソフトウェア構成管理)とは、ソースコードや文書などの成果物の変更履歴(「誰が」「いつ」「何を変更したか」)を管理し、任意のバージョンの製品を再現可能とすることを目的としています。

## 1-1. バージョン管理システム
バージョン管理システムとは、この構成管理を人手ではなく、システムを用いて行うことで、過去のある状態への復元を容易にしたり、変更内容の差分を表示できるようにします。
バージョン管理システムには大きく「集中型バージョン管理システム」と「分散型バージョン管理システム」に分けることが出来ます。

## 1-2. 集中型バージョン管理システム
* 特徴
    * 集中型バージョン管理システム(ex. [Subversion](https://subversion.apache.org/))では、1つのリポジトリ(変更管理情報を保存する場所)を複数人で共有して利用します。  
利用者は、サーバにあるリポジトリから資材を取得(Checkout)し、変更作業が完了したらリポジトリに登録(Commit)します。

![集中型バージョン管理システム.png](https://qiita-image-store.s3.amazonaws.com/0/265994/34e958e2-99ab-a668-4826-4bc1925c124e.png)

* メリット
  * 単一リポジトリで仕組みがシンプルなため、管理が容易である
* デメリット
  * 単一のリポジトリに対して並行開発を行うと、競合が発生しやすい
  * リポジトリへのアクセスが常にNW経由となる

## 1-3. 分散型バージョン管理システム
* 特徴
  * 分散型バージョン管理システム(ex. [Git](https://git-scm.com/),[Mercurial](https://www.mercurial-scm.org/)) では、複数のリポジトリを持つことが出来ます。  
利用者はサーバにあるリモートリポジトリから、開発者それぞれのローカル環境にリポジトリを構築して管理します。  
開発者の作業イメージとしては、普段はローカルリポジトリで作業を行い、作業を終えたらリモートリポジトリに反映します。

![分散型バージョン管理システム.png](https://qiita-image-store.s3.amazonaws.com/0/265994/12fb229c-1e61-c99b-1927-8d0ed9b2a5ee.png)

* メリット
  * ローカル上のリポジトリを更新することにより、NWに繋がらない状況でも利用できる
  * 他のリポジトリに影響なく並行開発が可能
* デメリット
  * リポジトリが複数存在するため、理解や管理が困難
  * 事実上マスターリポジトリが存在しない状況になる

# 2. Gitの基本編
Gitで構成管理を行う場合、どのような構造イメージなのか、そしてどんなコマンドで実施するのかをまとめます。

## 2-1. リモートリポジトリとローカルリポジトリ
![ローカルとリモート.png](https://qiita-image-store.s3.amazonaws.com/0/265994/3e5885fa-a1d6-dab8-d5c2-4672ddd59ca2.png)

* リモートリポジトリ
  * 専用のサーバに配置して、複数人で共有するためのリポジトリ
* ローカルリポジトリ
  * 個々のユーザが利用するために、自分の手元のマシン上に配置するリポジトリ

## 2-2. Gitの構造
![Gitの構造.png](https://qiita-image-store.s3.amazonaws.com/0/265994/f484e302-0697-9077-5ddd-f79db3a6a2e8.png)

1. ワーキングディレクトリ  
  * Gitの監視下でユーザーが更新や追加作業を行う領域
1. ステージングエリア  
  * リポジトリにコミットするファイルを登録する領域
1. ローカルリポジトリmaster  
  * ステージングエリアからコミットされたファイル群(スナップショット)を格納する領域
1. ローカルリポジトリorigin/master  
  * リモートリポジトリの状態をローカルリポジトリで確認するための領域
1. リモートリポジトリ  
  * リモートリポジトリ上に管理しているファイル群(スナップショット)を格納している領域

## 2-3. Gitコマンド～個人作業編～
主に個人作業で実施する機会の多いコマンドを以下に記載します。

![個人作業編1.png](https://qiita-image-store.s3.amazonaws.com/0/265994/e31db990-d13e-b9f2-40c2-fef5b2ddbfad.png)

* git add(ステージングエリアへの移行)
  * ワーキングディレクトリで追記変更を行ったファイルやディレクトリをステージングエリアに移行  
  * `git add <file>..` (スペース区切りで複数ファイルを指定可能)
* git commit(リポジトリへのファイル登録)
  * ステージングエリアに登録されたファイルのスナップショットを作成し、リポジトリへ移動する作業。
  * `git commit -m "<コメント>"`

![image.png](https://qiita-image-store.s3.amazonaws.com/0/265994/87730a71-d7b2-b90f-e97f-d9381fdfd9d3.png)

* git remote(リモートリポジトリの登録)
  * リモートリポジトリ連携の登録を行う(cloneでは動的に「origin」という名前でリモートリポジトリが登録)
  * `git remote add <name> <url>`  
  (name：登録名、url：リモートリポジトリのURL)
* git push(リモートリポジトリへの送信)
  * リモートリポジトリで自分の手元のローカルリポジトリの変更履歴を共有するために、ローカルリポジトリ内の変更履歴をアップロードする。  
  Pushを実行すると、リモートリポジトリ内の変更履歴がローカルリポジトリの変更履歴と同じ状態になる。
  * `git push <repository> <refspec>...`  
  (repository：プッシュ先アドレス、refspec：プッシュするブランチ)

## 2-4. Gitコマンド～チーム開発編～
主にチーム開発で実施する機会の多いコマンドを以下に記載します。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/265994/bfbdd12e-0c18-6862-9574-a845cbbe10f6.png)

* git fetch
  * ローカルリポジトリにあるリモートリポジトリのコピーを最新版に更新
  * `git fetch <remote repository url> or <remote repository name>`
* git merge(ブランチのマージ)
  * ブランチをメインのブランチに統合する
  * `git merge <branch name>`
* git pull
  * リモートリポジトリの内容を一度にローカル環境の所属ブランチに反映する
  * `git pull <remote repository> <local repository >`

![image.png](https://qiita-image-store.s3.amazonaws.com/0/265994/1218a948-c9bd-7c40-2eb3-a4533c86cb42.png)

* git clone(リモートリポジトリの複製)
  * リモートリポジトリ上で作成したリポジトリの複製をローカルリポジトリに用意する。
  * `git clone <repository> <directory>`  
  (repository：リモートリポジトリのURL、directory：複製先のディレクトリ名)

基本的な概念やコマンドは以上です。
rebaseやブランチ戦略、その他便利なコマンドや使い方については別途まとめたいと思います。

## 参考書籍
[わかばちゃんと学ぶ Git使い方入門](https://www.amazon.co.jp/dp/B071D4D6XX/ref=dp-kindle-redirect?_encoding=UTF8&btkr=1)：漫画感覚でGitを学ぶのにちょうど良い書籍です。