初学者がGitについて学習してみる

チーム開発においては、
バージョン管理システムなるものの利用がスタンダードであり、バージョン管理システムにも色々あるらしいが、その中でもGitがソース管理のデファクトスタンダードのようなので、使いこなせるように色々調べてみる。

##バージョン管理システムについて
####「集中管理方式」「分散管理方式」
　　バージョン管理システムではソースコードに対して、
　　**「誰が」「いつ」「何を変更したか」**というような情報を記録して、
　　`過去のある時点の状態を復元したり、変更内容の差分を表示できるようにする。`
　
　　過去、集中管理方式の「CVS」や「Subversion」の利用が多かったが、
　　複数人での分散開発の容易さやパフォーマンスに優れた
　　分散管理方式の「Git」や「Mercurial」がスタンダードとなっている。

####なぜバージョン管理するか
　　・開発中にバグが発生しても、問題発生前のバージョンに簡単に戻せる
　　・バグ発生時に、変更の差分から原因分析できる
　　・同じ環境を別に用意でき、機能の追加、変更を安心して行える
　　・変更内容はバージョン管理システムに記録されるため、コメントとしてコード内に入力しておく必要が無い

####何をバージョン管理するか
　　ソフトウェア開発の中で作成する成果物の中で、何をバージョン管理すれば良いのか。
　　理想的にはソフトウェア・環境構築するために必要なもの全てらしい。

　　具体的には
　　・ソースコード
　　　最も変更されるのでバージョン管理しない理由がない
　　・ビルドスクリプト(コンパイル等、プログラムが実行できるように準備するためのもの)
　　・データベースのスキーマ定義、マイグレーションのSQL、初期データ
　　　ソフトウェアのバージョンに対応したスキーマや初期データを構築するために必要
　　・環境構築用の設定ファイル・スクリプト

####バージョン管理の必要が無いもの/してはいけないもの
　　・ソースコードをコンパイルしてできたバイナリファイル(テキストデータ以外のファイル)
　　　ソースコードをコンパイルすれば再現できるので要らない
　　・秘密鍵ファイル等他人に見せては行けないもの

####ブランチとは
　　バージョン管理システムでは、**コミット**という単位で変更内容を記録して、その繋がりによって履歴を管理する。
　　ブランチは、コミットによる履歴の枝分かれの目印となるような存在。
　　ブランチで枝分かれした履歴は、それぞれで行われた変更の影響を受けることなくすすめることができるため、機能追加やバグ修正等、複数人での開発を並行して安全に進めることができる。
　　枝分かれした履歴は、必要に応じて**マージ**することで１つにまとめることができる。
　　ブランチは、マージしなければ他のブランチに影響を与えない。
　　ブランチを分岐してから、長時間マージを行わず作業をしていると、他のブランチとの差異が広がり、マージの際に「競合」を起こしてしまう可能性が高くなる。
　　復数のブランチで同時に作業を進めている場合など、マージの方針を決めておかないと、履歴が複雑になり、変更履歴をたどることが困難になる場合もある。

####４つのブランチ運用モデル
　　いざというときにあとから変更履歴をたどるのが困難になることを避けるために、開発メンバーでマージ等のブランチ運用に関するルールを決めたりする

#####統合ブランチとフィーチャーブランチ
　　基本的なブランチの運用として「統合ブランチ」「フィーチャーブランチ」２種類の運用方法がある。
　　「統合ブランチ」
　　　フィーチャーブランチを分岐したり、マージしたりする開発のメインラインとなるブランチ
　　　いつでもリリースできるよう安定した状態を保つげき
　　「フィーチャブランチ」
　　　機能追加やバグ修正の際、統合ブランチから分岐した、一つの機能やトピックスに関する開発をするためのブランチ

####バージョン管理のワークフロー
#####「git-flow」
　　デスクトップ/モバイルアプリケーションのように、「リリース」を必要とするソフトウェアの開発に適している。

　**メインブランチ**
　　メインブランチは「master」と「develop」で、常に存在する。

|種類|用途|
|:-:|:--|
|master|リリース済みのソースコードを管理する|
|develop|開発中のソースコードを管理する|

　**メインブランチ**
　　タスクごとにいずれかのブランチを作成して作業を行う。

|種類|分岐元|マージ先|用途|
|:-:|:-:|:-:|:--|
|フィーチャー|develop|develop|機能実装やバグ修正などの開発作業|
|リリース|develop|develop<br>master|リリース準備作業|
|ホットフィックス|master|develop<br>master|緊急の修正作業|

　**git-flowの開発フローの流れ（例）**

　　①masterブランチからdevelopブランチを作成
　　②developブランチからフィーチャーブランチを作成し、機能実装。
　　　フィーチャーブランチにコミットする
　　③フィーチャーブランチでの作業が完了後、フィーチャーブランチをdevelopブランチにマージする。
　　　マージ完了後にフィーチャーブランチを削除する。
　　④機能実装が終わり、リリースできる状態になったら、developブランチからリリースブランチを作成する。
　　　バージョン番号やドキュメントの更新などのリリース準備作業を行う。
　　⑤リリースブランチでの作業が完了したら、リリースブランチをmasterとdevelopブランチにマージする。
　　　マージ完了後にリリースブランチを削除する。
　　⑥リリース後に緊急の修正作業が発生した場合は、masterブランチからホットフィックスブランチを作成し、修正作業を行う。
　　⑦ホットフィックスブランチでの作業が完了したら、ホットフィックスブランチをmasterとdevelopブランチにマージする。
　　　マージ完了後にホットフィックスブランチを削除する。


#####「GitHub Flow」
　　「GitHub Flow」は「GitHub」の開発で使用されているワークフローで、
　　先述の「git-flow」に比べてシンプルな構成。
　　1日に複数回デプロイを行うようなWebアプリケーションの開発に適している。

