paint-brush
自信を持って Git の歴史を書き換える: ガイド@omerosenbaum
2,014 測定値
2,014 測定値

自信を持って Git の歴史を書き換える: ガイド

Omer Rosenbaum18m2023/04/27
Read on Terminal Reader

長すぎる; 読むには

Git は、ファイルシステムのスナップショットを適時に記録するためのシステムです。 Git リポジトリには、インデックス、ステージング領域、作業ツリーの 3 つの「状態」または「ツリー」があります。作業ディレクトリ (ectrory) は、Git リポジトリが関連付けられているファイル システム上の任意のディレクトリです。
featured image - 自信を持って Git の歴史を書き換える: ガイド
Omer Rosenbaum HackerNoon profile picture

開発者は常に Git を使用しています。


「うーん、私は今何をしたの?」と言ったことがありますか?

Git で問題が発生すると、多くのエンジニアは無力感を覚えます (出典: XKCD)


この投稿は、自信を持って歴史を書き換えるためのツールを提供します。

始める前の注意事項

  1. また、この投稿の内容をカバーするライブ トークも行いました。ビデオが好きな場合 (または読書と一緒に見たい場合) — あなたはそれを見つけることができます.


  2. Git に関する本を執筆中です。初期バージョンを読んでフィードバックを提供することに興味がありますか?メールを送ってください: [email protected]

Git での変更の記録

Git で元に戻す方法を理解する前に、Git で変更を記録する方法を理解する必要があります。すでにすべての用語を知っている場合は、この部分をスキップしてください。


Git をファイルシステムのスナップショットを適時に記録するためのシステムと考えると非常に便利です。 Git リポジトリを考えると、3 つの「状態」または「ツリー」があります。

