3/31 git part4

# 個人的リマインド用
リベース、タグ、作業を一時避難

## リベース
リベースとは変更を統合する際に、履歴をきれいに整えるために使うのがリベース
```
git rebase <ブランチ名>
ブランチの起点となるコミットを別のコミットに移動
```
流れイメージ
コミット1→コミット3(sub)
        →コミット2(master)
subにmasterブランチの内容を取り込みたい(ここでgit rebase master(subブランチにいる時))
そうするとコミット3がコミット3'になりコミット2の後ろに行く(親がコミット2に)
mergeと違う点はコミットが一直線になる(履歴をきれいに)
またこの時masterブランチはコミット2なので
git checkout masterからgit merge subでコミット3'にmasterブランチが移動

**リベースとマージの違い**
リベースは履歴が一直線、マージは履歴が枝分かれ

### リベースでしてはいけないこと
**GitHubにプッシュしたコミットをリベースするのはNG**
リベースで親コミットが変わるとpushできない

**特にgit push -f(force)は絶対にNG→履歴が完全に壊れる**

### リベースとマージどちらがいいか
正直考え方次第

**マージ(作業の履歴を残したい時)**
メリット：コンフリクトの解決が比較的簡単
デメリット：マージコミットがたくさんあると履歴が複雑化する
**リベース(履歴をきれいに保ちたい時)**
メリット：履歴をきれいに保つことができる
デメリット：コンフリクトの解決が若干面倒(コミットそれぞれに解消が必要)

→プッシュしていないローカルの変更にはリベースを使い、プッシュした後はマージを使う。コンフリクトしそうならマージを使う
### プルのマージ型とリベース型
**プルのマージ型**
```
git pull <リモート名> <ブランチ名>
git pull origin master マージコミットが残るから、マージした記録を残したい時に使う
```
**プルのリベース型**
```
git pull --rebase <リモート名> <ブランチ名>
git pull --rebase origin main マージコミットが残らないから、GitHubの内容を取得したい時だけ使う
```
デフォルトでリバース型にする
```
git config --global pull.rebase true

masterブランチでgit pullする時だけ
git config branch.master.rebase true
```
### コミットをきれいに整えてからPushしたい
履歴を書き換えろ
※GitHubにPushしていないコミット

**直前のコミットをやり直す**
```
git commit --amend
```
**複数のコミットをやり直す**
```
git rebase -i <コミットID> -iは--interactiveの略
git rebase -i HEAD~3 対話的リベースで、やりとりしながら履歴を変更する

pick ~~~~ ヘッダー修正
pick ~~~~ ファイル追加
pick ~~~~ README修正
```
```
やり直したいcommitをeditにする
edit ~~~~ ヘッダー修正
pick ~~~~ ファイル追加
pick ~~~~ README修正

やり直したら実行する
git commit --amend

次のコミットへ進む(リベース完了)
git rebase --continue
```
HEAD~
一番目の親を指定する。
HEADを基点にして数値分の親コミットまで指定する。

HEAD^
マージした場合の2番目の親を指定する。

HEAD~1 == HEAD^1 
イメージが掴みにくい場合はudemyを

1.git rebase -iコマンドで対話的リベースモードに入る
2.修正したいコミットをeditにしてコミットエディタを終了する
3.editのコミットのところでコミットの適用が止まる
4.git commit --amendコマンドで修正
5.git rebase --continueで次のコミットへいく
6.pickだとそのままのコミット内容を適用して次へ行く

**コミットを並び替える、削除する**
```
git rebase -i HEAD~3 
git logと違い下が最新

コミット消したい時はその行を消す
並び替えたい時は順番いじる
```
**コミットをまとめる**
```
git rebase -i HEAD~3 

pick ~~~~ ヘッダー修正
squash ~~~~ ファイル追加
squash ~~~~ README修正

squashを指定すると、そのコミットを直前のコミットと1つにする
```
**コミットを分割する**
```
git rebase -i HEAD~3

分割したいとこをeditに変更
pick ~~~~ ヘッダー修正
pick ~~~~ ファイル追加
edit ~~~~ READMEとindex修正

git reset(ステージングしてないとこまで戻す) HEAD^(editにしたとこを指す)
git add README
git commit -m "README修正"
git add index.html
git commit -m "index.html修正"
git rebase --continue
```
## タグ
タグとはコミットをさんしょしやすくするために、分かりやすい名前をつけること。よくリリースポイントに使う。

**タグの一覧を表示する**
```
git tag アルファベット順に全て表示
git tag -l "202302(例)" 202302から始まるものに絞る 
```
**タグを作成する(注釈付きタグ) 基本的にはこっち**
```
git tag -a [タグ名] -m "[メッセージ]"
-aをつけると注釈付きタグを作成。-mオプションをつけるとエディタを立ち上げずにメッセージ入力
```
**タグを作成する(軽量版タグ)**
```
git tag -a [タグ名]

後からタグ付けする
git tag [タグ名] [コミット名]
git tag 20230301_01 8a6cbc4

オプションをつけないと軽量版タグを作成することになる
```
**タグのデータを表示する**
```
git show [タグ名]
```
**タグをリモートリポジトリに送信する**
```
git push [リモート名] [タグ名]
git push origin 20230301_01

タグを一斉に送信する
git push origin --tags
```
### 作業を一時避難
作業を途中でコミットしたくないけど、別のブランチで作業しないといけない。そういう時に作業を一時避難する。

**作業を一時避難する**
```
git stash(隠すという意味)
git stash save

ワークツリーとステージの変更分を一時避難してくれる 
```
**避難した作業を確認する**
```
git stash list
```
**避難した作業を復元する**
```
git stash apply 最新の作業を復元する
git stash apply --index ステージの状況も復元する

特定の作業を復元する
git stash apply [スタッシュ名]
git stash apply stash@{1}←stash listで確認(最新が0 その後1づつ上がっていく)
```
**避難した作業を削除する**
```
最新の作業を削除する
git stash drop

特定の作業を削除する
git stash drop [スタッシュ名]
git stash drop stash@{1}

全作業を削除する
git stash clear
```