Gitと共同開発について



#GIT
GITとはファイルの変更履歴を保存できる。いちいちバックアップを取る必要がなく、削除したファイルなどを確認できる

###GITの導入方法
yum install git-core→インストール
↓
git config→名前や住所を設定できる！

git init→現在の場所に.gitというリポジトリを作る
リポジトリとはファイルの変更履歴を保存できる場所

git initでリポジトリを作る。作る場所は開発アプリのディレクトリ。ちなみリポジトリは.gitとして作られるが見えないようになっているため、ls -aで見つける！

###gitというリポジトリにファイルの変更保存方法
git add ファイル→ファイルを選択
↓
git commit -m '変更内容'→今選択しているファイルに対してコメントをつけてリポジトリに保存

git commitだけだと詳細な変更内容をログメッセージに書かないといけない

###よく使うコマンド
git status→自分がどのファイルを変更したか。どのファイルを選択して、どのファイルを選択していないか知る、変更だけしたものが赤、インデックスに反映したものが緑になる
また今自分がどのブランチにいるか、リモートリポジトリとどれだけ差分があるかを知る

git diff →変更内容が確認できる(詳しくは下に記述)

git log→これまでにどんなcommitがあったかを確認できる -pをつけると差分もみれる

#GITの約束事項
リポジトリの内容を直接変更する事は出来ない。ワークツリーとインデックスという場所的な概念がある。ワークツリーで編集をしてインデックスに反映させて、リポジトリにに保存をする

       
ワークツリー→インデックス→リポジトリ

・git add(ワークツリーからインデックスに反映)
・git commit(インデックスに書かれた内容をからリポジトリに保存)

