全力で怠けたい

怠けるために全力を尽くしたいブログ。

今さらだけど git switch と git restore を使ってみたメモ。

git switchgit restore を少し使ってみたメモ。

git のバージョン。

$ git --version
git version 2.29.2

git switch と git restore

git switchgit restore はなんとなく雰囲気で使ってる気がするのでちょっとだけ気にして使ってみたメモ。

git switchgit restoregit checkout ほどじゃないけど git のサブコマンドだけあって結構いろんなことができるのだけど、そのへんを書いていくと書くことが多くなりそうなのでよく使いそうなやつを git checkout とかと比較しながら書いていく。

git checkout のよりよいインタフェースとしての git switch と git restore

Git 2.23 は git checkout を代替する試みとして実験的なコマンドの git switchgit restore が追加した。 git checkout はブランチをチェックアウトしたりブランチを作ったりといろんなことができるけどいろんなことができすぎて「なにをするコマンドかよく分からない」感があるかなという気がしてるけど、そのへんの「いろんなできること」が git switchgit restore に分けたら分かりやすくするのが目的のよう。

Git 2.23 brings a new pair of experimental commands to the suite of existing ones: git switch and git restore. These two are meant to eventually provide a better interface for the well-known git checkout. The new commands intend to each have a clear separation, neatly divvying up what the many responsibilities of git checkout, as we’ll show below.

git switch

git switch はブランチを切り替える。オプションで新しいブランチを作ることもできる。

git switch の使い方を書いていく。

ブランチを切り替える

こんな感じでブランチを切り替える。

$ git switch <branch>

git checkout はこんな感じで同じことができる。

$ git checkout <branch>

ブランチを作る

git switch-c オプションか --create オプションを指定するとブランチを作る。

$ git switch --create <new-branch>

git checkout はこんな感じで同じことができる。

$ git checkout -b <new-branch>

git branchgit switch を組み合わせるとこんな感じで同じことができる。

$ git branch <new-branch>
$ git switch <new-branch>

強制的にブランチを作る

-c オプションと --create オプションは指定したブランチがすでに存在してると失敗するけど -C オプションか --force-create オプションは指定したブランチがすでに存在していると強制的にブランチを作り直す。

$ git switch --force-create <new-branch>

git branchgit switch を組み合わせるとこんな感じで同じことができる。

$ git branch --force <new-branch>
$ git switch <new-branch>

マニュアルを表示する

git help switch すると git switch のマニュアルを表示する。

$ git help switch

GIT-SWITCH(1)                                Git Manual                               GIT-SWITCH(1)

NAME
       git-switch - Switch branches

SYNOPSIS
       git switch [<options>] [--no-guess] <branch>
       git switch [<options>] --detach [<start-point>]
       git switch [<options>] (-c|-C) <new-branch> [<start-point>]
       git switch [<options>] --orphan <new-branch>

# 省略

git restore

git restore はワーキングツリー (作業ディレクトリ) の変更を戻す。

git restore の使い方を書いていく。

ワーキングツリーの変更を戻す

-W オプションか --worktree オプションを指定するとワーキングツリーつまりファイルの変更を git add する前の変更を取り消して変更前の状態に戻す。

$ git restore --worktree <pathspec>

実際に使ってみるとこんな感じ。

$ git status
On branch main
nothing to commit, working tree clean

$ echo hoge > README.md
$ git status
On branch main
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
    modified:   README.md

$ git restore README.md
$ git status
On branch main
nothing to commit, working tree clean

git checkout はこんな感じで同じことができる。

$ git checkout <pathspec>

ちなみに -W オプションまたは --worktree オプションと後述する -S オプションまたは --staged のどちらも指定しないときは --worktree を指定するのと同じ動作になる。 つまり次の2つのコマンドは同じ動きになる。

$ git restore --worktree <pathspec>
$ git restore <pathspec>

インデックスの変更を戻す

-S オプションか --staged オプションを指定するとインデックスつまりファイルの変更を git add した分を git add する前の状態に戻す。

$ git restore --staged <pathspec>

実際に使ってみるとこんな感じ。

$ git status
On branch main
nothing to commit, working tree clean

$ echo hoge > README.md
$ git add README.md
$ git status
On branch main
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
    modified:   README.md
$ git diff

$ git restore --staged README.md
$ git status
On branch main
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
    modified:   README.md
$ git diff
diff --git a/README.md b/README.md
index 0abf9a4..2262de0 100644
--- a/README.md
+++ b/README.md
@@ -1 +1 @@
-GOOD!
+hoge

git reset はこんな感じで同じことができる。

$ git reset README.md

ワーキングツリーとインデックスの変更を戻す

--worktree オプションと --staged オプションを両方指定するとワーキングツリーの変更とインデックスに追加したファイルの変更を取り消して変更前の状態に戻す。

$ git restore --worktree --staged <pathspec>
$ git st
On branch main
nothing to commit, working tree clean

$ echo hoge > README.md
$ git add README.md
$ echo fuga > README.md
$ git status
On branch main
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
    modified:   README.md

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
    modified:   README.md

$ git restore --worktree --staged README.md
$ git status

git resetgit checkout はこんな感じで同じことができる。

$ git reset README.md
$ git checkout README.md

任意のコミットに戻す

-s オプションか --source オプションを指定するとワーキングツリーを任意のコミットに戻すことができる。

任意のコミットに戻すとワーキングツリーの変更内容はインデックス追加する前つまり git add する前の状態になる。

$ cat README.md
GOOD!

$ git checkout fbda5d9 2>&1 > /dev/null
$ cat README.md
HELLO

$ git switch main
Previous HEAD position was fbda5d9 hello
Switched to branch 'main'

$ git restore --source fbda5d9 README.md
$ cat README.md
HELLO

$ git diff
diff --git a/README.md b/README.md
index 0abf9a4..e427984 100644
--- a/README.md
+++ b/README.md
@@ -1 +1 @@
-GOOD!
+HELLO

git checkoutgit reset はこんな感じで同じことができる。 git checkout は任意のコミットに戻すとワーキングツリーの変更内容はインデックス追加した後つまり git add した後の状態になるので git reset でインデックスに追加した内容をワーキングツリーに戻す。

$ git checkout <commit> <pathspec>
$ git reset <pathspec>

ちなみに --source を指定しないときは HEAD に戻すつまり以下の2つは同じ動きになる。

$ git restore <commit> <pathspec>
$ git restore --source HEAD <pathspec>

マニュアルを表示する

git help restore すると git restore のマニュアルを表示する。

$ git help restore

GIT-RESTORE(1)                               Git Manual                              GIT-RESTORE(1)

NAME
       git-restore - Restore working tree files

SYNOPSIS
       git restore [<options>] [--source=<tree>] [--staged] [--worktree] [--] <pathspec>...
       git restore [<options>] [--source=<tree>] [--staged] [--worktree] --pathspec-from-file=<file> [--pathspec-file-nul]
       git restore (-p|--patch) [<options>] [--source=<tree>] [--staged] [--worktree] [--] [<pathspec>...]

# 省略

参考サイト