　**「GitHub Flow」の6つのルール**
　　6つのルールが存在する。ルール①が最も重要で、他のルールは①を実現するために存在する。
　　①**masterブランチは常にデプロイ可能である**
　　②作業用ブランチをmasterから作成する
　　③作業用ブランチを定期的にプッシュする
　　④プルリクエストを活用する
　　⑤プルリクエストが承認されたらmasterへマージする
　　⑥masterへのマージが完了したら直ちにデプロイを行う

　**GitHub Flowの開発フローの流れ（例）**
　　①開発作業を行う
　　　作業開始時に作業用ブランチをmasterブランチから作成する。
　　　※git-glowとは異なり、全てのブランチはmasterブランチから作成する
　　②プルリクエストを行う
　　　作業用ブランチをmasterブランチへマージできる状態になったら、プルリクエストを作成して
　　　他の開発者にコードレビューを依頼する。
　　　そして、プルリクエストが承認されたら、masterブランチへマージする。
　　　※GitHub Flowでは、プルリクエストを積極的に活用する。作業途中の実装への助言を求めたりもする。
　　③デプロイする
　　　masterブランチへのマージが完了したら、直ちにデプロイする。

##Gitとは
ソースコードを作成してソフトウェアを開発していく中で、
バグ修正や機能追加ごとにソースコードの状態を記録して、
それぞれのバージョンを管理することが必要になる。

そういったことを管理するソフトウェアがバージョン管理システムであり、「Git」もその一つ。

####Gitを利用した作業の流れ
　　①**共有リポジトリ**から**ローカルリポジトリ**に**clone**(リポジトリのコピー)
　　↓
　　②実際に利用者が編集するファイル(**作業ツリー**)でファイルを編集
　　↓
　　③**作業ツリー**をコミット対象として**インデックス**に**add**する
　　↓
　　④**commit**して**インデックス**から**ローカルリポジトリ**に変更を反映
　　↓
　　⑤**push**して**ローカルリポジトリ**から**共有リポジトリ**に差分を反映
　　↓
　　⑥**pull**して**共有リポジトリ**から**ローカルリポジトリ**に差分を取得
　　↓
　　②へ進んでいく
　　というサイクル

#####共有リポジトリ
　　復数の利用者で共有するリポジトリ。
　　ローカルリポジトリの変更を共有リポジトリで反映して利用者間で共有する。
#####ローカルリポジトリ
　　利用者がローカルマシン上の作業で利用するリポジトリ。
　　**clone**により共有リポジトリを複製して、
　　**push**によりローカルリポジトリの変更差分を共有リポジトリへ反映
　　**pull**により共有リポジトリ上で更新された他の利用者の変更差分を取り込む
#####作業ツリー
　　実際に利用者が編集するファイル。
　　**checkout**により、他のブランチに切り替えたり、
　　特定の(バージョン)コミットの状態にすることもできる。
#####インデックス
　　**add**により作業ツリーの変更点を一時的に登録する領域。
　　登録された変更点は**commit**によりローカルリポジトリに反映する。

####ローカルリポジトリの作成
#####方法①新しいローカルリポジトリを作成
　　シェルを起動して、管理したいファイルが有るディレクトリ上で

```terminal
  $ git init
```
　　を実行する。
　　この時点で、「.git」が作成される。
　　ファイルをリポジトリへ登録するには以下を実行する

```terminal
  $ git add -A
  $ git commit
```

#####方法②共有リポジトリを複製
　pc上のフォルダからローカルリポジトリを作成して、GitHubで管理できる共有リポジトリにする
　　pc上にローカルリポジトリ作成の手順　※デスクトップに作成してみる

```terminal
    #デスクトップに移動
  $cd /Users/ユーザー名/Desktop

    #repositoryフォルダを作成
  $mkdir repository
```
　　GitHubでリポジトリ作成(Newボタンから)
<img width="249" alt="スクリーンショット 2019-12-24 12.22.10.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/493097/aaee7aa9-4c5c-c24e-7b69-6d00bb890b88.png">

　　GitHubで作成したリポジトリでclone

```terminal
    #共有リポジトリをclone
  $git clone http://リポジトリのURL
    #作業ツリーをステージにaddする
  $git add -A
    #ステージからローカルリポジトリに変更を反映
  $git commit -m "コメント"
    #ローカルリポジトリの変更を共有リポジトリにpush
  $git push
```



####無視ファイル(.gitignore)の設定
　　Gitリポジトリの管理対象外としたいファイルを
　　「.gitignore」というファイルに定義し、リポジトリの一番上のリポジトリに置いてコミットすることで、管理対象から外すことができる。

####gitコマンド
#####git status
　　作業ツリー内のファイルの状態を表示

　　【オプション(抜粋)】
　　　■-s(--short)
　　　　短いフォーマットで表示(ファイルが多いときに使うと見やすい)
　　　■-v
　　　　インデックスに入っている差分を表示
　　　■-v -v
　　　　-vに加えて、インデックスに入っていない差分も表示する
　　　■-b(--branch)
　　　　-sと併用する。ブランチ名も表示する。

#####git branch
　　ブランチの一覧表示

```terminal
    #アスタリスクが付いているブランチが現在のブランチ
  $git branch
   *masster
```
#####git checkout -b 【新しいブランチ名】
　　新しいブランチを作成して、そのブランチに現在のブランチを切り替える

```terminal
  $gitcheckout -b topic
  Switched to a new branch 'topic'
  $git branch -l
    master
   *topic
```

#####git reset HEAD
　　インデックスを HEAD の状態へ戻す

#####git commit --amend
　　直前のコミットの変更(エディタが開いて、内容を修正できる)