Gitコマンドリファレンス　～基本から応用まで～

#はじめに
Gitコマンドを中心とした自分用コマンドリファレンスです。
ご参考までに。

#基礎知識

##エリア
作業エリア（いわゆるローカル作業中のもの）
　↓
ステージングエリア（コミット待ちのエリア、作業エリアで完了したものを一度あげる場所）
　↓
コミット履歴（コミット済みのもの）

＜図を作ってみました＞
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/494282/346ba70a-1a7d-329c-5243-242d8c807e81.png)


##HEAD
現在、自分が参照しているブランチ/コミットのポインタ。
常に最新のコミットを参照しているわけではなく、任意の履歴を参照することもできる。
この状態は頭を切り離した状態（HEAD detached）となる。

##SHA1 ID
コミットごとに付与される一意のID。
このIDを指定することで、各種操作が可能となる。
ブランチ名やタグ名、"HEAD"などの指定で置き換えることもできる。

##クリーンマージ
ブランチをマージする際に、競合がなく自動的にマージできるもの。
ファストフォワード（fast-forward）として扱われる。

##Windows Git GUI セットアップ
http://sutara79.hatenablog.com/entry/2015/07/06/113431




#Gitコマンド

## 導入操作編
```sh
# 使い方の確認
git       # ヘルプを表示
git help  # ヘルプを表示
git help -a   #全コマンドリスト
git help [コマンド名]    #指定コマンド名の使い方
git [コマンド名] --help  #指定コマンド名の使い方

# Gitのバージョン確認
git --version

# ファイルリストの表示
git ls-files

# ファイルの詳細確認 [Q]で中止
git blame [ファイル名]
git blame README.md    #例
git blame [ブランチ名] [ファイル名]
git blame master README.md  #例

# コミット履歴 [Q]で中止
git log --oneline                #履歴を1行ずつ表示
git log --shortstat --oneline    #上記に加え、短いステータスを表示
```

## 設定編
```sh
# ユーザー情報設定
git config --global user.name "Your Name"
git config --global user.email "hoge@hoge"

# ユーザー情報確認
git config --global user.name
git config --global user.email
git config --list   # 全設定を表示

# 設定の削除方法
git config --global --unset [Key名]
```

# 共通操作編（Gitに限らず）
```sh
# CurrentDirectoryの確認
pwd

# ファイルリスト表示
ls

# ディレクトリ作成
mkdir [ディレクトリ名]

# ディレクトリ移動
cd [ディレクトリ名]

# ファイル/ディレクトリ削除
rm -r [ディレクトリ名]

# 履歴の表示
history 
```

# リポジトリ作成、登録
```sh
# リポジトリ作成
git init

# ステータス確認、リポジトリの状態を見る
git status

# ファイルをリポジトリに追加
git add [ファイル名]

# コミットする
git commit -m "メッセージ"

# コミット情報を確認する
git log
git log --stat  #コミットを構成しているファイルを見る

# ファイル追加とコミットを同時に行う
# 対象となるのは、既にGitが認識済み（add済み）のファイルに限られる
git commit -a -m "メッセージ"

# ディレクトリ単位でadd（作業エリア→ステージングエリア）する
git add --dry-run .  # 実行時のシミュレーション
git add .

#ファイルを確認する
git ls-tree HEAD
```

#Git GUI 関連
```sh
#git GUI 起動
git gui
git citool

#git log viewer 起動
gitk
```

#リポジトリ比較
```sh
#作業エリアとステージングエリアの差分比較
git diff

#ステージングエリアとコミット履歴の差分比較
git diff --staged
```

#ファイルの削除
```sh
#作業エリアで削除したファイルを、ステージングエリアから削除する
#作業エリアにファイルが残っていたとしても、以下のコマンド実行により作業エリアからも削除される
git rm [ファイル名]
```

#ファイル名の変更
エクスプローラでファイル名を直接変更すると、以下の２つの操作として扱われる。

+ 旧ファイル名のファイル削除
+ 新ファイル名のファイル追加

```sh
#Gitにファイル名変更として認識させる、
#合わせて作業エリアのファイル名も変更される
git mv [old_file_name] [new_file_name]
```