・git diff→ワークツリーとインデックスの間の差分を確認する
・git diff --cached→インデックスとリポジトリの間の差分を確認する
・git diff HEAD→ワークツリーからリポジトリの間の差分を確認する
参考文献は[忘れやすい人のための git diff チートシート](https://qiita.com/shibukk/items/8c9362a5bd399b9c56be)

ワークツリーでの操作間違えを元に戻す
・git checkout HEAD→ファイルの編集や削除を元に戻す、またインデックスの反映を全てサラになる

コミットを取り消したいとき
・git revert 取り消したいコミット名

・git rm 削除ファイル名→削除したファイルを選択
↓
・git commitで削除記録を保存

・git rm 既存ファイル名→既存のファイルの変更履歴をGITから消す！そしてファイルも消える！？


#ブランチとは
リポジトリから出ている枝。

枝を複数作り、最終的に一つにする事が開発する上での基本。親枝の名前はmaster
↓
ではなぜ枝を複数つくってから統合するような開発方法なのか
それは一つのブランチで編集していてミスったときに変更しにくいから。ブランチを新しく作ってそっちを下書きとしてから編集して、うまくいってから統合した方が怖くない！

HEADとは今チェックアウトされている枝の最新状態を表す

#####branch
git branch ブランチ名→新しいブランチを作る

#####checkout
git checkout ブランチ名→現在のブランチから指定したブランチに移動。

git checkoutはブランチへの移動だけと考えていたが、そうではない。

・git checkout ブランチ→そのブランチの最新状態(一番最後にcommitされた状態)に移動するということ。

・git checkout -b 枝名→新しい枝を作って、そちらに移動する

・git checkout　ファイル名→そのファイルの変更内容を取り消す。これはgit addでインデックスに上げる前にのみ実行可能

・git checkout HEAD --ファイル名→インデックスに挙げられてしまっているファイルの状態を最後にコミットした状態に戻し、編集したことも無かったことにする

・git checkout コミットid ファイルパス→そのファイルのみ選択したコミット状態の時の内容に戻す。

参考文献は[[git] 戻したい時よく使っているコマンドまとめ](https://qiita.com/rch1223/items/9377446c3d010d91399b)


#####merge
git merge ブランチ名→現在のブランチに指定したブランチを統合する
↓
git branch -d ブランチ名→統合されれば、されたブランチは不要になるのでこれで消す。-Dは強制削除

注意
mergeとcommitを間違えやすい
commitは編集内容を履歴として保存しているだけ。一つのブランチ内で起きる事。
mergeはブランチとブランチの結合。開発の基本。ブランチとブランチの間で起こる事。mergeの方が大きな単位


注意
mergeする時に二つのユーザーが互いに同じ場所を変更して、統合させる時conflictと出る

#リポジトリのバックアップを取る方法

git --bare init→リポジトリのバックアップ作成

git remote add バックアップの名前 バックアップの場所→バックアップリポジトリに名前をつける、基本originとする

#二人以上で作業をする時
自分のリポジトリを相手に反映させたり、逆をしたりしないといけない！！

git clone 複製リポジトリ名→ リポジトリの複製コピー

git push 送信先リポ 送信元ブランチ名
→ローカルのブランチを送信先リポに追加する。git push origin masterは非常に危険。ここでのmasterはローカルのもの。最初から本番のmasterを塗り替えることになるため危険。

git push -f→強制的にリモートリポジトリの内容をローカルリポジトリの内容と同じにする。リモートリポジトリの内容がA→B→Cでも
ローカルリポジトリの内容がA→D→Eならば強制的にそちらの内容に変更する。慎重に使うべきコマンド。

git pull リポジトリ名 ブランチ名→指定したリポのブランチを自分のブランチに反映させる


git rebase ブランチ→指定したブランチを最新の状態にして、その状態のその指定したブランチにに今自分がいるブランチの変更を追加していく。
詳しくは[git rebaseを初めて使った際のまとめ](https://qiita.com/310ma3/items/e0ec74b47c6c219f2a8b)

通常開発をしている自分のブランチがmasterに変更される前にmasterの内容が書き変わっていることがある。その状態でgit push -fで強制変更をすると別の人のブランチのpushが無かったことになる
↓
それをなくすために
1. git fetchで最新のリモートリポジトリーの状態を得て
2. git rebase
3. git push
することで的確にpushできる。
詳しくは[現場で使える Ruby on Rails 5速習実践ガイド ](https://www.amazon.co.jp/%E7%8F%BE%E5%A0%B4%E3%81%A7%E4%BD%BF%E3%81%88%E3%82%8B-Ruby-Rails-5%E9%80%9F%E7%BF%92%E5%AE%9F%E8%B7%B5%E3%82%AC%E3%82%A4%E3%83%89-%E5%A4%A7%E5%A0%B4%E5%AF%A7%E5%AD%90/dp/4839962227)

#GIThubとは
GIThubでは自分のリモートリポジトリをオンライン上におけるサービス。そのため複数開発や人が使っているコードを見る事が出来る

手順
GIThubにローカルリポジトリの入ったディレクトリ名で、リモートリポジトリを作る
↓
その場所に対してorignという名前をつける
git remote add
↓
ターミナルでローカルリポジトリの入ったディレクトリからorignに対してpushする！
しかしpush(githubにアクセスするにはその権限が無いといけない、githubを登録するだけではダメ)。だからHTTPSでアクセスするならばGitHub登録のメアド、passを入力しないといけない。またsshでアクセスするならばローカルで鍵を作成して、鍵の登録をGitHubで行わないといけない。

#実際の開発の流れ

<img width="468" alt="スクリーンショット.jpeg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510817/dc2bd9c3-f291-e5d0-5869-71195a63aea3.jpeg">


ローカルでmasterとは別のブランチAを作る
↓
その中で作業をする、完了すればgit commitで変更内容を保存する
↓
リモートリポジトリであるGitHubにpushをする
↓
プルリクエスト(GitHub上でブランチAをmasterにmergeしたいという申請)を上長に送る。
↓
コードレビューをして申請が大丈夫ならば上長がmergeする

#プルリクをレビューする時
プルリクレビューするときは、git fetch --allでリモートの状態だけを取ってくる。つまり自分のローカルのブランチには影響を及ぼさない(fetch自分の机の周りに荷物を置くイメージ)。
⬇️
そのあと
git checkout 目的のブランチで、作業するブランチを目的のブランチに変える(別の机に置かれた荷物をいじるために机を変えるイメージ)。

#補足、その他開発できをつけること
#####コードレビュー
コードレビューをする際はRubocopやSiderという自動コードレビューをするツールを使うと良い。

#####CIツールとGitHub
コードレビューの前後のタイミングでCIツールを使った自動テストを行うことがある。
CIツールとGitHubを連携させることでPull Requestが自動テストを通っているかを見ることができるため、問題のある部分に気づかないままmergeすることを防ぐ。

#####migrationファイル
migrationファイルの記述にミスをすると、ロールバックした時にエラーが発生してしまう。→rails dbmigrate:redoで自分の書いたマイグレーションファイルがロールバックする際にトラブルをおこなさない事を確認する。詳しくは[現場で使える Ruby on Rails 5速習実践ガイド ](https://www.amazon.co.jp/%E7%8F%BE%E5%A0%B4%E3%81%A7%E4%BD%BF%E3%81%88%E3%82%8B-Ruby-Rails-5%E9%80%9F%E7%BF%92%E5%AE%9F%E8%B7%B5%E3%82%AC%E3%82%A4%E3%83%89-%E5%A4%A7%E5%A0%B4%E5%AF%A7%E5%AD%90/dp/4839962227)
migrationファイルはデータベースの歴史なので大切だが数が多くなると管理できなくなるので、Squasherというgemを使って複数のマイグレーションファイルを一つに集約させたりする

またマイグレーションファイルにモデルのメソッドを記述するのは危険。モデルのメソッドは不変ではなく、将来的に新たな制限をq加えたりする可能性があるから。詳しい対処法は[現場で使える Ruby on Rails 5速習実践ガイド ](https://www.amazon.co.jp/%E7%8F%BE%E5%A0%B4%E3%81%A7%E4%BD%BF%E3%81%88%E3%82%8B-Ruby-Rails-5%E9%80%9F%E7%BF%92%E5%AE%9F%E8%B7%B5%E3%82%AC%E3%82%A4%E3%83%89-%E5%A4%A7%E5%A0%B4%E5%AF%A7%E5%AD%90/dp/4839962227)のP384