SYNOPSIS

git reset [-q] [<tree-ish>] [--] <pathspec>…
git reset [-q] [--pathspec-from-file=<file> [--pathspec-file-nul]] [<tree-ish>]
git reset (--patch | -p) [<tree-ish>] [--] [<pathspec>…]
git reset [--soft | --mixed [-N] | --hard | --merge | --keep] [-q] [<commit>]

DESCRIPTION

最初の3つの形式は、エントリを`<tree-ish>` からインデックスにコピーします。 最後の形式では、現在のブランチヘッド(HEAD) を <commit> に設定し、オプションでインデックスと作業ツリーを一致するように変更します。 <tree-ish>/<commit> は、すべての形式でデフォルトで HEAD になります。

git reset' [-q] [<tree-ish>] [--] <pathspec>...
git reset [-q] [--pathspec-from-file=<file> [--pathspec-file-nul]] [<tree-ish>]

これらの形式は、 <pathspec><tree-ish> の状態に一致させるすべてのパスのインデックスエントリをリセットします。 (作業ツリーや現在のブランチには影響しません。)

これは、 git reset <pathspec>git add <pathspec> の反対であることを意味します。 このコマンドは、 git restore [--source=<tree-ish>] --staged <pathspec>... と同等です。

git reset <pathspec> を実行してインデックスエントリを更新した後、 git-restore(1) を使用して、インデックスの内容を作業ツリーにチェックアウトできます。 または、 git-restore(1) を使用し、 --source でコミットを指定すると、コミットからインデックスと作業ツリーへのパスの内容を一度にコピーできます。

git reset (--patch | -p) [<tree-ish>] [--] [<pathspec>...]

インデックスと <tree-ish> (デフォルトは HEAD)の違いでハンクを対話的に選択します。 選択したハンクは、インデックスから適用を外します(apply in reverse)。

これは、 git reset -pgit add -p の反対であることを意味します。つまり、これを使用してハンクを選択的にリセットできます。 --patch モードの操作方法については、 git-add(1) の「Interactive Mode」セクションを参照してください。

git reset [<mode>] [<commit>]

この形式は、現在のブランチヘッドを <commit> にリセットし、場合によっては、 <mode> に応じて、インデックス(<commit> のツリーにリセット)と作業ツリーを更新します。 操作前に、 現在のブランチの先端に ORIG_HEAD が設定されます。 <mode> を省略すると、デフォルトで --mixed になります。 <mode> は以下のいずれかである必要があります:

--soft

インデックスファイルまたは作業ツリーにはまったく触りません(しかし、すべてのモードと同様に、ヘッドを <commit> にリセットします)。 これにより、 git status が示すように、変更されたすべてのファイルが「コミットされる変更」(Changes to be committed)のままになります。

--mixed

インデックスをリセットしますが、作業ツリーはリセットしません(つまり、変更されたファイルは保持されますが、コミットのマークは付けられません)。更新されていないものを報告します。 これがデフォルトのアクションです。

-N が指定されている場合、削除されたパスはadd対象(intent-to-add)としてマークされます(git-add(1) 参照)。

--hard

インデックスと作業ツリーをリセットします。 <commit> 以降の作業ツリー内の追跡中のファイルへの変更はすべて破棄されます。追跡中のファイルの書き込み時に邪魔になる、追跡されていないファイルまたはディレクトリは、単に削除されます。

--merge

インデックスをリセットし、作業ツリー内の <commit>HEAD の間で異なるファイルを更新しますが、インデックスと作業ツリーの間で異なるファイル(つまり、まだ追加されていない変更があるもの)は保持します。 もし <commit> とインデックスの間で異なるファイルに、ステージされていない変更がある場合、リセットは中断(abort)されます。

つまり、 --mergegit read-tree -u -m <commit> のようなことをしますが、アンマージインデックスエントリは引き継ぎます。

--keep

インデックスエントリをリセットし、 <commit>HEAD で異なる作業ツリー内のファイルを更新します。 <commit>HEAD で異なるファイルにローカル変更がある場合、リセットは中止(abort)されます。

--[no-]recurse-submodules

作業ツリーが更新される時、 --recurse-submodules を使用すると、スーパープロジェクトに記録されたコミットに従ってすべてのアクティブなサブモジュールの作業ツリーが再帰的にリセットされ、そのコミット時にサブモジュールのHEADが切り離されるよう(detach)に設定されます。

3つのコマンドの違いについては、 git(1) の「Reset, restore and revert」を参照してください。

OPTIONS

-q
--quiet

静かにして、エラーのみを報告してください。

--refresh
--no-refresh

混合リセット(mixed reset)後にインデックスを更新します。 デフォルトで有効になっています。

--pathspec-from-file=<file>

