[解決済み] わかりやすく言うと、「git reset」は何をするものなのでしょうか?
質問
私が見たのは
面白い記事
についての微妙な違いを説明しています。
git reset
.
残念ながら、読めば読むほど、私が完全に理解していないように見えるのです。私はSVN出身ですが、Gitはまったく新しいパラダイムです。mercurialは簡単に理解できましたが、Gitはもっと技術的なんです。
私が思うに
git reset
が近いです。
hg revert
ということですが、どうやら違いがあるようです。
では、具体的にどのような
git reset
を行うのですか?について、詳しい説明を入れてください。
-
オプション
--hard
,--soft
と--merge
; -
で使用する奇妙な記法は
HEAD
というようにHEAD^
とHEAD~1
; - 具体的なユースケースとワークフロー。
-
作業コピーの結果
HEAD
と、あなたのグローバルなストレスレベル。
解決方法は?
一般的には
git reset
の機能は、現在のブランチをリセットして別の場所を指すようにし、場合によってはインデックスと作業ツリーを一緒に持ってくることです。具体的には、master ブランチ (現在チェックアウトされている) がこのような状態だとすると、次のようになります。
- A - B - C (HEAD, master)
で、master が C ではなく B を指すようにしたい場合、次のようにします。
git reset B
で移動させます。
- A - B (HEAD, master) # - C is still here, but there's no branch pointing to it anymore
余談ですが これはチェックアウトとは違います。もしあなたが
git checkout B
ということになります。
- A - B (HEAD) - C (master)
デタッチドHEADの状態で終了していますね。
HEAD
作業ツリー、インデックスがすべて一致
B
で、master ブランチが取り残されています。
C
. 新しいコミットを行う場合
D
この時点で、おそらくあなたが望むものではない、次のようなものが得られます。
- A - B - C (master)
\
D (HEAD)
リセットがコミットを行うのではなく、ブランチ (コミットへのポインタ) を更新して別のコミットを指すようにするだけであることに注意しましょう。あとは、インデックスと作業ツリーに何が起こるかの詳細だけです。
使用例
の主なユースケースを多く取り上げています。
git reset
次のセクションのさまざまなオプションの説明の中にあります。ブランチ、インデックス、ワークツリーをリセットして、あるコミットを指すようにするのが共通点です。
注意すべきこと
-
--hard
は、本当に仕事を失う原因になりかねません。ワークツリーを修正してしまうのです。 -
git reset [options] commit
は、(一種の) コミットロスを引き起こす可能性があります。上のおもちゃの例では、コミットC
. これはまだレポに残っていて、次の場所で見つけることができます。git reflog show HEAD
またはgit reflog show master
しかし、実際にはもうどのブランチからもアクセスできないのです。 -
Git は 30 日後にそのようなコミットを永久に削除しますが、それまでは再びブランチを指して C を回復することができます (
git checkout C; git branch <new branch name>
).
引数
マニュアルによると、最も一般的な使い方は次のようなものです。
git reset [<commit>] [paths...]
これは、与えられたパスを与えられたコミットからの状態にリセットします。パスが提供されない場合、ツリー全体がリセットされ、コミットが提供されない場合、それは HEAD(現在のコミット)であるとみなされます。これは git コマンドに共通するパターンなので(正確な意味は異なりますが、checkout、diff、log など)、それほど驚くことではありません。
例えば
git reset other-branch path/to/foo
は、path/to/foo にあるすべてのものを other-branch の状態にリセットします。
git reset -- .
はカレントディレクトリを HEAD の状態にリセットし、単純な
git reset
は、すべてをHEADの状態にリセットします。
メインワークツリーとインデックスオプション
リセット中にワークツリーとインデックスに何が起こるかを制御するための4つの主要なオプションがあります。
インデックスとは、git の「ステージング・エリア」であり、次のような場合に使用されます。
git add
をコミットするための準備として使用します。
-
--hard
は、すべてをあなたがリセットしたコミットに一致させます。これはおそらく最も理解しやすいものです。ローカルで行ったすべての変更が取り込まれます。主な用途のひとつは、コミットを切り替えずに自分の作業を吹き飛ばすことです。git reset --hard
というのはgit reset --hard HEAD
つまり、ブランチは変更しないが、ローカルでの変更はすべて取り除くということです。もうひとつは、単にブランチをある場所から別の場所に移動し、インデックスとワークツリーを同期させたままにしておくものです。 これは、ワークツリーを変更するため、本当に仕事ができなくなる可能性があるものです。 を実行する前に、ローカルの仕事を捨てたいことをよくよく確認してください。reset --hard
. -
--mixed
はデフォルト、つまりgit reset
というのはgit reset --mixed
. これはインデックスをリセットしますが、作業ツリーはリセットしません。これは、すべてのファイルが無傷であることを意味します。しかし、元のコミットとリセットしたコミットの間に何らかの違いがあると、ローカルの変更 (あるいは追跡されていないファイル) として git ステータスに表示されます。この方法は、まずいコミットをしたことに気づいたけれども、それを修正して再コミットするためにすべての作業を残しておきたい場合に使用します。コミットするためには、ファイルを再度インデックスに追加しなければなりません (git add ...
). -
--soft
インデックスに触れない または の作業ツリーです。の場合と同様に、すべてのファイルは無傷です。--mixed
として表示されますが、すべての変更はchanges to be committed
を、git ステータス (コミット準備のためのチェックイン) で指定します。これは、間違ったコミットをしたことに気づいたけれども作業はすべて順調で、あとは別の方法で再コミットするだけという場合に使用します。インデックスには何も手をつけていないので、必要ならすぐにコミットすることができます。 -
--merge
は最近追加されたもので、失敗したマージを中止するのに役立つことを目的としています。これが必要な理由はgit merge
は、ダーティな作業ツリー (ローカルに変更を加えたもの) であっても、その変更がマージの影響を受けないファイルであれば、実際にマージを試行することを許可します。git reset --merge
はインデックスをリセットします(--mixed
- はローカルでの変更として表示されます)、そしてマージの影響を受けたファイルをリセットし、他のファイルはそのままにしておきます。これでうまくいけば、悪いマージの前にあった状態にすべてを戻すことができます。通常は次のように使用します。git reset --merge
(意味git reset --merge HEAD
というのも、実際にブランチを移動させるのではなく、マージをリセットしたいだけだからです。(HEAD
は、マージが失敗したため、まだ更新されていません)もう少し具体的に説明すると、ファイル A と B を変更し、ファイル C と D を変更したブランチでマージしようとしたとき、何らかの理由でマージに失敗し、それを中断することにしたとします。そこであなたは
git reset --merge
. CとDを元の状態に戻します。HEAD
しかし、A と B に対する修正は、マージの対象外であるため、そのままにしておきます。
もっと知りたい?
私はこう思う
man git reset
しかし、それらを本当に理解するためには、gitの動作に関するちょっとしたセンスが必要かもしれません。特に、時間をかけて注意深く読めば、様々なオプションやケースについて、インデックスや作業ツリーにおけるファイルの状態を詳細に示す表は、とても役に立ちます。(しかし、そうです、これらは非常に密です。彼らは非常に多くの上記の情報を非常に簡潔な形で伝えているのです)。
変な表記
奇妙な表記法" (
HEAD^
と
HEAD~1
のようなハッシュ名を使わなくても、コミットを指定できるようにするための単なる省略記法です。
3ebe3f6
. これは
リビジョンの指定"セクション
のマニュアルページには、たくさんの例と関連する構文が掲載されています。キャレットとチルダは、実際には次のような意味です。
異なるもの
:
-
HEAD~
の略です。HEAD~1
で、コミットの最初の親を意味します。HEAD~2
は、コミットの最初の親の最初の親を意味します。次のように考えてください。HEAD~n
は、"HEAD" よりも前の n コミット、または "HEAD" の第 n 世代の祖先である、と考えてください。 -
HEAD^
(またはHEAD^1
) は、コミットの最初の親を意味することもあります。HEAD^2
はコミットの 第二 の親になります。通常のマージコミットは2つの親を持つことを覚えておいてください。最初の親はマージされるコミットで、2番目の親はマージされたコミットです。一般に、マージは実際には任意の数の親を持つことができます (オクトパスマージ)。 -
は
^
と~
のように、演算子をつなげることができます。HEAD~3^2
の3代目先祖の2代目親である。HEAD
,HEAD^^2
の最初の親の2番目の親はHEAD
あるいはHEAD^^^
と等価である。HEAD~3
.
関連
-
[解決済み] Git で直近のローカルコミットを取り消すには?
-
[解決済み] Gitブランチをローカルやリモートで削除するには?
-
[解決済み] git pull」と「git fetch」の違いは何ですか?
-
[解決済み] コミット前に 'git add' を取り消すにはどうすればよいですか?
-
[解決済み] リモートのGitブランチをチェックアウトするには?
-
[解決済み] Git リポジトリを以前のコミットに戻すにはどうすればよいですか?
-
[解決済み] 現在のGit作業ツリーからローカル(未追跡)ファイルを削除する方法
-
[解決済み] Git で、ステージされていない変更を破棄するにはどうしたらいいですか?
-
[解決済み】"git pull" でローカルファイルを強制的に上書きするには?
-
[解決済み】ローカルのGitブランチの名前を変更するには?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】Git サブモジュール head 'reference is not a tree' エラー
-
[解決済み] [Solved] 作業ツリーのディレクトリ 'example.com' を作成できませんでした。パーミッションが拒否されました
-
[解決済み] 無効なVCSルートマッピング - 私のプロジェクトで3つのエラーが発生しました。
-
[解決済み] SourceTree error:1407742E:SSLルーチン:SSL23_GET_SERVER_HELLO:tlsv1警告プロトコルバージョン
-
[解決済み] 最後にpushされなかったgitコミットを、変更を失うことなくアンコミットする方法
-
[解決済み] プル中に自分の変更を優先してGitのマージの競合を解決する
-
[解決済み] git reset --mixed, --soft, --hard の違いは何ですか?
-
[解決済み] GitでコミットIDを元に特定のコミットに戻す?重複
-
[解決済み】ローカルコミットした後、再び自分のファイルのステージを解除するには?
-
[解決済み】gitのHEADとは何ですか?