個人用Git操作まとめ

# はじめに
今まで自分が作成したプログラムやyamlなどをちゃんと管理しようと思い、Gitを勉強中。
よく使用しそうなコマンドなどを備忘として記載しておく。随時更新予定。


# 初期設定
## gitインストール後の初期設定
```bash
git config --global user.name "<name>"
git config --global user.email "<mailaddress>"
git config --global core.editor vim #コミットコメント記載する際に使用するエディタ
git config --global core.ui auto #インデックスハイライトのようになる
git config --global init.defaultBranch "master" #未設定だと最初のコミット時にmasterブランチが作成され、git init時に余計な画面が表示されるのが気になるので設定する
git config --global -l #設定した内容確認
git config --global --unset user.mail "<mailaddress>" #誤って設定した内容を削除
git config --global alias.graphall "log --graph --all --pretty=format:'%C(yellow)%h%Creset -%C(red)%d%Creset %s %C(green)(%cr) %C(bold blue)<%an>%Creset'  --date=relative" #alias設定。git graphallで実行できる。参考：https://qiita.com/crarrry/items/c5964512e21e383b73da
```
※`--global`オプションは`~/.gitconifig`の設定

## git管理したくないファイルを無視
`.gitignore`に無視するファイルを記載し、配置したディレクトリ以下で有効となる。`!`で無視させたくないファイルを指定可能。`.gitignore`も`git add .gitignore; git commit`で管理する。以下記載例
```:.gitignore
a.out
*.out
*.log
!test.log
```




# 基本操作コマンド