#ファイル内の一部のみリポジトリに反映したい場合
+ Git GUI の Unstaged Changes でファイル選択
+ 差分表示の反映したい行で右クリック
+ Stage Line For Commit を選択
+ Staged Changes に選択した選択した部分だけ反映される

※git add -p の後 e を選択することで、viエディタによるマニュアル操作も可能だが、難しいので割愛。

#ファイルを元に戻す
```sh
#ステージングエリアの変更を削除（unstagedにする）
git reset [file_name]

#コミット履歴のファイルを作業エリアに反映する
#コミット済みファイルで作業エリアのファイルを上書きする
git checkout -- [file_name]
```

#履歴を確認する
```sh
#親子関係を確認する
git log --parents

#親子関係を確認する（短縮表示）
git log --parents --abbrev-commit

#直近のログ１件だけを表示する
git log -1

#GUIで確認する
gitk

#その他のコマンド
git log --oneline    # 簡略表示
git log --patch      # パッチビュー
git log --stat       # コミットファイルの変化
git log --patch-with-stat      # 上記２つを結合したもの
git log --oneline [file_name]  # ファイル指定
```

#コミット時のコメントを変更する
```sh
#直近のコミットのコメントを修正する
git commit --amend
```

#ブランチ関連
```sh
#SHA1 ID 参照
git rev-parse HEAD
git rev-parse master
git log --oneline

#ブランチの先端のSHA1参照
git branch -v

#チェックアウト（ファイル取得、HEAD切り替え）
git checkout [SHA1_ID]
git checkout [tag_name]

#HEADをmasterに戻す
git checkout master

#変更を破棄してmasterに戻す
git checkout -f master

#ブランチを確認する
git branch
#全ブランチを確認する
git branch --all
#ブランチを確認する（ツリー表示あり）
git log --graph --decorate --pretty=oneline --all --abbrev-commit

#ブランチを作る
git branch [new_branch_name]

#ブランチの途中（SHA1_ID指定）から新たなブランチを作る
git branch [new_branch_name] [SHA1_ID]

#ブランチを作って即座にチェックアウトする
git checkout -b [new_branch_name] [start_branch_name]

#ブランチを削除する
git branch -d [branch_name]    #削除時のSHA1_IDが表示される

#削除したブランチを復旧させる
git checkout -b [new_branch_name] [SHA1_ID of deleted branch]

#ブランチを切り替えた記録を参照する
git reflog
```

##ブランチ切り替え時に作業エリアを退避させる
```sh
#作業エリアの作業中ファイルをスタッシュに退避（コミット）させる
#WIP : Work In Progress
git stash

#スタッシュのリストを見る
git stash list

#スタッシュを作業エリアに戻す（ポップする）
git stash pop
```

###スタッシュのポップを異なるブランチでポップするとどうなる？
マージされてしまうので、操作は注意が必要。

###gitkでブランチ参照
View > New view > All(local)branches ...check


##ブランチをマージする
```sh
#ブランチ間の差分を確認する
git diff [base_branch_name]...[branch_name]

#ステータスと名前の差分だけを表示する
#ステータス  A:added, C:copied, D:deleted, M:modified, R:renamed
git diff --name-status [base_branch_name]...[branch_name]

#マージする
#マージ後に残したいブランチ（親ブランチ）をチェックアウトしてから実行
git merge [merged_branch_name]

#マージを中止する（もとに戻す）
git merge --abort
```


#タグ関連
```sh
#タグをつける
git tag [tag_name] -m "comment" [SHA1_ID]

#タグの内容を表示する
git show [tag_name]

#タグを削除する
git tag -d [tag_name]
```

#クローン
```sh
#リポジトリを複製（クローン）する
git clone [original_branch] [cloned_branch]

#クローンしていない他のブランチを取得する
git checkout [original_branch2]
git checkout -b [original_branch2]remotes/origin/[original_branch2]  #こちらと同義
```

##ベアリポジトリ
+ 作業エリアを持たないリポジトリ。
+ clone, push, pull が基本操作となる。

```sh
#ベアリポジトリの作成
git clone --bare [original_repository] [cloned_bare_repository]
```