パススペックは、コマンドライン引数の代わりに <file> で渡されます。 <file> が正確に - の場合、標準入力が使用されます。 Pathspec要素は、LFまたはCR/LFで区切られます。 パススペック要素は、構成変数 core.quotePath で説明されているようにクォートできます(git-config(1) 参照)。 --pathspec-file-nul および グローバルの --literal-pathspecs も参照してください。

--pathspec-file-nul

--pathspec-from-file 指定時のみ意味があります。 パススペック要素はNUL文字で区切られ、他のすべての文字は文字通りに解釈されます(改行と引用符を含む)。

--

これ以降の引数をオプションとして解釈しないでください。

<pathspec>…

操作の影響を受けるパスを制限します。

詳細については、 gitglossary(7) の「pathspec」エントリを参照してください。

EXAMPLES

addを取り消し(undo add)
$ edit                                     <1>
$ git add frotz.c filfre.c
$ mailx                                    <2>
$ git reset                                <3>
$ git pull git://info.example.com/ nitfol  <4>
  1. あなたは喜んで何かに取り組んでおり、これらのファイルの変更が適切に行われていることがわかります。 あなたが git diff を実行するときにそれらを表示したくないのは、他のファイルで作業することを計画していて、これらのファイルでの変更が気を散らすためです。

  2. 誰かがあなたにプルを要求し、その変更がマージに値すると思われる場合。

  3. しかしながら、あなたはすでにインデックスをダーティにしています(つまり、インデックスが HEAD コミットと一致していません)。 ただし、これから行うプルは frotz.c または filfre.c には影響しないため、これら2つのファイルのインデックスの変更を元に戻します。 作業ツリーのあなたの変更はそのまま残ります。

  4. それから、あなたは frotz.cfilfre.c の変更を作業ツリーに残したまま、プルしてマージできます。

コミットを取り消し、再度行う(undo a commit and redo)
$ git commit ...
$ git reset --soft HEAD^      <1>
$ edit                        <2>
$ git commit -a -c ORIG_HEAD  <3>
  1. これは、コミットした内容が不完全であることを思い出した場合、コミットメッセージのスペルを間違えた場合、またはその両方の場合に最もよく行われます。 「リセット」前の状態で作業ツリーを残します。

  2. 作業ツリーファイルを修正します。

  3. 「リセット」は古いヘッドを .git/ORIG_HEAD にコピーします。 ログメッセージから始めて、コミットをやり直します。 メッセージをさらに編集する必要がない場合は、代わりに -C オプションを指定できます。

    git-commit(1)--amend オプションも参照してください。

コミットを取り消し(undo)、トピックブランチにします
$ git branch topic/wip          <1>
$ git reset --hard HEAD~3       <2>
$ git switch topic/wip          <3>
  1. あなたはいくつかのコミットをしましたが、それらが master ブランチに入るのは時期尚早であることに気づきました。 あなたはトピックブランチでそれらを磨き続けたいので、現在の HEAD から topic/wip ブランチを作成します。

  2. masterブランチを巻き戻して、これら3つのコミットを取り除きます。

  3. topic/wip ブランチに切り替えて、作業を続けます。

コミットを永久に取り消す(undo commits permanently)
$ git commit ...
$ git reset --hard HEAD~3   <1>
  1. 最後の3コミット(HEADHEAD^HEAD~2)は悪かったので、二度と見たくありません。 あなたがこれらのコミットを他の誰かにすでに与えている場合は、これを行ってはいけません。 (そうすることの意味については、 git-rebase(1) の「RECOVERING FROM UPSTREAM REBASE」セクションを参照してください。)

マージまたはプルを取り消す(undo a merge or pull)
$ git pull                         <1>
Auto-merging nitfol
CONFLICT (content): Merge conflict in nitfol
Automatic merge failed; fix conflicts and then commit the result.
$ git reset --hard                 <2>
$ git pull . topic/branch          <3>
Updating from 41223... to 13134...
Fast-forward
$ git reset --hard ORIG_HEAD       <4>
  1. アップストリームから更新しようとすると、多くの競合が発生しました。 あなたは現在、マージに多くの時間を費やす準備ができていなかったため、後でマージすることにしました。

  2. 「プル」はマージコミットを行っていないため、 git reset--hard HEAD の同義語である git reset --hard は、インデックスファイルと作業ツリーから混乱を取り除きます。

  3. トピックブランチを現在のブランチにマージします。これにより、早送り(fast-forward)が行われました。

  4. しかし、あなたはそのトピックブランチがまだ一般公開の準備ができていないと判断しました。 「pull」または「merge」は常に現在のブランチの元の先端を ORIG_HEAD に残すため、ハードにリセットするとインデックスファイルと作業ツリーがその状態に戻り、ブランチの先端がそのコミットにリセットされます。

