paint-brush
git reflog を使用して Git 履歴を効果的に書き換える時が来ましたby@pragativerma
5,441
5,441

git reflog を使用して Git 履歴を効果的に書き換える時が来ました

Pragati Verma2022/05/09
Read on Terminal Reader
Read this story w/o Javascript

Git は、コミットされた変更が失われないように、さまざまな方法で変更を記録します。 reflog は参照であり、多くの場合「ref**」と呼ばれ、多くの Git コマンドがパラメーターとして受け入れるコミットまたはブランチへのポインターです。デフォルトでは、reflog は過去 90 日間の各 `HEAD` 位置を追跡します。 reflog 履歴はリポジトリ専用であり、リモートからアクセスすることはできません。各 reflog エントリにはタイムスタンプが添付されており、Git ref ポインター構文の修飾子トークンとしても利用できます。

Company Mentioned

Mention Thumbnail
featured image - git reflog を使用して Git 履歴を効果的に書き換える時が来ました
Pragati Verma HackerNoon profile picture


Git は現在最も広く使用されているバージョン管理システムであり、さまざまな方法で変更を追跡して、コミットされた変更が失われないようにします。さらに、開発ワークフローを制御できるということは、プロジェクトの履歴がどのように見えるかを正確に判断できることを意味します。 Git には、 git commit --amendgit rebasegit reflog reflog など、コミット履歴を書き換えるためのメカニズムがいくつかあります。


この記事では、 git reflogを利用して、Git コミット履歴を効果的かつ簡単に再編成および書き換える方法を学びます。同時に、コミット履歴の書き換えがもたらすリスクを軽減します。


リログとは?

Git は、参照ログ、または単に「 reflog 」と呼ばれるシステムを使用して、ブランチのヒントの変更を追跡します。多くの場合「 ref 」と呼ばれる参照は、多くの Git コマンドがパラメーターとして受け入れるコミットまたはブランチへのポインターです。 git checkoutgit reset 、およびgit mergeは、参照をパラメーターとして受け入れるいくつかの一般的な git コマンドの例です。


デフォルトでは、reflog は過去 90 日間の各HEAD位置を追跡します。さらに、reflog 履歴はリポジトリ専用であり、リモートからアクセスすることはできません。ブランチ チップの reflog とは別に、 Git stash用の別の reflog があります。


reflog は、ローカル リポジトリの.gitディレクトリの下の特定のディレクトリに保存されます。これらのgit reflogディレクトリは.git/logs/refs/heads/..git/logs/HEAD 、およびリポジトリでgit stashが使用されている場合は.git/logs/refs/stash


基本構成

基本的な reflog コマンドは次のとおりです。

 # To see activity on HEAD git reflog show


上記のコマンドの出力は、次のようになります。

 0a2e358 HEAD@{0}: reset: moving to HEAD~2 0254ea7 HEAD@{1}: checkout: moving from 2.2 to main c10f740 HEAD@{2}: checkout: moving from main to 2.2


その他の一般的な使用法は次のとおりです。

 # To see activity on HEAD, including timestamp git reflog show --date=relative #or git reflog --relative-date # same, on some_branch git reflog show --date=relative some_branch


Reflog への参照

デフォルトでは、 git reflogHEAD ref の reflog を出力します。シンボルHEADは、現在アクティブなブランチを示します。他の参照に使用できる reflog もあります。 git ref にアクセスするために使用される構文は、 name@{qualifier}です。たとえば、 - otherbranch@{0}です。 HEAD参照に加えて、他のブランチ、タグ、リモート、および Git stash も参照できます。


すべての参照の完全な reflog を表示するには、次を実行できます。

 git reflog show --all


順序付けられたインデックス以外に、各 reflog エントリにはタイムスタンプが添付されており、Git ref ポインター構文の修飾子トークンとしても利用できます。これにより、これらの reflog エントリを時間でフィルタリングできます。一般的に使用される時間修飾子の例は次のとおりです。

  • @{0}
  • @{6.minutes.ago}
  • @{2.hour.ago}
  • @{3.day.ago}
  • @{5.weeks.ago}
  • @{8.years.ago}
  • @{today}
  • @{2022-01-23.08:30:00}
  • @{1.day.10.hours.ago}


