Gitのstashとrestoreの違い

Gitの`stash`コマンドは、現在の作業中の変更を一時的に保管し、作業ディレクトリを最後のコミットの状態に戻します。これは、異なるタスクに切り替える必要があるが、現在の変更をまだコミットしたくない場合に便利です。

一方で、`git restore`コマンドは、特定のファイルの作業ディレクトリやステージングされた変更を元に戻すために使用されます。誤って変更した内容を修正したい時や、ステージングした内容を取り消したい場合に役立ちます。

どちらも作業中の変更を扱うためのツールですが、使用目的と機能には大きな違いがあります。


### git stash

`git stash`コマンドは、作業中の変更（ステージングされていない変更とステージングされた変更の両方）を一時的に保存し、作業ディレクトリをクリーンな状態（最後のコミットの状態）に戻すために使用されます。このコマンドは、別のブランチに切り替える必要があるが、現在のブランチにコミットしたくない変更がある場合に特に便利です。

使用例
- 変更を一時保存する: `git stash push -m "メッセージ"`
- スタッシュリストを表示する: `git stash list`
- 最後のスタッシュを適用する: `git stash pop`
- N番保存されたスタッシュを適用する：`git stash apply stash@{N}`

stash仕様確認

```sh
git stash -h
```

```text
usage: git stash list [<log-options>]
   or: git stash show [-u | --include-untracked | --only-untracked] [<diff-options>] [<stash>]
   or: git stash drop [-q | --quiet] [<stash>]
   or: git stash pop [--index] [-q | --quiet] [<stash>]
   or: git stash apply [--index] [-q | --quiet] [<stash>]
   or: git stash branch <branchname> [<stash>]
   or: git stash [push [-p | --patch] [-S | --staged] [-k | --[no-]keep-index] [-q | --quiet]
                 [-u | --include-untracked] [-a | --all] [(-m | --message) <message>]
                 [--pathspec-from-file=<file> [--pathspec-file-nul]]
                 [--] [<pathspec>...]]
   or: git stash save [-p | --patch] [-S | --staged] [-k | --[no-]keep-index] [-q | --quiet]
                 [-u | --include-untracked] [-a | --all] [<message>]
   or: git stash clear
   or: git stash create [<message>]
   or: git stash store [(-m | --message) <message>] [-q | --quiet] <commit>
```

### git restore
一方、`git restore`コマンドは、作業ディレクトリやステージングエリア（インデックス）の変更を復元するために使用されます。これにより、特定のファイルやディレクトリの変更を元に戻したり、ステージングされた変更を取り消すことができます。`git restore`は、手元の変更を破棄したい場合や、誤ってステージングした変更を戻したい場合に便利です。

使用例
- ワークツリーの変更を破棄する: `git restore ファイル名`
- ステージングされた変更を取り消す: `git restore --staged ファイル名`
- 特定のコミットにファイルを戻す: `git restore --source=<コミットハッシュ> ファイル名`

restore仕様確認

```sh
git restore -h
```

```text
usage: git restore [<options>] [--source=<branch>] <file>...

    -s, --source <tree-ish>
                          which tree-ish to checkout from
    -S, --staged          restore the index
    -W, --worktree        restore the working tree (default)
    --ignore-unmerged     ignore unmerged entries
    --overlay             use overlay mode
    -q, --quiet           suppress progress reporting
    --recurse-submodules[=<checkout>]
                          control recursive updating of submodules
    --progress            force progress reporting
    -m, --merge           perform a 3-way merge with the new branch
    --conflict <style>    conflict style (merge, diff3, or zdiff3)
    -2, --ours            checkout our version for unmerged files
    -3, --theirs          checkout their version for unmerged files
    -p, --patch           select hunks interactively
    --ignore-skip-worktree-bits
                          do not limit pathspecs to sparse entries only
    --pathspec-from-file <file>
                          read pathspec from file
    --pathspec-file-nul   with --pathspec-from-file, pathspec elements are separated with NUL character
```

### まとめ
それぞれのコマンドは異なる目的で設計されており、Gitを使用する上での柔軟なワークフローをサポートしています。適切なコマンドを選択することで、効率的に作業を進めることができます。

- git stashは、作業中の変更を一時的に保存し、後で再適用するためのコマンドです。ブランチの切り替え時などに役立ちます。
- git restoreは、作業ディレクトリやステージングエリアの変更を元に戻すためのコマンドです。特定の変更を取り消したい場合に使用します。

https://git-scm.com/docs/git-stash

https://git-scm.com/docs/git-restore