git / GitHub で間違った commit / push を取り消す 

間違った commit を消すには revert ? reset ? あとリモートに push してしまったらどうしたらいいかな?
いざというときに慌てないように備忘録。

# ミステイク!

`github/OMCUSS/`

というフォルダで作業をしていたのだが、ファイル操作を間違えて、

`github/OMCUSS/OMCUSS`

という階層を作ってしまった。

同じ内容のものが入れ子になっている状態で、ソースを更新して commit / push してしまった。


# どうしたい?

## その1. 
`github/OMCUSS/OMCUSS` にあるものを削除したい

## その2.
`github/OMCUSS/` にあるソースの変更は維持したい

## その3.
リモートとローカルを一致させたい


# 状況確認

まずは、履歴を確認。


```
$ git log
```

```
commit bc90c2a1acb1f3a5d7db4fdca1462aec0fda8956 (HEAD -> main, origin/main, origin/HEAD)
Author: nanbuwks <nanbuwks+github@nanbu.com>
Date:   Thu Mar 16 23:32:28 2023 +0900

    add xojo_raspverrypi_webappp, and etc.

commit 1f101b498378a3f76c1e0bde1660441535d9b5a3
Author: nanbuwks <nanbuwks+github@nanbu.com>
Date:   Sat Mar 11 11:07:59 2023 +0900

    first commit
```
# 作戦

取り消しは revert と reset があるが、無駄なファイルを履歴で持ちたくないので reset で対処。


git reset にはモードがある。

```
       git reset [<mode>] [<commit>]
           This form resets the current branch head to <commit> and possibly updates the index (resetting it to the
           tree of <commit>) and the working tree depending on <mode>. If <mode> is omitted, defaults to --mixed.
           The <mode> must be one of the following:

           --soft
               Does not touch the index file or the working tree at all (but resets the head to <commit>, just like
               all modes do). This leaves all your changed files "Changes to be committed", as git status would put
               it.

           --mixed
               Resets the index but not the working tree (i.e., the changed files are preserved but not marked for
               commit) and reports what has not been updated. This is the default action.

               If -N is specified, removed paths are marked as intent-to-add (see git-add(1)).

           --hard
               Resets the index and working tree. Any changes to tracked files in the working tree since <commit>
               are discarded.

           --merge
               Resets the index and updates the files in the working tree that are different between <commit> and
               HEAD, but keeps those which are different between the index and working tree (i.e. which have
               changes which have not been added). If a file that is different between <commit> and the index has
               unstaged changes, reset is aborted.

               In other words, --merge does something like a git read-tree -u -m <commit>, but carries forward
               unmerged index entries.

           --keep
               Resets index entries and updates files in the working tree that are different between <commit> and
               HEAD. If a file that is different between <commit> and HEAD has local changes, reset is aborted.

```


これを見ると、以下の5つが使える。

--soft
--mixed
--hard
--merge
--keep


あまり自信がないけど、こんな感じかな?


|オプション|commit|index|indexed file|unindexed file|
|:---:|:---:|:---:|:---:|:---:|
|soft|reset|none|none|none|
|mixed|reset|reset|none|none|
|hard|reset|reset|reset|reset|
|merge|reset|reset|reset|none|
|keep|reset|reset|reset|stop|

index というのは `git add` で行われる処理のこと。

上を読んで、` --mixed ` を使うことにした。


# 作業

```
$ git reset --mixed HEAD^
```

これで、ひとつ前の状態に戻る。
ファイルはそのまま。

```
$ git log
```
で確認すると、
```
commit 1f101b498378a3f76c1e0bde1660441535d9b5a3 (HEAD -> main)
Author: nanbuwks <nanbuwks+github@nanbu.com>
Date:   Sat Mar 11 11:07:59 2023 +0900

    first commit
```


間違った commit が消えている。
なので余計なファイルを削除してしまおう。

```
$rm -rf OMCUSS
```
> ## その1. 
> `github/OMCUSS/OMCUSS` にあるものを削除したい
> 
> ## その2.
> `github/OMCUSS/` にあるソースの変更は維持したい

ということで、その2の作業。

```
$ git add .
$ git commit
```

これで、ローカルはうまくいったので、リモートに反映。

```
$ git push -f origin main
```
としてリモートを上書きします