備忘録：Git

何となくやっていたことを再度学習して内容をまとめる。

# コミットとブランチ

![スクリーンショット 2022-12-16 13.04.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523652/d3e1c1ed-0df3-6a29-516a-ca88e14b8656.png)

コミットは前のコミットをポインタとしている。ブランチはコミットを指しているポインタ。HEADは今いる場所で通常はブランチを指している。HEADがブランチを指していないと```Detached HEAD```状態となる。この場合は新規にブランチを作成する必要がある。

# 用語

|用語|説明|
|:---:|:---|
|HEAD|自分が今いる場所|
|.gitignore|無視リスト（Gitに追跡されない）|
|origin|リモートリポジトリのアクセス先に設定されるデフォルトの名前|
|checkout|任意のコミットへ自分を移動、ブランチを移動する時にも使用（HEADの位置を動かしているだけ）|
|fork|他人が公開しているリモートリポジトリを自分のアカウントにクラウド上でコピー|
|clone|リモートリポジトリを自分のパソコンの中にコピー|
|branch|ポインタ（ポインタとは今ココを示すもの）|
|merge|ブランチを統合|
|push|リモートリポジトリにアップロード|
|pull|リモートリポジトリから変更をダウンロードしてローカルリポジトリに反映（フェッチ＋マージ）|
|revert|反対の内容で新規コミットを作成して過去の変更を打ち消す|
|rebase|もともとのコミットが改変されて、リベース先のブランチに載っかかり、履歴が一直線になる（既にリモートリポジトリ上に存在するコミットはリベースしない）|
|squash|コミットを1つにまとめる（インタラクティブリベースモードでスカッシュする）（既にリモートリポジトリ上に存在するコミットはスカッシュしない）|
|fetch|リモートブランチをリモート追跡ブランチにダウンロード|
|prune|不要なリモート追跡ブランチを削除|
|stash|未コミットのファイルを一時的に退避|
|cherry-pick|特定のコミットを今いるブランチ上にコピー|
|reset|特定の時点までコミットを戻す（オプションでステージ、作業ファイルも戻す）|
|reflog|HEADの動きの履歴（自分の操作履歴）|
|grep|Gitリポジトリ内だけ検索出来る|

# コマンド

## init
```bash
git init # ローカルリポジトリ作成
```

## commit
```bash
git commit -m "message"
git commit --amend # 直近のコミットメッセージを修正（viが起動する）
```

## checkout
```bash
git checkout コミットID # 指定時点のデータを作業ディレクトリにロード
git checkout ブランチ名 # 指定したブランチに移動
git checkout -b ブランチ名 # ブランチを作成して作成したブランチに移動
git checkout -f ブランチ名　 # ブランチを強制的に切り替える（コミットしていない作業データは消える）
```

## branch
```bash
git branch # 存在するブランチ一覧を表示
git branch ブランチ名 # 現在のブランチを元に新規ブランチ作成
git branch ブランチ名 コミットID # 任意のコミットIDを指定して新規にブランチ作成
git branch -D ブランチ名 # プッシュ、マージされていないブランチを強制的に削除
```

## merge
```bash
git checkout ブランチA　 # マージコミットを作成したいブランチAに移動
git merge ブランチB　 # マージしたいブランチBを指定してマージ
git merge --abort # コンフリクトが多く修正が難しい際、コミット前ならキャンセル可能
```
abortした場合は最新のコミットから新たにブランチを作成して、追加したいコードを追加

## push
```bash
git push リモートリポジトリ名　ブランチ名 # ローカルリポジトリの変更をリモートリポジトリにプッシュ
git push origin main # Example
```

## pull
```bash
git checkout ブランチ名 # プルしてきたいブランチにチェックアウト
git pull リモートリポジトリ名　ブランチ名
git checkout main # Example
git pull origin main # Example
```

## revert
```bash
git revert コミットID # コミットIDを指定してリバート
```

## rebase
```bash
git checkout ブランチ名 # リベースしたいブランチに移動
git rebase main # リベース先のブランチを指定
```

## fetch＋merge（pull）
```bash
git checkout main # mainブランチに移動
git fetch # リモートブランチをリモート追跡ブランチ上にダウンロード
git merge origin/main # リモート追跡ブランチをローカルブランチにマージ
```