## branch
- ブランチ一覧の確認
```bash
git branch -v
git branch -rv #リモート追跡ブランチのみ
git branch -v --all #全てのブランチを確認
```
- ブランチの作成　※ブランチの切り替えはされない
```bash
git branch <branch>
```
- リモート追跡ブランチ(origin/master)の確認
```bash
git branch -rv
```
- 上流ブランチの設定(`git pull`に引数が不要になる）
```bash
git branch -u <trackBranch>
```
- 上流ブランチが設定されているか確認
```bash
git branch -vv
```


## checkout
※Git 2.23（2019/8リリース）以降`git switch`/`git restore`に機能が分割されているらしい
### restore系
- ステージのファイルを作業ツリーに戻す
```bash
git checkout -- <fileName>
```
- コミットのファイルを作業ツリー, ステージに追加。同じファイル名が存在したら上書きされる。HEADの位置は変わらない。
```bash
git checkout <commit> -- <fileName>
```
- HEAD, ステージ, 作業ツリーを指定したコミットにする。切り離されたHEAD状態となる。ブランチを作成しない場合、コミットしても内容はガベージコレクト（自動/手動）で削除される。切り離されたブランチから戻るには`git switch <branch>`を実行する
```bash
git checkout <commit>
```


### switch系
- ブランチの切り替え
```bash
git checkout <branch>
git switch <branch>
```
- ブランチ作成してブランチを切り替える
```bash
git checkout -b <branch>
git switch -c <branch> #-Cとすると同じブランチ名を上書きで作成してしまうので注意
```


## cherry-pick
別ブランチの更新の一部を取り込む
```bash
git cherry-pick <branch>
git cherry-pick <commit> #複数コミットを指定可能
git cherry-pick <commit1>..<commit2> #指定したコミット間の変更を反映
```

## commit
- コミット：1行目summary, 2行目空行, 3行目詳細のようにコミットメッセージを残せる
```bash
git commit -m "summary" -m "detail"
```
- ステージし忘れたファイルや修正漏れした際にHEADのコミット内容を修正できる
```bash
git commit --amend
```


## diff
- 作業ツリーとの差分
```bash
git diff #ステージと作業ツリー
git diff HEAD #HEADと作業ツリー
git diff <commit> #指定コミットと作業ツリー
```
- ステージとHEADの差分
```bash
git diff --staged
```
- その他差分
```bash
git diff <commit1> <commit2> #コミット間の差分
git diff <branch1> <branch2> #ブランチ間の差分
```

## init
- リポジトリ作成
```bash
git init
git init --bare #作業ツリー、ステージを持たない。リモートリポジトリとして使用する際に実行
```

## log
- コミット履歴確認
```bash
git log
git log --oneline #コミットメッセージが1行目だけ表示されるので見やすい
git log --all --graph #all:全ブランチを表示、graph：ブランチが分かりやすく見える
```

## ls-files
- ステージのファイル確認
```bash
git ls-files
git ls-files -s #ファイルのハッシュを確認
```
- Untrackedのファイル一覧を表示
```bash
git ls-files -o
```

## merge
- マージ：現在のブランチに指定したブランチの内容を反映
```bash
git merge <branch>
```
- 早送りマージ　※`fetch`した後に追跡ブランチを指定することでリモートリポジトリの更新をローカルに反映できる。`pull`は同じ手順相当を実施してくれる。
```bash
git merge --ff-only <branch>
```
- 早送りマージさせたくない場合（3方向マージ指定）　※早送りマージするとマージした履歴が残らないため
```bash
git merge --no-ff <branch>
```
- マージの中止　※コンフリクト発生時
```bash
git merge --abort
```


## mv
- ファイル名変更。ステージングまでされる。
```bash
git mv <before> <after>
```

## rebase
挙動としては`cherry-pick`を連続して行われる操作らしい。
- ブランチの根元を移す　※更新履歴を単純化する
```bash
git rebase <branch>
```
- 複数コミットを1コミットにまとめる　※ひとまとめにする1つ前のコミットを指定する事
```bash
git rebase -i <commit>
```
まとめるコミットを指定する画面が開くので、まとめたいコミットの`pick`を`squash`に変更する。  
コミットメッセージが複数ある場合、コミットメッセージを修正する画面も表示される。



## reset
**※オプションにコミットを指定すると最新のHEADが削除されてしまうことがあるので要注意**
- ステージをHEADの状態に合わせる
```bash
git reset #ステージをHEADに合わせる
git reset -- <fileName> #特定ファイルのみHEADに合わせる
```
- 履歴を削除する  
履歴はなるべく削除せず、なるべく`revert`を使用する
```bash
git reset <commit> --hard #HEAD, ステージ, 作業ツリーを指定したコミットの内容にする
git reset <commit> #HEAD, ステージを指定したコミットの内容にする
git reset <commit> --soft #HEADのみ指定したコミットの内容にする
```

## revert
指定したコミットを削除（削除したことがコミットとして残る）
```bash
git revert <commit>
```

## rm
- git管理から削除　※ステージングまでされる
```bash
git rm <fileName>
git rm -r <directoryName>
```
- 作業ツリーにファイルは残すが、git管理（ステージ, HEAD）から削除する
```bash
git rm --cached <fileName>
```

## show
- 指定コミットのファイルの中身を表示する
```bash
git show <commit>:<fileName>
```
- コミット内容の確認
```bash
git show #HEADのコミット内容
git show <commit>
```
-  `ls-files -s`で確認したハッシュ値からファイルの中身を確認する
```bash
git show <fileHash>
```

## status
- 現在の作業ツリー、ステージ、コミット内容全体を確認
```bash
git status
```
- Untrackedのファイル一覧を表示
```bash
git status -u
```

## tag

- 軽量タグの付与
```bash
git tag <tag> #HEADに付与
git tag <tag> <commit>
```
- 注釈タグの付与
```bash
git tag -a <tag> <commit>
```
- タグの削除
```bash
git tag -d <tag>
```

# リモートリポジトリ関係
## clone
リモートリポジトリをローカルにコピー
```bash
git clone <url>
git clone <url> <directory> #ディレクトリを作成してクローン実施
```


## fetch
追跡ブランチの更新（なければ作成）。事前に更新するブランチにcheckoutしておくこと。
```bash
git fetch <remote> <branch>
```


## pull
リモートブランチの状態をローカルブランチに反映する。`fetch`+`merge --ff-only`と同じ動作
上流ブランチ設定(`git branch -u <trackBranch>`)をしている場合引数は不要
```bash
git pull <remote> <branch>
```

## push
リモートリポジトリのブランチ履歴を更新する
- 指定ブランチのみ
```bash
git push <remote> <branch> #コマンド実行後GitHubのユーザ名/パスワード（もしくはアクセストークン）の入力が求められる
```
- 全ブランチをリモートリポジトリに反映する
```bash
git push <remote> --all
```
- すべてのタグをpushする
```bash
git push <remote> --tags
```
- resetした後に強制的にpushする場合
```bash
git push <remote> <branch> -f
```
- push時に上流ブランチを設定(`git pull`に引数が不要になる）
```bash
git push -u <remote> <branch>
```


## remote
リモートリポジトリを使用する初期設定
- リモートの追加　※リモート名はoriginとする慣習あり
```bash
git remote add <remote> <repogitoryURL>
```
- リモートの設定変更
```bash
git remote set-url <remote> <repogitoryURL>
```
- リモートの設定確認
```bash
git remote -v
```
- リモートの詳細情報を見る（追跡ブランチがすでにあるか、リモートに新しいブランチが出来ているかなど確認できる
```bash
git remote show <remote>
```