Gitコマンド学習

#この記事の目的
筆者がGitを学習する上で、習熟度アップのためのアウトプット用記事投稿として活用します。また、覚えたコマンドの備忘録としても使うため、誤った解釈や内容がある場合はご教示お願いします。


#Gitコマンド
[学習リンク「サルでもわかるGit入門」](http://www.backlog.jp/git-guide/)

【基本コマンド一覧】
■git branch "branch名"
"branch名"のbranch作成

■git checkout -d
branchの削除をする。マージされていないコミットがある場合は削除出来ないが"-D"で強制的に削除することが可能

■git st(statusのエイリアス)
gitコマンドに自分オリジナルのaliasを設定する必要あり

■git config --global alias.co checkout
git config --global alias."alias名" "aliasを作成するコマンド"
↪︎上記記述でalias作成

■git clone "GitホスティングサービスのRepositoryのURL"
指定のremoteRepositoryからlocalRepositoryへcloneを作成する

■git diff
・まだindex(ステージング)にaddしてないものを表示
↪︎※新規ファイルはGitにtrackされていないのでされていないので表示されない

■git add "ファイル名"
"ファイル名"の変更内容を現在のbranchにindex(ステージングにあげる)

■git commit -m "hogehoge"
"hogehoge"のメッセージとともにステージングの変更を現在のbranchにコミット

■git log
リポジトリのコミット履歴を新しい順に表示。

■git push origin hogehoge
hogehoge(branch名指定)で指定のbranchをremoteRepositoryにpushする

■git checkout master
master branchに移動

■git merge hogehoge
・"hogehoge"のブランチにmerge
↪︎※"hogehoge"などの指定がない場合はHEADに指定してあるbranchにmerge

■git push origin master
現在のディレクトリのbranchをremoteリポジトリにpushする

■git co(checkoutのエイリアス)
これも自分で設定すれば使用可能

■git tag "tagname"
"tagname"の軽量タグを作成
↪︎※"--decorate"のオプションでタグ情報を含めた情報の表示が可能

■git tag -a "tagname"
"tagname"の注釈タグを作成
↪︎※"-am"のオプションで現在のHEADが指定しているコミットに注釈タグをつけることができる
↪︎※"git tag -n"で一覧の確認が可能

■git tag -d 
タグの削除

■git reset --hard HEAD~~
2つ分のコミットを削除する
↪︎※"~(チルダ)"の個数で何個前まで戻るか指定可能
↪︎※git reset --hard ORIG_HEAD　でreset前の状態に戻すことも可能

■git reset --hard ORIG_HEAD
resetする前の状態に戻すコマンド

■reset　のオプション
--soft
↪︎HEADの位置のみ変更
--mixed
↪︎HEADの位置とindexを変更する
--hard
↪︎HEADの位置、index、ワーキングツリー全てを変更する

■git rebase
現在いるbranchの分岐元のbranch書き換える

■git status
現在のbranchで変更が行われたファイルの一覧が表示される(commitされたものは表示されない)

■git stash "コメント"
変更を施したファイルをcommitせずに他のbranchに切り替えたい時に活用する。
addをしてindexしていてもいなくても使用可能。
↪︎※stashをした場合、git statusで一覧化されないので注意

■git stash pop
stashで一時退避させていたbranchに戻る
↪︎※git stash listで一次保存されている作業ツリーの一覧を見ることもできる


#branchについて

■統合ブランチ
・リリース版がいつでも作成出来るようにするためのブランチ。
・トピックブランチの分岐元となる
・安定状態を保つことが重要なブランチのため、何か作業を行う場合は別途トピックブランチを作成して作業を行うことがほとんど
・JenkinsなどのCIツールなどはこのブランチを使用して行うことがほとんど

■トピックブランチ(フィーチャーブランチ)
・主に機能追加やバグ修正に使われる、課題解決に使われるブランチ
・複数の課題を解決すつためにはその作業分だけブランチの作成が行われる
・基本的にトピックブランチは作業完了後に統合ブランチにマージされる

■チェックアウト
・現在のブランチから別のブランチへチェックアウトした場合、遷移前のブランチ内の最後のコミットがワークツリーに反映される


■HEAD
・HEADは現在いるブランチの先頭を表す名前。デフォルトではmasterの先頭を表している
・コミットを指定する時に"~(チルダ)"や"^(キャレット)"を使うことで相対パス指定をすることができる
・~(チルダ)は現在のブランチから何世代か前の親を指定できる
・^(キャレット)はブランチのマージ先が複数ある場合に何番目の親かを選択すつことができる

■stash
・チェックアウトをする際に遷移先のブランチで同じ箇所の変更点がある場合、チェックアウトに失敗をすることがある
・チェックアウトに失敗する場合、stash(隠すの意)を活用し、ワークツリーとインデックスの中でまだコミットされていない変更を一時的に退避させることができる機能

■統合方法(merge)
・マスターブランチにmergeする際にmasterが分岐以前の状態から変化がない場合、簡単にmergeをすることができることをfast-forwardと呼ぶ。この際にmaster branchは新しく生成されない
・mergeの際にmasterの変更が進んでいる場合は、両方の変更内容を合わせた新しいmaster branchが生成される
・上記の場合"not fast-forward"のオプションを使うことで、masterの変更がない場合にも新しいburanchを作成する。その場合、分岐までのbranchがそのまま残るので、そのブランチで行なった作業の特定が容易になる

■rebase
・分岐したbranchをrebaseすると、分岐したbranchがmaster branchの後ろにそのまま履歴が追加される
・そのため変更の履歴は分岐形状ではなく一本化される
・ここでこの際に発生した競合はそれぞれ個別に修正をしなければいけない
・この時HEADはmergeしたbranchが指定される(masterの変更履歴に一本化されるため)

■merge&rebaseの運用例
・機能追加のbranchを作成後にmasterのバグが発覚し、新たにbugfixのブランチを作成することにした
・この場合、機能追加のbranchはbugfix前のmasterを参照しているため、このままmergeするとbugfix前のmasterにmergeすることになってしまう
・そのため、一度bugfixのbranchをmasterにrebaseすることでbugfix後のmasterがHEAD(先頭)になるため、機能追加branchを次にmergeするとbugfux後のmasterにmergeされる

■メインブランチ
・master
↪︎リリース可能な状態だけを管理する。
↪︎コミットにはタグを使用してリリース番号を記録する
・develop
↪︎先のリリースに向けた普段の開発で活用する
↪︎統合ブランチの役割を担う

■フィーチャーブランチ
・トピックブランチのこと
・新機能開発やバグ修正のためにdevelopブランチから分岐して活用する
・フィーチャーブランチは基本的に共有する必要はないのでリモートでの管理はしない
・開発が完了したらdevelopブランチにmergeして公開する

■リリースブランチ
・リリースをの準備を行うブランチで先頭に"release-"とつけるのが慣例
・リリースに向けた最終調整を行いながら、同時並行でdevelopブランチでの開発を進めることができる
・リリースブランチでの修正が完了した後にメインブランチにmergeしてできたコミットに対してリリース番号のタグを付与する
・リリースブランチ上で行った修正を取り込みためにdevelopブランチへもmergeを行う

■ホットフィックスブランチ
・リリースした製品に緊急で修正が必要な場合にmasterブランチから分岐して作成するブランチ
・進行中のdevelopブランチから修正のための分岐をさせると修正完了までに時間がかかるため直接masterブランチから分岐する
・修正が完了した際にdevelopブランチにもmergeする


#リモートリポジトリ

■FETCH_HEAD
リモートリポジトリからpullした時に通常だと自動的にmergeが行われてしまうのだが、FETCH_HEADを使うことでmergeをせずにpullすることができる。※pull=(fetch + merge)となる

■PUSH
PUSHをする時はローカルリポジトリがfast-forwardされる状態にしておく必要がある。そうでないとPUSHが拒否されてしまう。基本的にリモートリポジトリで共有しているコミットは変更をしてはいけない。そのリポジトリと同期している他のリポジトリの履歴もおかしくなるので注意が必要。


#タグ
■軽量タグ
・名前をつけることができる
ローカルリポジトリで使う使い捨てのようなもの

■注釈付きタグ
・名前を付けられる
・コメントを付けられる
・署名を付けられる
主にリリースように使うタグ