間違ったgit commit（コミットメッセージ）を修正したい

Qiitaの見出しになってしまうのでコードのコメントアウト#の前に//をつけています。
PSHU後にコミットミスに気がついた
## 直前のコミットメッセージを修正したい


```swift:コミットメッセージを間違えてpush
% git add .
% git commit -m "#8 課題1 マジックナンバーを修正"
% git push origin main
// コミットメッセージを間違えていた！時を遡りたい...
```
### 直前のメッセージを上書き
% git commit --amend -m "修正コミット内容"

```swift:直前のコミットメッセージを上書きする
------------------------------------------------------
% git commit --amend -m "#10 課題2 マジックナンバーを修正" 
// 直前のコミットメッセージが更新された！                              
------------------------------------------------------
% git status
// 変更内容の確認１
% git log
// 変更内容の確認２　確認したらqを押すともどる
```
### 強制pushで更新
```swift:冷静に強制プッシュ
// 万が一テンパってローカルに更新内容があったりすると以下のように怒られる
 % git push origin main
To github.com:hogehogeStady/Lesson_ymp-a.git
 ! [rejected]        main -> main (non-fast-forward)
error: failed to push some refs to 'github.com:hogehogeStady/Lesson_ymp-a.git'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. Integrate the remote changes (e.g.
hint: 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
--------------------------------------------------------
% git push -f origin main
// 私は冷静に強制プッシュします（ローカルの内容をリモートリポジトリへ反映）
--------------------------------------------------------
```
## コミットの不足内容を発見したとき
- コミット後に追加で修正を行った
- git addし忘れたファイルがあった
- 一時コミットを残したくない

### コミットメッセージはそのままコミット内容を追加
% git commit --amend --no-edit
```swift:コミットの不足内容を発見
% git add .           
% git commit -m "#12 コレクション型 課題1 変数名 をisNextButtonに変更"
[main b3e4afe] #12 コレクション型 課題1 変数名をisNextButtonに変更
 1 file changed, 5 insertions(+), 5 deletions(-)
% git status // 不足内容を発見した
```
```swift:コミット内容を追加
% git add .                    // 不足内容を追加する
% git commit --amend --no-edit // メッセージそのままコミット内容追加
% git log                      // メッセージの確認
```