#リモート関連
```sh
#リモートリポジトリの確認
git remote          #リモートの名前だけの確認
git remote -v show  #リモートの確認
git remote -v show [remote_name]  #対象リモートの詳細確認

#リモートの名前変更（origin -> new_name）
git remote rename origin [new_name]

#追跡リポジトリの追加
git remote add [new_remote_name] [repository_path]

#リモートリポジトリの調査
git ls-remote
git ls-remote [remote_name]

#リモートの追跡先（参照先）にプッシュする
git push [remote_name] [pushed_branch_name]


####
####ブランチ操作
####

#作業エリアで作った新しいブランチをプッシュする
git push --set-upstream [remote_name] [new_branche_name]

#ブランチを削除し、リモートに反映する
git branch -d [branch_name]
git push [remote_name] :[branche_name]


####
####タグ操作
####

#タグをプッシュする
git push [remote_name] [tag_name]

#タグを削除する
git push [remote_name] :[tag_name]
```

##【ユースケース】コミット履歴（リモートリポジトリ）との差分比較
```sh
#作業エリアの最新（HEAD）とリモートリポジトリを比較する
git diff HEAD..orgin/master
```

diffについてはこちらを見たほうが早い。
　■忘れやすい人のための git diff チートシート
　　https://qiita.com/shibukk/items/8c9362a5bd399b9c56be

##リモートからのマージ
```sh
#プルする：フェッチとマージが実行される
git pull

#プルする：fast-forwardに限定する（競合がある場合にオートマージしない）
git pull --ff-only
#これをデフォルト設定にしたい場合
git config  pull.ff only

#フェッチする
git fetch

#FETCH_HEADを確認する
#fetch結果（FETCH_HAED）とローカル作業エリア（HEAD）に差分がある場合、異なるSHA1_IDが表示される
git rev-parse FETCH_HEAD
git rev-parse origin/master
git diff HEAD..FETCH_HEAD

#マージする
git merge FETCH_HEAD
```

###git pull の危険性
pullはfetchとmergeを同時に行うため、初心者は混乱しやすい。
何が変更されているかを確認しながら進めるには、fetchとmergeを利用した方がよい。

```sh
#まずはリモートの変更を取り込む（フェッチする）
git fetch

#ローカル作業エリア（HEAD）とフェッチ結果（FETCH＿HEAD）の差分を確認する
git diff HEAD FETCH_HEAD

#マージを行う
git merge FETCH_HEAD
```

###【ユースケース】git pullでコンフリクトが発生した場合
```sh
#以下のメッセージが出たら
error: Your local changes to the following files would be overwritten by merge:
    [directory/file]
Please, commit your changes or stash them before you can merge.

##スタッシュ（変更分を退避）してからプルして、スタッシュをポップ（元に戻す）する##
#スタッシュ
git stash

#スタッシュのリストを確認
git stash list

#プルする
git pull

#スタッシュを作業エリアに戻す（ポップする）
git stash pop

#スタッシュリストがなくなっていることを確認
git stash list
```

#log関連
[Git log関連コマンドリファレンス](https://qiita.com/ksj555/items/ed6d56de448b425169d1)

#rebase
```sh
#rebaseしたいブランチ上で以下のコマンド
git rebase [target_branch_name]
git rebase master
```

##rebase後に元の状態に戻す
```sh
#HEADの履歴を追う
git reflog

#もとの状態に戻す
#  HEAD@{4}に戻したい場合
git reset --hard HEAD@{4}
```

##rebaseにより履歴をマージする
guiでは面倒なのでSourceTreeなどを使った方がよよさそう。
https://qiita.com/ryounagaoka/items/7c129e98a7f81c507a61

#config関連
```sh
#helpを見る
git config --help
```

##構成の優先順位
+ local < global < system
+ localはリポジトリ固有の構成。
+ globalはユーザー設定と同等。
+ systemはユーザーをまたいだスコープとなる。

##configの確認
```sh
#構成レベルごとの確認
git config --local --list
git config --global --list
git config --system --list

#出力例
branch.master.remote=github
## branch : セクション
## master : サブセクション（なし、あるいは複数ありの場合もある）
## remote : キー
```