Git リポジトリの 3 つの「ツリー」(出典: https://youtu.be/ozA1V00GIT8)


通常、ソース コードで作業するときは、作業ディレクトリから作業します。作業ディレクトリ (ectrory) (または作業ツリー) は、リポジトリが関連付けられているファイル システム内の任意のディレクトリです。


プロジェクトのフォルダーとファイル、および.gitというディレクトリが含まれています。 .gitフォルダーの内容については、以前の投稿.


いくつかの変更を行った後、それらをリポジトリに記録することをお勧めします。リポジトリ(要するに: repo ) はcommitsのコレクションであり、それぞれのコミットは、自分のマシン上か他の誰かのマシン上にあるかにかかわらず、過去の日付でプロジェクトの作業ツリーがどのように見えたかのアーカイブです。


リポジトリには、 HEADやブランチなど、コード ファイル以外のものも含まれます。


その間に、インデックスまたはステージング領域があります。これら 2 つの用語は交換可能です。ブランチcheckoutと、Git は、作業ディレクトリに最後にチェックアウトされたすべてのファイルの内容と、それらが最初にチェックアウトされたときの様子をインデックスに入力します。


git commitを使用すると、インデックスの状態に基づいてコミットが作成されます。


したがって、インデックス、またはステージング領域は、次のコミットの遊び場です。 indexで好きなことをしたり、ファイルを追加したり、何かを削除したりできます。準備ができたら、先に進んでリポジトリにコミットします。


ハンズオンの時間です🙌🏻


git init使用して、新しいリポジトリを初期化します。 1.txtというファイルにテキストを書き込みます。

新しいレポを開始し、その中に最初のファイルを作成する(出典: https://youtu.be/ozA1V00GIT8)


上記の 3 つのツリー状態のうち、 1.txt現在どこにありますか?


まだインデックスに導入されていないため、作業ツリー内。

ファイル「1.txt」は現在、作業ディレクトリのみの一部です(出典: https://youtu.be/ozA1V00GIT8)


ステージングしてインデックスに追加するには、 git add 1.txtを使用します。

「git add」を使用するとファイルがステージングされるため、インデックスにも含まれるようになりました(出典: https://youtu.be/ozA1V00GIT8)


これで、 git commit使用して変更をリポジトリにコミットできます。

「git commit」を使用すると、リポジトリにコミット オブジェクトが作成されます(出典: https://youtu.be/ozA1V00GIT8)


作業ツリー全体を記述するツリーへのポインターを含む、新しいコミット オブジェクトを作成しました。この場合、ルート フォルダー内の1.txtのみになります。ツリーへのポインターに加えて、コミット オブジェクトには、タイムスタンプや作成者情報などのメタデータが含まれます。


Git のオブジェクト (コミットやツリーなど) の詳細については、 私の以前の投稿をチェックしてください.


(はい、「チェックアウト」、しゃれが意図されています😇)


Git は、このコミット オブジェクトの SHA-1 値も教えてくれます。私の場合、それはc49f4baでした (スペースを節約するために、SHA-1 値の最初の 7 文字のみです)。


このコマンドを自分のマシンで実行すると、別の作成者であるため、別の SHA-1 値が取得されます。また、別のタイムスタンプでコミットを作成します。


リポジトリを初期化すると、Git は新しいブランチ (デフォルトではmainという名前) を作成します。とGit のブランチは、コミットへの名前付き参照にすぎません.したがって、デフォルトではmainブランチしかありません。複数のブランチがある場合はどうなりますか? Git はどのブランチがアクティブなブランチであるかをどのように認識しますか?


Git にはHEADと呼ばれる別のポインターがあります。これは (通常) ブランチを指し、次にコミットを指します。ところで、 フードの下、 HEAD は単なるファイルです。ブランチの名前といくつかのプレフィックスが含まれています。


リポジトリにさらに変更を加える時が来ました!


さて、もう一つ作りたいと思います。それでは、新しいファイルを作成して、前と同じようにインデックスに追加しましょう。

ファイル `2.txt` は、`git add` でステージングした後の作業ディレクトリとインデックスにあります (出典: https://youtu.be/ozA1V00GIT8)


では、 git commitを使用します。重要なことに、 git commit次の 2 つのことを行います。


まず、コミット オブジェクトが作成されるため、Git の内部オブジェクト データベース内に、対応する SHA-1 値を持つオブジェクトが存在します。この新しいコミット オブジェクトは、親コミットも指します。これは、 git commitコマンドを作成したときにHEADが指していたコミットです。

まず、新しい commit オブジェクトが作成されました — 「main」はまだ前の commit を指しています (出典: https://youtu.be/ozA1V00GIT8)


2 番目に、 git commitアクティブ ブランチのmainを移動します。

「git commit」は、新しく作成されたコミット オブジェクトを指すようにアクティブ ブランチも更新します(出典: https://youtu.be/ozA1V00GIT8)


変更の取り消し

履歴を書き換えるには、コミットを導入するプロセスを元に戻すことから始めましょう。そのために、非常に強力なツールであるコマンドgit resetについて学びます。

git reset --soft

つまり、前に行った最後のステップはgit commitでした。これは実際には 2 つのことを意味します。つまり、Git は commit オブジェクトを作成し、アクティブなブランチであるmainを移動しました。このステップを元に戻すには、コマンドgit reset --soft HEAD~1を使用します。


構文HEAD~1 HEADの最初の親を参照します。コミットグラフに複数のコミットがある場合は、「コミット 2」を指している「コミット 3」と言います。これは、「コミット 1」を指しています。


そして、 HEAD 「Commit 3」を指していたとします。 HEAD~1を使用して「コミット 2」を参照し、 HEAD~2を「コミット 1」を参照することができます。


それでは、コマンドに戻ります: git reset --soft HEAD~1


このコマンドは、Git にHEADが指すものを変更するように要求します。 (注: 以下の図では、「 HEADが指しているすべてのもの」に*HEADを使用しています)。この例では、 HEADmainを指しています。したがって、Git はmainのポインターをHEAD~1を指すように変更するだけです。つまり、 main 「コミット 1」を指します。


ただし、このコマンドは、インデックスまたは作業ツリーの状態には影響しませんでした。したがって、 git statusを使用するとgit commitを実行する前と同じように、 2.txtがステージングされていることがわかります。

「メイン」を「コミット 1」にリセットする(出典: https://youtu.be/ozA1V00GIT8)


git log? HEADから始まり、 mainに進み、次に「Commit 1」に進みます。これは、履歴から「Commit 2」に到達できなくなったことを意味することに注意してください。


「コミット2」のコミットオブジェクトが削除されたということでしょうか? 🤔


いいえ、削除されません。オブジェクトの Git の内部オブジェクト データベース内にまだ存在します。


git pushを使用して現在の履歴をプッシュすると、Git は「コミット 2」をリモート サーバーにプッシュしませんが、コミット オブジェクトはリポジトリのローカル コピーにまだ存在します。


ここで、再度コミットします。「コミット 2.1」のコミット メッセージを使用して、この新しいオブジェクトを元の「コミット 2」と区別します。

新しい commit の作成(出典: https://youtu.be/ozA1V00GIT8)


「Commit 2」と「Commit 2.1」はなぜ違うのですか?同じコミットメッセージを使用したとしても、それらが指しているとしても同じ木のオブジェクト( 1.txt2.txtで構成されるルート フォルダーの)、作成された時期が異なるため、タイムスタンプは異なります。


上の図では、Git の内部オブジェクト データベースにまだ存在していることを思い出させるために、「コミット 2」を残しました。 「Commit 2」と「Commit 2.1」の両方が「Commit 1」を指すようになりましたが、「Commit 2.1」のみがHEADから到達可能です。

Git リセット -- 混合

さかのぼってさらに元に戻す時が来ました。今回は、 git reset --mixed HEAD~1を使用します (注: --mixedgit resetのデフォルト スイッチです)。


このコマンドはgit reset --soft HEAD~1と同じように開始されます。つまり、 HEADが現在指しているポインタmainブランチ) を取得し、それをHEAD~1に設定します。この例では、「コミット 1」です。

`git reset --mixed` の最初のステップは `git reset --soft` と同じです (出典: https://youtu.be/ozA1V00GIT8)


次に、Git はさらに進んで、インデックスに加えた変更を効果的に元に戻します。つまり、最初のステップで設定した後の新しいHEADある現在のHEADと一致するようにインデックスを変更します。


git reset --mixed HEAD~1を実行すると、 HEADHEAD~1 (「コミット 1」) に設定され、Git はインデックスを「コミット 1」の状態に一致させることを意味します。 2.txtインデックスに含まれなくなることを意味します。

`git reset --mixed` の 2 番目のステップは、インデックスを新しい `HEAD` と一致させることです (出典: https://youtu.be/ozA1V00GIT8)


元の「コミット 2」の状態で新しいコミットを作成します。今回は、作成する前に2.txt再度ステージングする必要があります。

「Commit 2.2」の作成(出典: https://youtu.be/ozA1V00GIT8)


Git リセット -- ハード

続けて、さらに元に戻してください!


git reset --hard HEAD~1を実行してください。


繰り返しになりますが、Git は--softステージから開始し、 HEADが指すもの ( main ) をHEAD~1 (「コミット 1」) に設定します。

`git reset --hard` の最初のステップは `git reset --soft` と同じです (出典: https://youtu.be/ozA1V00GIT8)


ここまでは順調ですね。


次に、 --mixedステージに進み、インデックスをHEADと一致させます。つまり、Git は2.txtのステージングを取り消します。

`git reset --hard` の 2 番目のステップは、`git reset --mixed` と同じです (出典: https://youtu.be/ozA1V00GIT8)


Git がさらに進んで、作業ディレクトリをインデックスのステージと一致させる--hardステップの時間です。この場合、作業ディレクトリからも2.txtを削除することを意味します。

`git reset --hard` の 3 番目のステップは、作業ディレクトリの状態とインデックスの状態を一致させます (出典: https://youtu.be/ozA1V00GIT8)


(**注: この特定のケースでは、ファイルは追跡されていないため、ファイル システムから削除されません。ただし、 git resetを理解するためにはそれほど重要ではありません)。


Git に変更を加えるには、3 つのステップがあります。作業ディレクトリ、インデックス、またはステージング領域を変更し、それらの変更で新しいスナップショットをコミットします。これらの変更を元に戻すには:


  • git reset --softを使用すると、コミット ステップが取り消されます。


  • git reset --mixedを使用すると、ステージング ステップも元に戻します。


  • git reset --hardを使用すると、作業ディレクトリへの変更が元に戻されます。

リアルなシナリオ!

シナリオ #1

したがって、実際のシナリオでは、「私は Git が大好きです」とファイル ( love.txt ) に書き込みます。先に進み、これもステージングしてコミットします。

「Commit 2.3」の作成(出典: https://youtu.be/ozA1V00GIT8)


おっと!


実は、私はあなたにそれをコミットして欲しくありませんでした。


私が実際にあなたにして欲しかったのは、このファイルをコミットする前に、このファイルにいくつかの愛の言葉を書くことです.

あなたは何ができますか?


これを克服する 1 つの方法は、 git reset --mixed HEAD~1を使用して、実行したコミットとステージングの両方のアクションを効果的に元に戻すことです。

ステージングとコミットの手順を元に戻す(出典: https://youtu.be/ozA1V00GIT8)


したがってmain再び「コミット 1」を指し示し、 love.txtもはやインデックスの一部ではありません。ただし、ファイルは作業ディレクトリに残ります。先に進み、さらにコンテンツを追加できます。

愛の歌詞を追加(出典: https://youtu.be/ozA1V00GIT8)


ファイルをステージングしてコミットします。

目的の状態で新しい commit を作成する(出典: https://youtu.be/ozA1V00GIT8)


よくやった👏🏻


「Commit 1」を指している「Commit 2.4」のこの明確で素晴らしい歴史があります。


ツールボックスに新しいツールgit reset追加されました 💪🏻

git reset がツールボックスに追加されました(出典: https://youtu.be/ozA1V00GIT8)


このツールは非常に便利で、ほとんど何でも実現できます。常に最も便利なツールというわけではありませんが、慎重に使用すれば、ほぼすべての書き換え履歴シナリオを解決できます。


初心者の場合、Git で元に戻したいときはほぼいつでもgit resetのみを使用することをお勧めします。慣れてきたら、他のツールに移ります。

シナリオ 2

別のケースを考えてみましょう。


new.txtという新しいファイルを作成します。ステージングとコミット:

「new.txt」と「コミット 3」の作成(出典: https://youtu.be/ozA1V00GIT8)


おっと。実はそれは間違いです。あなたはmainにいましたが、機能ブランチでこのコミットを作成してほしいと思いました。私の悪い😇


この記事からあなたに取ってもらいたい最も重要なツールが 2 つあります。 2 つ目はgit resetです。最初の、そしてはるかに重要なことは、現在の状態とあなたがなりたい状態をホワイトボードに載せることです.


このシナリオでは、現在の状態と目的の状態は次のようになります。

シナリオ #2: 現在の状態と望ましい状態 (出典: https://youtu.be/ozA1V00GIT8)


次の 3 つの変更点に気付くでしょう。


  1. main現在の状態では「コミット 3」(青い部分) を指していますが、目的の状態では「コミット 2.4」を指しています。


  2. featureブランチは現在の状態には存在しませんが、存在し、目的の状態の「コミット 3」を指しています。


  3. HEAD現在の状態ではmainを指し、目的の状態ではfeatureを指します。


これを描くことができ、 git reset使い方を知っていれば、間違いなくこの状況から抜け出すことができます。


繰り返しますが、最も重要なことは、息を吸ってこれを引き出すことです.


上の図を見て、どうすれば現在の状態から望ましい状態になるのでしょうか?


もちろん、いくつかの異なる方法がありますが、シナリオごとに 1 つのオプションのみを提示します。他のオプションも自由に試してみてください。


git reset --soft HEAD~1を使用して開始できます。これにより、 main前のコミット「Commit 2.4」を指すように設定されます。

「メイン」を変更します。 「コミット 3 はまだそこにあるためぼやけていますが、到達できないだけです (出典: https://youtu.be/ozA1V00GIT8)


current-vs-desired の図をもう一度見てみると、新しいブランチが必要であることがわかりますよね? git switch -c featureまたはgit checkout -b feature (同じことを行います) を使用できます。

「feature」ブランチの作成(出典: https://youtu.be/ozA1V00GIT8)


このコマンドは、新しいブランチを指すようにHEADも更新します。


git reset --softを使用したため、インデックスを変更していないため、現在、コミットしたい状態とまったく同じです — なんと便利なことでしょう! featureブランチにコミットするだけです。

「feature」ブランチへのコミット(出典: https://youtu.be/ozA1V00GIT8)


そして、あなたは望ましい状態になりました🎉

シナリオ #3

あなたの知識を他のケースに適用する準備はできましたか?


love.txtにいくつかの変更を加え、さらにcool.txtという名前の新しいファイルを作成します。それらをステージングしてコミットします。

「コミット 4」の作成(出典: https://youtu.be/ozA1V00GIT8)


ああ、おっと、実際には、変更ごとに 1 つずつ、2 つの別々のコミットを作成してほしかった 🤦🏻

これを自分で試してみませんか?


コミットとステージングの手順を元に戻すことができます。

`git reset --mixed HEAD~1` を使用してコミットとステージングを元に戻します (ソース: https://youtu.be/ozA1V00GIT8)


このコマンドを実行すると、インデックスにはこれら 2 つの変更が含まれなくなりますが、両方ともファイル システムに残ります。したがって、 love.txtのみをステージングする場合は、個別にコミットしてから、 cool.txtに対して同じことを行うことができます。

個別にコミットする(出典: https://youtu.be/ozA1V00GIT8)


ナイス😎

シナリオ #4

テキストを含む新しいファイル ( new_file.txt ) を作成し、テキストをlove.txtに追加します。両方の変更をステージングし、コミットします。

新しいコミット(出典: https://youtu.be/ozA1V00GIT8)


おっと🙈🙈


今回は、新しいブランチではなく、既存のブランチではなく、別のブランチに配置したいと考えました。


それで、あなたは何ができますか?


ヒントをあげます。答えは本当に短く、とても簡単です。最初に何をしますか?


いいえ、 resetしません。私たちは描く。他のすべてがずっと簡単になるので、それが最初に行うことです。これが現在の状態です。

「メイン」の新しいコミットは青色で表示されます(出典: https://youtu.be/ozA1V00GIT8)


そして望ましい状態?

「青い」コミットを別の「既存の」ブランチに配置したい(出典: https://youtu.be/ozA1V00GIT8)


現在の状態から目的の状態にどのように移行しますか? 最も簡単なのはどれですか?


先ほどのようにgit resetを使うのもひとつの方法ですが、別の方法も試していただきたいです。


まず、 existingブランチを指すようにHEADを移動します。

「既存の」ブランチに切り替えます(出典: https://youtu.be/ozA1V00GIT8)


直観的に、青いコミットで導入された変更を取得し、これらの変更をexistingブランチの上に適用 (「コピー アンド ペースト」) する必要があります。 Git にはそのためのツールがあります。


このコミットとその親コミットの間に導入された変更を取得し、これらの変更をアクティブなブランチに適用するように Git に依頼するには、 git cherry-pickを使用できます。このコマンドは、指定されたリビジョンで導入された変更を取得し、アクティブなコミットに適用します。


また、新しいコミット オブジェクトを作成し、この新しいオブジェクトを指すようにアクティブ ブランチを更新します。

`git cherry-pick` の使用 (出典: https://youtu.be/ozA1V00GIT8)


上記の例では、作成されたコミットの SHA-1 識別子を指定しましたが、変更を適用するコミットがmainが指しているコミットであるため、 git cherry-pick mainを使用することもできます。


しかし、これらの変更がmainブランチに存在することは望ましくありません。 git cherry-pick変更をexistingブランチにのみ適用しました。それらをmainからどのように削除できますか?


1 つの方法は、 mainswitchからgit reset --hard HEAD~1を使用することです。

「メイン」のリセット(出典: https://youtu.be/ozA1V00GIT8)


できたね! 💪🏻


git cherry-pick実際には、指定されたコミットとその親の違いを計算し、それらをアクティブなコミットに適用することに注意してください。これは、競合が発生する可能性があるため、Git がこれらの変更を適用できない場合があることを意味しますが、それは別の投稿のトピックです。


また、ブランチによって参照されるコミットだけでなく、任意のコミットで導入された変更をcherry-pickように Git に依頼できることに注意してください。


新しいツールを取得したので、 git resetgit cherry-pickを使用しています。

シナリオ 5

さて、別の日、別のレポ、別の問題。


コミットを作成します。

別のコミット(出典: https://youtu.be/ozA1V00GIT8)


そして、それをリモート サーバーにpush

(出典: https://youtu.be/ozA1V00GIT8)


うーん、おっと😓…


私はちょうど何かに気づきました。そこにタイプミスがあります。 This is This is more text This is more teztと書きました。おっと。では、今の大きな問題は何ですか?私は ed push 。つまり、他の誰かがすでにそれらの変更をpull ed している可能性があります。


これまで行ってきたように、 git resetを使用してこれらの変更をオーバーライドすると、異なる履歴が作成され、すべてが崩壊する可能性があります。 pushするまでは、自分のレポのコピーを好きなだけ書き換えることができます。


変更をpushしたら、履歴を書き換える場合は、他の誰もそれらの変更を取得していないことを十分に確認する必要があります。


または、 git revertという別のツールを使用することもできます。このコマンドは、提供しているコミットを取得し、 git cherry-pickと同様に、その親コミットから Diff を計算しますが、今回は逆の変更を計算します。


したがって、指定されたコミットで行を追加した場合、その逆は行を削除し、その逆も同様です。

「git revert」を使用して変更を元に戻します(出典: https://youtu.be/ozA1V00GIT8)


git revert新しいコミット オブジェクトを作成しました。これは、履歴への追加であることを意味します。 git revert使用することで、履歴を書き換えませんでした。あなたは過去の過ちを認めました。このコミットは、あなたが間違いを犯し、それを修正したことを認めたものです。


それがより成熟した方法だと言う人もいます。 git resetを使用して以前のコミットを書き換えた場合に得られるほどクリーンな履歴ではないと言う人もいます。しかし、これは歴史の書き換えを避ける方法です。


タイプミスを修正して、再度コミットできます。

変更をやり直す(出典: https://youtu.be/ozA1V00GIT8)


あなたのツールボックスには、新しい輝かしいツールrevertがロードされました:

ツールボックス(出典: https://youtu.be/ozA1V00GIT8)


シナリオ #6

作業を完了し、コードを記述して、 love.txtに追加します。この変更をステージングし、コミットします。

別のコミット(出典: https://youtu.be/ozA1V00GIT8)


私は自分のマシンで同じことを行い、キーボードの上Upキーを使用して前のコマンドにスクロールして戻り、 Enterを押して…うわー。


おっと。

私はちょうど `git reset -- hard` でしたか? (出典: https://youtu.be/ozA1V00GIT8)


git reset --hardを使用しただけですか? 😨


実際に何が起こったのですか? Git はポインターをHEAD~1に移動したため、現在の履歴からは、すべての貴重な作業を含む最後のコミットに到達できません。また、Git はステージング領域からすべての変更をステージング解除し、作業ディレクトリをステージング領域の状態に一致させました。


つまり、私の仕事がなくなったこの状態にすべてが一致します。


フリークアウトタイム。怖がら。

しかし、本当に、びっくりする理由はありますか?そうではありません… 私たちはリラックスした人々です。私たちは何をしますか?さて、直観的に、コミットは本当に、本当になくなったのでしょうか?いいえ、なぜですか? Git の内部データベース内にまだ存在します。


その場所さえわかれば、このコミットを識別する SHA-1 値がわかるので、復元できます。元に戻す操作を元に戻し、このコミットにresetこともできました。


したがって、ここで本当に必要なのは、「削除された」コミットの SHA-1 だけです。


問題は、どうすればそれを見つけることができるかということです。 git log役に立ちますか?


まあ、そうではありません。 git log 、探しているコミットの親コミットを指すmainを指すHEADに移動します。次に、 git log親チェーンをトレースバックしますが、これには私の貴重な作業のコミットは含まれません。

この場合、「git log」は役に立ちません(出典: https://youtu.be/ozA1V00GIT8)


ありがたいことに、Git を作成した非常に頭の良い人たちは、バックアップ プランも作成してくれました。これはreflogと呼ばれます。


Git で作業しているときに、 git reset使用して行うことができるHEADでなく、 git switchgit checkoutなどの他のコマンドを変更するたびに、Git はエントリをreflogに追加します。


`git reflog` は、`HEAD` がどこにあったかを示しています (出典: https://youtu.be/ozA1V00GIT8)


コミットが見つかりました! 0fb929eで始まるものです。


HEAD@{1}という「ニックネーム」で関連付けることもできます。 Git はHEAD~1を使用してHEADの最初の親を取得し、 HEAD~2を使用してHEADの 2 番目の親を参照するなど、Git はHEAD@{1}を使用してHEADの最初の reflog 親を参照します。前の手順でHEAD指していた場所。


git rev-parseにその値を表示するように依頼することもできます。

(出典: https://youtu.be/ozA1V00GIT8)


reflogを表示する別の方法は、 git log -gを使用することです。これは、 git logに実際にreflogを考慮するように要求します。

`git log -g` の出力 (出典: https://youtu.be/ozA1V00GIT8)


上記のように、 reflog HEADと同様に、「コミット 2」を指すmainを指しています。しかし、 reflog内のそのエントリの親は「コミット 3」を指しています。


したがって、「コミット 3」に戻るには、 git reset --hard HEAD@{1} (または「コミット 3」の SHA-1 値) を使用できます。

(出典: https://youtu.be/ozA1V00GIT8)


そして今、 git log実行すると:

私たちの歴史が戻ってきました!!! (出典: https://youtu.be/ozA1V00GIT8)


私たちはその日を救いました! 🎉👏🏻


このコマンドをもう一度使用するとどうなりますか? git commit --reset HEAD@{1}を実行しましたか? Git はHEADを、最後のreset前にHEADが指していた場所、つまり「コミット 2」に設定します。私たちは一日中続けることができます:

(出典: https://youtu.be/ozA1V00GIT8)


ツールボックスを見ると、Git でうまくいかない多くのケースを解決するのに役立つツールが満載です。

私たちのツールボックスは非常に広範囲です! (出典: https://youtu.be/ozA1V00GIT8)


これらのツールを使用すると、Git の仕組みをよりよく理解できるようになります。具体的にはgit rebaseなど、履歴を書き換えることができるツールは他にもありますが、この投稿ですでに多くのことを学んでいます。今後の投稿では、 git rebaseについても掘り下げます。


このツールボックスにリストされている 5 つのツールよりもさらに重要な最も重要なツールは、現在の状況と望ましい状況をホワイトボードで示すことです。これで私を信じてください、それはすべての状況を困難に思わせず、解決策をより明確にします.

Git の詳細

また、この投稿の内容をカバーするライブ トークも行いました。ビデオが好きな場合 (または読書と一緒に見たい場合) — あなたはそれを見つけることができます.


一般に、私の YouTube チャンネルGit とその内部の多くの側面をカバーしています。あなたは歓迎されています見てみな(しゃれのつもり😇)

著者について

オマー・ローゼンバウムのCTO兼共同創設者です。スイムは、開発者とそのチームが最新の内部ドキュメントを使用してコードベースに関する知識を管理するのに役立つ開発ツールです。 Omer は、Check Point Security Academy の創設者であり、ITC でサイバー セキュリティ リードを務めていました。ITC は、有能な専門家を訓練してテクノロジのキャリアを開発する教育機関です。


Omer は、テルアビブ大学で言語学の修士号を取得しており、簡単な YouTube チャンネル.


ここで初公開