## いくつか前のコミットメッセージを修正したい
参考：[Git：過去のコミットコメントを修正する方法](https://www-creators.com/archives/5238#git_rebase_-i)
- 「git log --oneline」などでコミット履歴を一覧し、適切なコミット識別子（SHA-1）を見つけます（修正する一つ前のコミット識別子）を確認
- エディタ内でコミット名を編集
- git push -f origin リポジトリ名

### 「git log --oneline」でコミット履歴を一覧
```swift:コミット履歴を参照する
% git log --oneline  
cb1def2 (HEAD -> main, origin/main, origin/HEAD) #6 タプル型 課題2 条件4 関数1 numbersCheck実装
bef7a1b '#6 タプル型 課題1 型名を定数名・変数名に含めない
1c1ae0b #6 タプル型 課題2 外部引数名を設定 // ←コレを修正したい直前の4d8ab6aをコピペ
4d8ab6a '#6 タプル型 課題1 関数名、定数名をLowerCamelCaseで記述
ed18929 #6 タプル型 課題2 レイアウト作成
ebb32f3 #6 タプル型 課題1
```
修正したいコミットのひとつ古いコミット識別子「4d8ab6a」をコピペしておく
照会画面を終了するときはq

### コミット識別子で範囲指定
git rebase -i コミット識別子　
```swift:コミット識別子で範囲を指定する
% git rebase -i 4d8ab6a 
```
```swift:git rebase -iの実行直後 
pick 1c1ae0b #6 タプル型 課題2 外部引数名を設定
pick bef7a1b '#6 タプル型 課題1 型名を定数名・変数名に含めない
pick cb1def2 #6 タプル型 課題2 条件4 関数1 numbersCheck実装

//# Rebase 4d8ab6a..cb1def2 onto 4d8ab6a (3 commands)
//#
//# Commands:
//# p, pick <commit> = use commit
//# r, reword <commit> = use commit, but edit the commit message
//# e, edit <commit> = use commit, but stop for amending
//# s, squash <commit> = use commit, but meld into previous commit
//# f, fixup [-C | -c] <commit> = like "squash" but keep only the previous
//#                    commit's log message, unless -C is used, in which case
//#                    keep only this commit's message; -c is same as -C but
//#                    opens the editor
//# x, exec <command> = run command (the rest of the line) using shell
//# b, break = stop here (continue rebase later with 'git rebase --continue')
//# d, drop <commit> = remove commit
//# l, label <label> = label current HEAD with a name
//# t, reset <label> = reset HEAD to a label
//# m, merge [-C <commit> | -c <commit>] <label> [# <oneline>]
//# .       create a merge commit using the original merge commit's
//# .       message (or the oneline, if no original merge commit was
//# .       specified); use -c <commit> to reword the commit message

```
iを押してインサートモードへ移行
修正したいコミット名のpickをeditに変更
escキーを押してインサートモード終了
:wqで保存終了
### 編集するコミットの選択
```swift:修正するコミットを指定するフロー
// 最初にiを押してインサートモードへ移行（入力できるようになる）
edit 1c1ae0b #6 タプル型 課題2 外部引数名を設定 // 修正したいところをeditにする
pick bef7a1b '#6 タプル型 課題1 型名を定数名・変数名に含めない
pick cb1def2 #6 タプル型 課題2 条件4 関数1 numbersCheck実装

//# Rebase 4d8ab6a..cb1def2 onto 4d8ab6a (3 commands)
//#
//# Commands:
//# p, pick <commit> = use commit
//# r, reword <commit> = use commit, but edit the commit message
//# e, edit <commit> = use commit, but stop for amending
//# s, squash <commit> = use commit, but meld into previous commit
//# f, fixup [-C | -c] <commit> = like "squash" but keep only the previous
//#                    commit's log message, unless -C is used, in which case
//#                    keep only this commit's message; -c is same as -C but
//#                    opens the editor
//# x, exec <command> = run command (the rest of the line) using shell
//# b, break = stop here (continue rebase later with 'git rebase --continue')
//# d, drop <commit> = remove commit
//# l, label <label> = label current HEAD with a name
//# t, reset <label> = reset HEAD to a label
//# m, merge [-C <commit> | -c <commit>] <label> [# <oneline>]
//# .       create a merge commit using the original merge commit's
//# .       message (or the oneline, if no original merge commit was
//# .       specified); use -c <commit> to reword the commit message
//#
//# These lines can be re-ordered; they are executed from top to bottom.
//#
//# If you remove a line here THAT COMMIT WILL BE LOST.
//#
//# However, if you remove everything, the rebase will be aborted.
//#
:wq // インサートモードをescキーで解除したら入力してエンター

```
どーちどっちと聞かれる
git commit --amend　修正するとき
git rebase --continue　修正後確定する
```swift:どーちどっち
% git rebase -i 4d8ab6a  
Stopped at 1c1ae0b...  #6 タプル型 課題2 外部引数名を設定
You can amend the commit now, with

  git commit --amend 

Once you are satisfied with your changes, run

  git rebase --continue
```
### コミット名を修正するのでgit commit --amendを実行

```swift:コミット名修正を選択
% git commit --amend 
hint: Waiting for your editor to close the file... 
　　　　　　#6 タプル型 課題2 外部引数名を設定

//# Please enter the commit message for your changes. Lines starting
//# with '#' will be ignored, and an empty message aborts the commit.
//#
//# Date:      Tue Mar 22 22:29:15 2022 +0900
//#
//# interactive rebase in progress; onto 4d8ab6a
//# Last command done (1 command done):
//#    edit 1c1ae0b #6 タプル型 課題2 外部引数名を設定
//# Next commands to do (2 remaining commands):
//#    pick bef7a1b '#6 タプル型 課題1 型名を定数名・変数名に含めない
//#    pick cb1def2 #6 タプル型 課題2 条件4 関数1 numbersCheck実装
//# You are currently editing a commit while rebasing branch 'main' on '4d8ab6a'.
//#
//# Changes to be committed:
//#       modified:   Tuple.playground/Contents.swift
//#
~                                                                               
~                                                                               
~                                                                               
~                                                                               
~                                                                               
~                                                                               
~                                                                               
"~/Desktop/Swift-Beginners/Lesson_ymp-a/.git/COMMIT_EDITMSG" 18L, 754B
```
またiを押してインサートモードに移行
コミット名を修正
escキーでインサートモード終了
:wqで保存終了
### コミット名修正フロー
```swift:コミット名修正フロー
// iを押してインサートモードへ移行
hint: Waiting for your editor to close the file... 
'#6 タプル型 課題1 外部引数名を設定 // コミット名を修正

//# Please enter the commit message for your changes. Lines starting
//# with '#' will be ignored, and an empty message aborts the commit.
//#
//# Date:      Tue Mar 22 22:29:15 2022 +0900
//#
//# interactive rebase in progress; onto 4d8ab6a
//# Last command done (1 command done):
//#    edit 1c1ae0b #6 タプル型 課題2 外部引数名を設定
//# Next commands to do (2 remaining commands):
//#    pick bef7a1b '#6 タプル型 課題1 型名を定数名・変数名に含めない
//#    pick cb1def2 #6 タプル型 課題2 条件4 関数1 numbersCheck実装
//# You are currently editing a commit while rebasing branch 'main' on '4d8ab6a'.
//#
//# Changes to be committed:
//#       modified:   Tuple.playground/Contents.swift
//#
~                                                                               
~                                                                               
~                                                                               
~                                                                               
~                                                                               
~                                                                               
~                                                                               
"~/Desktop/Swift-Beginners/Lesson_ymp-a/.git/COMMIT_EDITMSG" 18L, 754B
:wq // escキーを押してインサートモード終了したら:wq入力してエンター
```
今回コミット名先頭が（GitHubのissue紐つけのため）#6〜と#からはじまっている。
インサートモードでは#はコメント扱いのため先頭に'をつけて対応している。（もっと良い方法あるかも）
### 修正したコミット名を決定する
```swift:コミット名修正確定後
% git commit --amend 
[detached HEAD 9c21bc5] '#6 タプル型 課題1 外部引数名を設定
 Date: Tue Mar 22 22:29:15 2022 +0900
 1 file changed, 4 insertions(+), 4 deletions(-)
```

pickをeditにするところで複数editにしているとどーちどっちの再選択を迫られ繰り返す。
コミット名の修正が完了したらgit rebase --continueを実行する
### コミットメッセージの確定
```swift:コミット名修正確定を実行
% git rebase --continue
Successfully rebased and updated refs/heads/main.
```
あとはプッシュするだけ
このタイミングで% git logとかでコミット名を再確認するもよし
いつものプッシュでは怒られる
```swift:いつものpushはダメ
% git push origin main 
To github.com:hogehogeStady/Lesson_ymp-a.git
 ! [rejected]        main -> main (non-fast-forward)
error: failed to push some refs to 'github.com:hogehogeStady/Lesson_ymp-a.git'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. Integrate the remote changes (e.g.
hint: 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
```
### 強制pushで更新
% git push -f origin リポジトリ名 で強制プッシュする
```swift:強制pushでおk
% git push -f origin main
Enumerating objects: 19, done.
Counting objects: 100% (19/19), done.
Delta compression using up to 8 threads
Compressing objects: 100% (13/13), done.
Writing objects: 100% (13/13), 2.60 KiB | 2.60 MiB/s, done.
Total 13 (delta 6), reused 0 (delta 0), pack-reused 0
remote: Resolving deltas: 100% (6/6), completed with 3 local objects.
To github.com:hogehogeStady/Lesson_ymp-a.git
 + cb1def2...d6d2914 main -> main (forced update)
```
成功です。
おつかれさまでした。

コミットとプッシュは心を落ち着かせてから
冷静職人になりたい
次回はスマートに修正できますように。