Gitの基本
入門編
・Gitでは、ファイルの状態を好きなときに更新履歴として保存しておくことができる。そのため、一度編集したファイルを過去の状態に戻したり、編集箇所の差分を表示したりすることが出来る。
・古いファイルを元に編集したファイルで、他人の編集した最新ファイルを上書きしようとすると、サーバにアップロードした時に警告が出るため、他人の編集内容を上書きできないようになっている。
・リポジトリとは、ファイルやディレクトリの状態を記録する場所。
●リモートリポジトリとローカルリポジトリ
・リモートリポジトリ
専用のサーバに配置して複数人で共有するためのリポジトリ。
・ローカルリポジトリ
ユーザ一人ひとりが利用するために、自分の手元のマシン上に配置するリポジトリ。
・リポジトリをリモートとローカルの2種類に分けることで、普段の作業はローカルリポジトリを使って全て手元のマシン上で行うことができる。
・自分のローカルリポジトリで作業した内容を公開したい時は、リモートリポジトリにアップロードして公開。また、リモートリポジトリを通してほかの人の作業内容を取得することもできる。
●リポジトリの作成方法
1.全く新しいリポジトリを作成する方法
2.リモートリポジトリをコピーして作成する方法
・コミット
ファイルやディレクトリの追加・変更を、リポジトリに記録する時に操作する。
・時系列順につながった状態でリポジトリに格納される。最新の物から辿ることで、過去の変更履歴やその内容を知ることができる。
・コミットの情報から計算された重複のない英数字40桁の名前が付けられている。この名前を指定することで、リポジトリの中からコミットを指定することができる。
・コミットの実行時にはコミットメッセージの入力を求められる。コミットメッセージは必須となっているため、空のままで実行するとコミットが失敗する。
Gitでは、Gitの管理下に置かれた、実際に作業をしているディレクトリのことをワークツリーと呼ぶ。
Gitではリポジトリとワークツリーの間にはインデックスというものが存在している。
インデックスとは、リポジトリにコミットする準備をするための場所のこと。
Gitでは、コミットを実行した時にワークツリーから直接リポジトリ内に状態を記録するのでなく、インデックスの設定された状態を記録するようになっている。
そのため、コミットでファイルの状態を記録するためには、まずインデックスにファイルを登録する必要がある。
●Push
・リモートリポジトリで自分の手元のローカルリポジトリの変更履歴を共有するには、ローカルリポジトリ内の変更履歴をアップロードする必要があるので、プッシュ(Push)という操作を行う。
・Pushを実行すると、リモートリポジトリに自分の変更履歴がアップロードされて、リモートリポジトリ内の変更履歴がローカルリポジトリの変更履歴と同じ状態になる。
発展編
履歴の流れを分岐して記録していくためのものです。分岐したブランチは他のブランチの影響を受けないため、同じリポジトリ中で複数の変更を同時に進めていくことができる。
分岐したブランチは他のブランチと合流(マージ)することで、一つのブランチにまとめ直すことが出来る。
チームのメンバーは、他のメンバーの作業の影響を受けないように、メインのブランチから自分の作業専用のブランチを作成する。
そして作業の終わったメンバーは、メインのブランチに自分のブランチの変更を取り込んでいく。
このようにすることで、他のメンバーの作業による影響を受けることなく、自分の作業に取り込むことができる。また、作業単位で履歴を残すことで、問題が発生した場合に原因となる変更箇所の調査や対策を行うことが容易になる。
●masterブランチ
リポジトリに最初のコミットを行うと、Gitはmasterという名前のブランチを作成する。そのため、以後のコミットはブランチを切り替えるまでmasterブランチに追加されていく。
ブランチは自由に作成することができるが、あらかじめ運用ルールを設けておく必要がある。
●統合ブランチ
・リリース版が何時でも作成可能にしておくためのブランチ。
・トピックブランチの分岐元としても使用する。安定した状態を保っておくことが重要。
・変更を行う場合は、トピックブランチを作成して作業を行うことが多い。
・Jenkins等のCIツールを使用した自動ビルドやテストはこのブランチを使って行う。
通常、masterブランチを統合ブランチとして使用する。
●トピックブランチ
・機能追加やバグ修正といったある課題に関する作業を行うために作成するブランチ。複数の課題に関する作業を同時に行う時は、その数だけトピックブランチが作成される。
・トピックブランチは安定した統合ブランチから分岐する形で作成し、作業が完了したら統合ブランチに取り込むという使い方をする。
作業するブランチを切り替えるには、チェックアウトという操作を行う。 チェックアウトを行うと、まず移動先のブランチ内の最後のコミットの内容がワークツリーに展開される。また、チェックアウト後に行ったコミットは、移動後のブランチに対して追加されるようになる。
●HEAD
現在使用しているブランチの先頭を表す名前。デフォルトではmasterの先頭を表している。HEADが移動することで、使用するブランチが変更される。
●stash
ファイルの変更内容を一時的に記録しておく領域。
stashを使うことで、ワークツリーとインデックス中でまだコミットされていない変更を一時的に退避させることができる。退避させた変更は後から取り出して、元のブランチや別のブランチに反映させることができる。
mergeを使う方法と、rebaseを使う方法の2種類がある。
●merge
変更内容の履歴はそのまま残るが、履歴が複雑になる。
●rebase
履歴は単純になるが、元のコミットから変更内容が変更される。そのため、元のコミットを動かない状態にしてしまうことがある。
mergeとrebaseは、チームの運用方針に応じて使い分ける。例えば、履歴を一本化するように運用をするのであれば
・トピックブランチに統合ブランチの最新のコードを取り込む場合はrebaseを使う
・統合ブランチにトピックブランチを取り込む場合は、まずrebaseしてからmerge
というように使い分ける。
機能の追加を行うトピックブランチで作業を行なっている途中に、バグの修正を行わなければならなくなったとしても、バグ修正用のトピックブランチをつくることで作業をすることが出来る。
完成したバグ修正は元の統合ブランチに取り込むことで公開できる。
しかし、作業の続きを行うには今のバグ修正、コミットXの内容が必要だったことに気づいたとしても、直接mergeする方法と、コミットXを取り込んだ統合ブランチにrebaseする方法があるので大丈夫。
●メインブランチ
・master
masterブランチでは、リリース可能な状態だけを管理する。また、コミットにはタグを使用してリリース番号を記録する。
・develop(トピックブランチ)
developブランチでは、先のリリースに向けた普段の開発で使用するブランチ。先に説明した統合ブランチの役割を担う。
●フィーチャーブランチ
フィーチャーブランチでは、トピックブランチの役割を担う。
このブランチは新機能の開発や、バグ修正を行う際にdevelopブランチから分岐する。フィーチャーブランチでの作業は基本的に共有する必要がないので、リモートでは管理しない。開発が完了したら、developブランチにマージを行うことで公開する。
●リリースブランチ
・リリースの準備を行う。ブランチ名の頭には release- をつける。
リリースブランチを作ることで、最終的な調整はこのブランチで行いながら、更に次のリリースに向けた開発をdevelopブランチ上ですすめることができる。
・普段の開発はdevelopブランチ上で行なっているため、ほとんどリリース可能な状態が近づいてからリリースブランチを作成する。そして、リリースに向けた最終的なバグ修正などの開発を行う。
・最終的に、リリースブランチがリリース可能な状態になったらmasterブランチにマージを行い、できたマージコミットに対してリリース番号のタグを追加する。
・また、リリースブランチ上で行った修正を取り込むため、developブランチに対してもマージを行う。
●ホットフィックスブランチ
・リリースした製品に緊急で修正が必要になった場合に、masterブランチから分岐して作成されるブランチ。 ブランチ名の頭には hotfix- をつける。
・例えば、developブランチ上での開発がまだ中途半端な状態の時に、緊急で修正が必要になったとする。この場合、developブランチからリリース可能なバージョンを作るのは時間がかかるため、masterブランチから直接ブランチを作成して修正を行い、マージする。
・修正時に作成したホットフィックスブランチは、developブランチにもマージして取り込む。
発展編-チュートリアル1 ブランチを使ってみよう!
まずは新しくディレクトリを作成し、そこに空のリポジトリを作成する。 ここでは、tutorialというディレクトリを作成。
tutorialディレクトリにmyfile.txtという名前でファイルを作成し、コミットする。
この時点での履歴はこのようになる。
ここでは、issue1という名前でブランチを作成。
ブランチは branch コマンドで作成することができる。
ここでは、issue1という名前でブランチを作成。
引数を指定せずにbranchコマンドを実行すると、ブランチの一覧を表示することができる。頭に * のついているのが現在のブランチ。
この時点での履歴はこのようになる。
新しく作成したissue1ブランチにコミットを追加していくには、issue1ブランチをチェックアウトする必要がある。
ブランチのチェックアウトはcheckoutコマンドで行う。
issue1ブランチをチェックアウトする。
この時点での履歴はこのようになる。
issue1ブランチをチェックアウトした状態でコミットを行うと、issue1ブランチに履歴が記録されていく。
myfile.txtにaddコマンドの説明を追加してからコミットしてみる。
この時点での履歴はこのようになる。
issue1ブランチに行った変更をmasterブランチに統合。
ブランチのマージはmergeコマンドで行う。
このコマンドでは、指定したブランチがHEADの指しているブランチに取り込まれる。masterブランチにissue1を取り込むためには、まずはmasterブランチに移動する。
マージを行う前に一度myfile.txtファイルを開いて内容を確認。
前のページでのファイルの編集はissue1ブランチ上で行ったので、masterブランチのmyfile.txtの内容は変更されていない。
masterブランチの指すコミットがissue1と同じ位置に移動した。このマージはfast-forward(早送り)マージ。
myfile.txtファイルを開いて内容を確認。
「add 変更をインデックスに登録する」が追加されている。
プルリクエスト編
・機能追加や改修など、作業内容をレビュー・マージ担当者やその他関係者に通知。
・ソースコードの変更箇所をわかりやすく表示。
・ソースコードに関するコミュニケーションの場を提供。
●レビュー・マージ作業をタスク化して管理し、やりとりを記録できる
・作成されたプルリクエストは一覧で見ることができるため、未完了のプルリクエストを簡単に確認できる。
・プルリクエスト作成者とレビュー担当者は、プルリクエスト上でコメントをやりとりして議論できる。
・最終的にマージされるソースコードの品質を高くできる。
●レビューを促進できる
ソースコードの変更部分を明確に表示できる。また、プルリクエストの作成者は、ソースコードの意図や補足事項をコメントとして伝えることができ、レビュー担当者の負担を減らせる。