ダーティな作業ツリー内でマージまたはプルを取り消し(undo)
$ git pull                         <1>
Auto-merging nitfol
Merge made by recursive.
 nitfol                |   20 +++++----
 ...
$ git reset --merge ORIG_HEAD      <2>
  1. 作業ツリーにローカルの変更がある場合でも、他のブランチの変更がそれらと重複していないことがわかっている場合は、「git pull」と安全に言うことができます。

  2. マージの結果を調べた後、他のブランチでの変更が不十分であることがわかる場合があります。 git reset --hard ORIG_HEAD を実行すると、元の場所に戻ることができますが、不要なローカルの変更は破棄されます。 git reset --merge は、ローカルの変更を保持します。

Interrupted workflow

あなたが大規模な変更をしている最中に、緊急の修正リクエストによって中断されたとします。 作業ツリー内のファイルはまだコミットできる形ではありませんが、バグをすばやく修正するには、他のブランチにアクセスする必要があります。

$ git switch feature  ;# you were working in "feature" branch and
$ work work work      ;# got interrupted
$ git commit -a -m "snapshot WIP"                 <1>
$ git switch master
$ fix fix fix
$ git commit ;# commit with real log
$ git switch feature
$ git reset --soft HEAD^ ;# go back to WIP state  <2>
$ git reset                                       <3>
  1. このコミットは吹き飛ばされちゃうので、投げやりなログメッセージでOKです。

  2. これにより、コミット履歴から「WIP」コミットが削除され、作業ツリーがスナップショットを作成する直前の状態に設定されます。

  3. この時点で、インデックスファイルには「スナップショットWIP」としてコミットしたすべてのWIP変更がまだ含まれています。 これにより、インデックスが更新され、WIPファイルがコミットされていないものとして表示されます。

    git-stash(1) も参照して下さい。

Reset a single file in the index

インデックスにファイルを追加したが、後でそれをコミットに追加したくないと判断したとします。 git resetを使用して変更を保持しながら、ファイルをインデックスから削除できます。

$ git reset -- frotz.c                      <1>
$ git commit -m "Commit files in index"     <2>
$ git add frotz.c                           <3>
  1. これにより、ファイルは作業ディレクトリに保持されたまま、インデックスから削除されます。

  2. これにより、インデックス内の他のすべての変更がコミットされます。

  3. そのファイルをインデックスに再度追加します。

以前のコミットを破棄しつつ作業ツリーの変更を保持する

何かに取り組んでいて、それをコミットしてから、もう少し作業を続けたとして、作業ツリーにあるものは、以前にコミットしたものとは関係のない別のブランチにあるはずだと思います。 作業ツリーに変更を加えたまま、新しいブランチを開始してリセットできます。

$ git tag start
$ git switch -c branch1
$ edit
$ git commit ...                            <1>
$ edit
$ git switch -c branch2                     <2>
$ git reset --keep start                    <3>
  1. これにより、branch1 にあなたの最初の編集がコミットされます。

  2. 理想的な世界では、 あなたが branch2 (つまり、 git switch -c branch2 start)を作成して切り替えたときに、以前のコミットが新しいトピックに属していないことに気付くかもしれませんが、完璧な人は誰もいません。

  3. しかし、 あなたが branch2 に切り替えた後は、 reset --keep を使用して不要なコミットを削除できます。

コミット(a commit)を一連のコミット(a sequence of commits)に分割

論理的に別々の変更をたくさん作成し、それらを一緒にコミットしたとします。 次に、後で、各論理チャンクを独自のコミットに関連付ける方がよい場合があると判断したとします。 あなたが git reset を使用すると、ローカルファイルの内容を変更せずに履歴を巻き戻すことができます。その後、git add -p を使用して各コミットに含めるハンクを対話的に選択し、 git commit -c でコミットメッセージをあらかじめ入力しておくことができます。