## prune
```bash
git branch -a # 全てのブランチを確認（リモート追跡ブランチを含む）
git fetch --prune # リモートリポジトリで消えた追跡ブランチを削除
git branch -d ブランチ名 # 任意のローカルブランチを削除
```

## stash
```bash
git stash save # スタッシュを保存
git stash list # 過去に保存したスタッシュのリストを確認
git stash apply # スタッシュリストの一番上の変更を適用
git stash apply stash@{0} # 0番目の変更を適用
git stash drop # スタッシュリストの一番上の変更を捨てる
git stash drop stash@{0} # 0番目の変更を捨てる
git stash pop stash@{0} # applyとdropを同時に行う
```

## cherry-pick
```bash
git cherry-pick コミットID # 任意のコミットIDを今いるブランチの上にコピー（自動的にコミットされる）
git cherry-pick コミットID..コミットID # 複数コミットをコピーする場合
git cherry-pick -n コミットID # コミットしたくない場合
```

## tag
```bash
git tag タグ名 # 新規タグを作成
git push origin タグ名 # タグをリモートリポジトリに共有
git push origin --tags # タグをまとめてリモートリポジトリに共有
git tag -d タグ名 # ローカルリポジトリのタグを削除
git push origin --delete タグ名 # リモートリポジトリのタグを削除
git tag # リポジトリ内に存在するタグを一覧表示
git checkout -b ブランチ名 タグ名 # 過去のタグ名にチェックアウト（新規ブランチ作成）
```

## log
```bash
git log
git log -p # 変更差分確認
git log --graph # グラフィカルに表示
```

## cat-file
```bash
git cat-file -p コミットID # コミットオブジェクトを表示
```

## reset
```bash
git reset --soft コミットID # HEADだけを動かす（コミットだけが消える）
git reset --soft HEAD^ # Example)直前のコミット内容を取消す
git reset --soft HEAD^^ # Example)2つ前のコミット内容を取消す
git reset --soft HEAD~5 # Example)5つ前のコミット内容を取消す
git reset --mixed コミットID # HEADとステージを消す（作業ディレクトリのファイルは消えない）
git reset --mixed HEAD^ # Example)直前のコミット、ステージを取消す
git reset --hard コミットID # HEAD、ステージ、作業ディレクトリのファイルを取消す
git reset --hard HEAD^ # Example)直前のコミット、ステージ、作業ディレクトリを取消す
```

## reflog
```bash
git reflog # 操作履歴を見る
git reset --hard HEAD@{1} # 戻りたい時点を指定する。（例は1つ前）
```

## diff
```bash
git diff 変更前 変更後

git diff 変更前のコミットID..変更後のコミットID # コミット同士の差分

git diff ブランチ名..ブランチ名 # ブランチ同士の差分
git diff main..develop # Example

git fetch origin # 比較前にリモートリポジトリの更新内容取得
git diff HEAD..origin/main # ローカルリポジトリのHEADとリモート追跡ブランチを比較(git pull前に)

git diff origin/main..HEAD # ローカルリポジトリのHEADとリモート追跡ブランチを比較(git push前に)
```

## grep
```bash
git grep "文字列" # 文字列を検索する
git grep -l "文字列" # ファイル名のみ表示
git grep "文字列" コミットID # 指定したコミットIDを検索
git grep "文字列" HEAD^ # 1つ前のコミットを検索
```

## blame
```bash
git blame ファイル名 # いつ誰が変更したか表示
```

## remote
```bash
git remote add "リモートリポジトリ名" "リモートリポジトリのURL" # リモートリポジトリの追加
git remote rm "リモートリポジトリ名" # リモートリポジトリの削除
git remote -v # 登録されているリモートリポジトリ一覧を表示
```

# Config

## グローバル（~/.gitconfig）
全体に反映

### 編集
```bash
git config --global --edit
vi ~/.gitconfig
```
### 設定（例）
```bash
git config --global user.name "username"
git config --global user.email "email@example.com"
```

### エイリアス（例）
```bash
[user]
        name = username
        email = xxxx@example.co.jp
[alias]
        s = status
        b = branch
        c = checkout
        a = add
        l = log
```
## リポジトリ毎（.git/config）
そのリポジトリにみに反映