Gitを触ってみたらやることが多すぎた

未来電子テクノロジーでインターンをしているtokky08です。
Git/GitHubについて勉強したのでアウトプットとして書いていきます。

プログラミング初心者であるため、内容に誤りがあるかもしれません。
もし、誤りがあれば修正するのでどんどん指摘してください。


#Gitって何をするの？
ファイルのバージョンを管理するためにある！

・最新のファイルがどれか分からなくなったり。
・気づかずに上書きしてしまったりする。

こういうことを防止するためにgitがある！

#GitHubってGitと何が違うの？
GitHubとは、gitリポジトリのホスティングサービス。
gitでのファイルの変更・変更履歴をオンライン上で扱ってくれるサービス！

#ローカルで大事な３要素！
**ワークツリー**
手元でファイルを変更する作業場

**ステージ**
コミットする変更を準備する場 
= 記録したい変更だけステージに追加してコミットしていく。一部の変更だけ記録したいときのためにステージが存在している。

**リポジトリ**
スナップショットを記録する場


#作業の流れ
ローカルでスナップショットを記録 → GitHub（リモートリポジトリ）へアップ


#コマンド集

|コマンド|意味|
|:---:|:--:|
|git init|.gitディレクトリが作成されリポジトリが生成される。このディレクトリの中にgitで必要なほとんどのファイルが含まれる|
|git clone リポジトリ名|GitHubから.gitディレクトリとファイルをローカルにコピーする。githubにアクセスしてURLをコピペ。|
|git status|ワークツリーとステージの間で変更されたファイルとリポジトリとステージの間で変更されたファイルを表示する|
|git diff |ワークツリーとステージの間で変更されたファイルの変更差分を表示する|
|git diff --staged |リポジトリとステージの間で変更されたファイルの変更差分を表示する|
|git log |変更履歴を確認する|
|git rm ファイル名|ファイルの削除を記録する。ワークツリーとリポジトリどちらのファイルも削除する|
|git rm -r ディレクトリ名|ディレクトリの削除を記録する。ワークツリーとリポジトリどちらのディレクトリも削除する|
|git rm --cached ファイル名|ワークツリーのファイルは残して、リポジトリにあるファイルだけを削除する|
|git mv 旧ファイル 新ファイル|ファイルの移動を記録する。ファイル名の変更。ワークツリーとステージにあるファイル名をまとめて変更|
|git remote add origin URL(リモートリポジトリ)|リモートリポジトリ（GitHub）を新規追加する。originは任意の名前でOK。|
|git push origin master|リモートリポジトリへ送信する|
|git checkout -- ファイル名|ファイルの変更を取り消す|
|git checkout -- ディレクトリ名|ディレクトリの変更を取り消す|
|git checkout -- .|現在いるディレクトリ以下の変更を全て取り消す|
|git reset HEAD ファイル名|ステージしたファイルの変更を取り消す。ステージをなかったことにする。|
|git reset HEAD ディレクトリ名|ステージしたディレクトリの変更を取り消す。ステージをなかったことにする。|
|git reset HEAD .|先ほどステージしたもの全部をステージしなかったことにする 。|
|git commit --amend|さっきやったコミットをやり直します。ただし、pushしたコミットはやり直したらだめ！|
|git remote -v|登録しているリモートリポジトリ名とURLを表示する|
|git fetch リモート名|リモートリポジトリの内容をローカルリポジトリに落とす|
|git merge リモート名/ブランチ名|ローカルリポジトリの内容をブランチのワークツリーに統合する|
|git pull リモート名 ブランチ名|リモートリポジトリの内容をローカルリポジトリに落として、ローカルリポジトリの内容をワークツリーに統合する。* 現在いるブランチに統合されるので気を付ける！|
|git remote show リモート名|リモートの詳細情報を表示する|
|git remote rename 旧リモート名 新リモート名|リモート名の変更|
|git remote rm リモート名|リモートを削除する|
|git branch ブランチ名|ブランチを作成する。ブランチの切り替えまでは行わない。|
|git branch|ブランチの一覧表示|
|git branch -a|リモートリポジトリも表示|
|git checkout 既存ブランチ名|ブランチを切り替える|
|git checkout -b 新ブランチ名|ブランチの作成と切り替えを一度にしてくれる|
|git merge リモート名/ブランチ名|他の人の変更内容を取り込む|
|git branch -m 新ブランチ名|現在いるブランチの名前を変更する|
|git branch -d ブランチ名|ブランチを削除する。masterにmergeされていない変更が残っているブランチは削除しない。|
|git branch -D ブランチ名|ブランチを強制削除する|
|git tag|tagの一覧を表示する|
|git tag -a タグ名 -m “メッセージ”|注釈付きタグをつける。リリース時につける|
|git tag -a タグ名 コミット名 -m “メッセージ”|後からタグをつける|
|git show タグ名|タグの詳細を表示する|
|git push リモート名 タグ名|タグをリモートリポジトリに送信する|
|git push origin --tags|ローカルにあってリモートリポジトリに存在しないタグを一斉に送信する|
|git stash|作業を一次避難する。stashに避難させることで、ワークツリーとステージの変更をなかったことにする。|
|git stash list|避難した作業の一覧を表示する|
|git stash apply|最新の作業を復元する|
|git stash apply --index|ステージの状況も復元する|
|git stash apply スタッシュ名|特定の作業を復元する|
|git stash drop|最新の作業を削除する|
|git stash drop スタッシュ名|特定の作業を削除する|
|git stash clear|全作業を削除する|


#3種類のマージ
・Fast Foward：ブランチが枝分かれしてなかったときはブランチのポインタを前に進めるだけ
・Auto Merge：枝分かれして開発していた場合、マージコミットという新しいコミットを作る
・コンフリクト：同じファイルの同じ行に対して複数人が異なる編集を行ったときに生じる

#コンフリクト防ぐには
・複数人で同じファイルを変更しない
・pullやmergeする前に変更中の状態を無くしておく（commitやstashをしておく）
・pullするときは、pullするブランチに移動してからpullする
・コンフリクトしても慌てない

#マージかリベースどっちを使うべきか？
作業の履歴を残したいならマージ
履歴をきれいにしたいならリベース

プッシュしていないローカルの変更にはリベースを使い、プッシュした後はマージを使う。コンフリクトしそうならマージを使う。

#複数のコミットをやり直す
rebase -i コマンドの一連の流れ
・`git rebase -i HEAD~数字` コマンドで対話的リベースモードに入る
・修正したいコミットを`edit`にしてコミットエディタを終了する
・`edit`のコミットのところでコミットの適用が止まる
・`git commit --amend`コマンドで修正
・`git rebase --continue`で次のコミットへ行く
・`pick`だとそのままのコミット内容を適用して次へ行く


#まとめ
Git/Githubを勉強するにあたって色々覚えることが多いなという印象です。実際に使っていくことで覚えていきたいですね。特に、プルリクエストなどは共同開発しなければ使わないと思うのでいざ使う時が訪れても慌てずに対処できるように流れを確認しておくべきだなと思いました。定期的に復習しようと思います。