$ git reset -N HEAD^                        <1>
$ git add -p                                <2>
$ git diff --cached                         <3>
$ git commit -c HEAD@{1}                    <4>
...                                         <5>
$ git add ...                               <6>
$ git diff --cached                         <7>
$ git commit ...                            <8>
  1. まず、履歴をあるコミットにリセットして、元のコミットを削除しますが、すべての変更を作業ツリーに残します。 -N を使用すると、 HEAD で追加された新しいファイルにマークが付けられ、 git add -p がそれらを検出できるようになります。

  2. 次に、 私達は git add -p 機能を使用して、追加するdiffハンクを対話的に選択します。 これにより、各diffハンクについて順番に尋ねられ、「はい、これを含める」、「いいえ、これを含めない」、または非常に強力な「編集」機能などの簡単なコマンドを使用できます。

  3. あなたが含めたいハンクに満足したら、 git diff --cached を使用して、最初のコミットのために何が準備されているかを確認する必要があります。 これは、インデックスに移動され、コミットされようとしているすべての変更を示しています。

  4. 次に、インデックスに保存されている変更をコミットします。 -c オプションは、最初のコミットで開始した元のメッセージからコミットメッセージを事前入力することを指定します。 これは、再入力を避けるのに役立ちます。 HEAD@{1} は、元のリセットコミット(1変更前)の前に HEAD が使用されていたコミットの特別な表記です。 詳細については、 git-reflog(1) を参照してください。 他の有効なコミット参照を使用することもできます。

  5. あなたは手順2〜4を複数回繰り返して、元のコードを任意の数のコミットに分割できます。

  6. さて、あなたは多くの変更をそれぞれのコミットに分割したので、残りの未コミットの変更をすべて選択するために、もはや git add のパッチモードは使用しないかもしれません。

  7. もう一度、必要なものが含まれていることを確認してください。 また、git diffにて後でコミットする残りの変更が表示されないことを確認することもできます。

  8. そして最後に最終コミットを作成します。

DISCUSSION

以下の表は、実行時に何が起こるかを示しています:

git reset --option target

ファイルの状態に応じて異なるリセットオプションを使用して、 HEAD を別のコミット(target)にリセットします。

これらの表で、 ABCD はファイルのいくつかの異なる状態を表しています。例えば、最初のテーブルの1行目は、あるファイルが作業ツリーの状態 A 、インデックスの状態 B 、HEADの状態 C、ターゲットの状態 D にある場合、 git reset --soft target は作業ツリーの状態 A とインデックスの状態 B を残したままにすることを意味しています。 これは、HEAD (つまり、現在のブランチの先端)を target (状態 D のファイルがある)にリセット(つまり移動)するものです。

working index HEAD target         working index HEAD
----------------------------------------------------
 A       B     C    D     --soft   A       B     D
                          --mixed  A       D     D
                          --hard   D       D     D
                          --merge (disallowed)
                          --keep  (disallowed)
working index HEAD target         working index HEAD
----------------------------------------------------
 A       B     C    C     --soft   A       B     C
                          --mixed  A       C     C
                          --hard   C       C     C
                          --merge (disallowed)
                          --keep   A       C     C
working index HEAD target         working index HEAD
----------------------------------------------------
 B       B     C    D     --soft   B       B     D
                          --mixed  B       D     D
                          --hard   D       D     D
                          --merge  D       D     D
                          --keep  (disallowed)
working index HEAD target         working index HEAD
----------------------------------------------------
 B       B     C    C     --soft   B       B     C
                          --mixed  B       C     C
                          --hard   C       C     C
                          --merge  C       C     C
                          --keep   B       C     C
working index HEAD target         working index HEAD
----------------------------------------------------
 B       C     C    D     --soft   B       C     D
                          --mixed  B       D     D
                          --hard   D       D     D
                          --merge (disallowed)
                          --keep  (disallowed)
working index HEAD target         working index HEAD
----------------------------------------------------
 B       C     C    C     --soft   B       C     C
                          --mixed  B       C     C
                          --hard   C       C     C
                          --merge  B       C     C
                          --keep   B       C     C

reset --merge は、競合するマージからリセットするときに使用することを目的としています。 マージ操作は、マージに関係する作業ツリーファイルが、開始前にインデックスに対してローカルな変更がないこと、そしてその結果を作業ツリーに書き出すことを保証しています。 したがって、インデックスとターゲットの間、およびインデックスと作業ツリーの間に何らかの違いが見られる場合、それは、マージ中の操作が競合で失敗した後に残した状態からリセットされていないことを意味します。 そのため、この場合は --merge オプションを使用を許可しません。

reset --keep は、作業ツリーの変更を維持しながら、現在のブランチの最後のコミットの一部を削除するときに使用することを目的としています。 削除するコミットの変更と保持する作業ツリーの変更の間に競合が発生する可能性がある場合、リセットは許可されません。 そのため、作業ツリーと HEAD の間、および HEAD とターゲットの間の両方に変更がある場合、リセットは許可されません。 安全のため、アンマージエントリがある場合もリセットは許可されません。

以下の表は、アンマージエントリがある場合に何が起こるかを示しています:

working index HEAD target         working index HEAD
----------------------------------------------------
 X       U     A    B     --soft  (disallowed)
                          --mixed  X       B     B
                          --hard   B       B     B
                          --merge  B       B     B
                          --keep  (disallowed)
working index HEAD target         working index HEAD
----------------------------------------------------
 X       U     A    A     --soft  (disallowed)
                          --mixed  X       A     A
                          --hard   A       A     A
                          --merge  A       A     A
                          --keep  (disallowed)

X は任意の状態を意味し、 U はアンマージインデックスを意味します。

GIT

Part of the git(1) suite