これらの時間修飾子は組み合わせることができます (例: 1.day.3.hours.ago )。これらの時間修飾子の複数形も受け入れられます (例: 5.minutes.ago )。これらは、次のようにgit reflogコマンドと一緒に使用できます。


 git reflog show develop@{3.days.ago}


サブコマンドと設定オプション

git reflogは、 showexpiredeleteなどのサブコマンドと見なされる追加の引数を受け入れます。これらのサブコマンドについて詳しく説明しましょう。


git reflog ショー

前に説明したように、 showはデフォルトで暗黙的に渡されます。 git reflog showを実行すると、渡された引数のログが表示されます。


例えば:

 git reflog develop@{0}


と同じです

git reflog show develop@{0}


さらに、 git reflog showgit log -g --abbrev-commit --pretty=onelineのエイリアスです。


git reflog の有効期限が切れる

expireサブコマンドは、古いまたは到達不能な reflog エントリをクリーンアップするのに役立ちます。


expireサブコマンドは、データ損失を引き起こす可能性があります。


ただし、このサブコマンドは通常、エンド ユーザーによって使用されるのではなく、git 内部で使用されます。


「ドライラン」は、 -nまたは--dry-runオプションをgit reflog expireに渡すことで実行でき、実際にはプルーニングされないように、どの reflog エントリがプルーニング対象としてマークされているかを出力します。これは、期限切れの reflog エントリをクリーンアップする際のセーフティ ネットとして役立ちます。


さらに、有効期限は、コマンドライン引数--expire=timegit reflog expireに渡すか、 gc.reflogExpireの git 構成名を設定することで指定できます。


git reflog 削除

delete サブコマンドは、その名前が示すように、渡された reflog エントリを削除します。削除は、期限切れと同様に、データ損失を引き起こす可能性があり、エンド ユーザーが頻繁に使用するものではありません。


git reflog と git log

git refloggit logは、Git が提供する名前が似ている 2 つのコンポーネントで、リポジトリのコミット履歴、ログ、および reflog に忍び込むことができます。 2 つのコンポーネントが同じ履歴を示すことが多いという事実は、特に開発者がフェッチまたはプルなしで多数のローカル コミットを完了した場合に、Git reflog とログの混乱の理由の 1 つです。

ただし、これらは本質的に異なり、使用例も異なります。


上記の 2 つのコマンドの基本的な違いと類似点を理解しましょう。


Git reflog とログの最も顕著な違いは、ログがリポジトリのコミット履歴の公開記録であるのに対し、reflog はリポジトリのローカル コミットの非公開のワークスペース固有の記録であることです。


プッシュ、フェッチ、またはプルの後、Git ログは Git リポジトリの一部として複製されます。一方、Git reflog は、複製されたリポジトリには含まれません。ローカル リポジトリが保持されているコンピューターに物理的にアクセスできないと、開発者は reflog を調べることができません。


reflog は.git\logs\refs\headsにあるファイルで、特定のブランチのローカル コミットの履歴を追跡し、Git ガベージ コレクション プロセスによって取り除かれた可能性のあるコミットを除外します。一方、Git ログは、ブランチの履歴のコミット トラバーサルを提供します。これは、最新のコミットから始まり、ブランチの履歴の最初のコミットで終了します。


安全策としての Git reflog

Git reflog は、reflog の概念を正しく理解していれば、コミット後にリポジトリからデータを失うことがないため、開発中のセーフティ ネットとして使用できます。意図せずに古いコミットにリセットしたり、誤ってリベースしたり、目に見えて「削除」する他の操作を実行した場合は、reflog を使用して以前の場所を確認し、 git reset --hardを使用してその ref に戻って以前の状態に戻すことができます。コミットします。


参照は、コミット自体だけでなく、コミットの完全な履歴を参照することに注意してください。


結論

この記事では、 git reflogの拡張構成オプション、一般的なユースケース、およびgit reflogの落とし穴について説明しました。


要約すると、Git は reflog を保持します。これは、 HEADとブランチの参照が過去数か月 (90 日間) のログであり、作業中にバックグラウンドで行われます。 Git は、何らかの理由でブランチ ヒントが変更されるたびに、この一時履歴に情報を保存します。


reflog コマンドを使用して、古すぎるエントリを reflog から削除または期限切れにすることもできます。 expire the サブコマンドは、古い reflog エントリを削除するために使用され、 deleteサブコマンドは、reflog から削除する特定のエントリを削除および指定するために使用されます。