Git
英語 ▾ トピック ▾ 最新バージョン ▾ git-maintenance は 2.47.0 で最後に更新されました

名前

git-maintenance - Git リポジトリデータを最適化するタスクを実行します

概要

git maintenance run [<options>]
git maintenance start [--scheduler=<scheduler>]
git maintenance (stop|register|unregister) [<options>]

説明

Git リポジトリデータを最適化し、他の Git コマンドの速度を向上させ、リポジトリのストレージ要件を削減します。

git addgit fetch などのリポジトリデータを追加する Git コマンドは、反応の良いユーザーエクスペリエンスのために最適化されています。これらのコマンドは、Git データの最適化に時間をかけません。これは、このような最適化がリポジトリの全サイズに比例するのに対し、これらのユーザーコマンドはそれぞれ比較的小さなアクションを実行するためです。

git maintenance コマンドは、Git リポジトリを最適化する方法の柔軟性を提供します。

サブコマンド

run

1つ以上のメンテナンスタスクを実行します。1つ以上の--taskオプションが指定されている場合、それらのタスクはその順序で実行されます。それ以外の場合は、どのmaintenance.<task>.enabled設定オプションがtrueであるかによってタスクが決定されます。デフォルトでは、maintenance.gc.enabledのみがtrueです。

start

現在のリポジトリでメンテナンスの実行を開始します。これはregisterサブコマンドと同じ設定の更新を行い、バックグラウンドスケジューラを更新して、1時間ごとにgit maintenance run --scheduledを実行します。

stop

バックグラウンドメンテナンススケジュールを停止します。バックグラウンドメンテナンスが後で再開される場合に備えて、現在のリポジトリはメンテナンス対象のリポジトリのリストから削除されません。

register

スケジュールされたメンテナンスがすべてこのリポジトリで開始されるように、Git 設定値を初期化します。これは、現在のユーザーのグローバル設定、または --config-file オプションで指定された設定に、maintenance.repo設定変数にリポジトリを追加し、maintenance.<task>.scheduleに対して推奨される設定値を有効にします。有効になっているタスクは、フォアグラウンドプロセスを中断することなくバックグラウンドで実行するのに安全です。

registerサブコマンドは、この値が事前に設定されていない場合、maintenance.strategy設定値をincrementalに設定します。incremental戦略は、各メンテナンスタスクに対して次のスケジュールを使用します。

  • gc: 無効。

  • commit-graph: 毎時。

  • prefetch: 毎時。

  • loose-objects: 毎日。

  • incremental-repack: 毎日。

git maintenance registerは、現在のリポジトリでmaintenance.auto = falseを設定することにより、フォアグラウンドメンテナンスも無効にします。この設定は、git maintenance unregisterコマンドの後も残ります。

unregister

バックグラウンドメンテナンスから現在のリポジトリを削除します。これは、設定されたリストからリポジトリを削除するだけです。バックグラウンドメンテナンスプロセスが実行されるのを停止しません。

unregisterサブコマンドは、現在のリポジトリがまだ登録されていない場合、エラーを報告します。現在のリポジトリが登録されていない場合でも成功を返すには、--forceオプションを使用します。

タスク

commit-graph

commit-graphジョブはcommit-graphファイルをインクリメンタルに更新し、書き込まれたデータが正しいことを検証します。インクリメンタル書き込みは、前のcommit-graph-chainファイルにあった.graphファイルを期限切れにしないため、同時実行のGitプロセスと同時に実行しても安全です。それらは、期限切れの遅延に基づいて、後の実行によって削除されます。

prefetch

prefetchタスクは、登録されているすべてのリモートから最新のオブジェクトを使用してオブジェクトディレクトリを更新します。各リモートに対して、git fetchコマンドが実行されます。設定されたrefspecは、要求されたすべてのrefをrefs/prefetch/内に配置するように変更されます。また、タグは更新されません。

これは、リモート追跡ブランチを中断しないために行われます。エンドユーザーは、フェッチを開始しない限り、これらのrefは移動されたままになることを期待しています。しかし、prefetchタスクを使用すると、後の実際のフェッチを完了するために必要なオブジェクトは既に取得されているため、実際のフェッチが高速になります。理想的なケースでは、オブジェクト転送なしで、多くのリモート追跡ブランチの更新になるだけです。

remote.<name>.skipFetchAll設定を使用して、特定のリモートをプリフェッチから除外できます。

gc

不要なファイルをクリーンアップし、ローカルリポジトリを最適化します。「GC」は「ガベージコレクション」を意味しますが、このタスクは多くの小さなタスクを実行します。このタスクは、大きなリポジトリでは高価になる可能性があります。これは、すべてのGitオブジェクトを単一のpackファイルに再パックするためです。古いデータを削除するため、状況によっては中断することもあります。Gitでのガベージコレクションの詳細については、git-gc[1]を参照してください。

loose-objects

loose-objectsジョブは、ルーズオブジェクトをクリーンアップし、packファイルに配置します。同時実行のGitコマンドとの競合状態を防ぐために、2段階のプロセスに従います。まず、既にpackファイルに存在するルーズオブジェクトを削除します。同時実行のGitプロセスは、ルーズオブジェクトではなくpackファイルでオブジェクトデータを確認します。次に、「loose-」で始まる新しいpackファイルを作成し、一括のルーズオブジェクトを含めます。バッチサイズは、ジョブが多くのルーズオブジェクトを持つリポジトリで長すぎる時間を費やすのを防ぐために、5万オブジェクトに制限されています。gcタスクは、到達不能なオブジェクトをルーズオブジェクトとして書き込み、packファイルに再追加されない場合にのみ、後のステップでクリーンアップします。このため、loose-objectsタスクとgcタスクの両方を同時に有効にすることはお勧めできません。

incremental-repack

incremental-repackジョブは、multi-pack-index機能を使用してオブジェクトディレクトリを再パックします。同時実行のGitコマンドとの競合状態を防ぐために、2段階のプロセスに従います。まず、git multi-pack-index expireを呼び出して、multi-pack-indexファイルによって参照されていないpackファイルを削除します。次に、git multi-pack-index repackを呼び出して、いくつかの小さなpackファイルを選択し、それらをより大きなファイルに再パックし、小さなpackファイルを指すmulti-pack-indexのエントリを新しいpackファイルを指すように更新します。これにより、git multi-pack-index expireの次回実行時に、それらの小さなpackファイルを削除する準備が整います。小さなpackファイルの選択は、大きなpackファイルの予想サイズがバッチサイズ以上になるように行われます。git-multi-pack-indexrepackサブコマンドの--batch-sizeオプションを参照してください。git-multi-pack-index[1]。デフォルトのバッチサイズは0で、これはすべてのpackファイルを単一のpackファイルに再パックしようとする特別なケースです。

pack-refs

pack-refsタスクは、ルーズな参照ファイルを収集し、それらを単一のファイルに収集します。これにより、多くの参照を反復処理する必要がある操作の速度が向上します。詳細については、git-pack-refs[1]を参照してください。

オプション

--auto

runサブコマンドと組み合わせて使用すると、特定のしきい値が満たされた場合にのみ、メンテナンスタスクを実行します。たとえば、gcタスクは、ルーズオブジェクトの数がgc.auto設定に格納されている数を超えた場合、またはpackファイルの数がgc.autoPackLimit設定を超えた場合に実行されます。--scheduleオプションとは互換性がありません。

--schedule

run サブコマンドと組み合わせると、各<task>maintenance.<task>.schedule 設定値で指定された特定の時間条件が満たされた場合にのみ、メンテナンスタスクを実行します。この設定値は、maintenance.<task>.lastRun 設定値に従って、そのタスクが最後に実行されてからの秒数を指定します。テストされるタスクは、--task=<task> オプションで指定されたタスク、またはmaintenance.<task>.enabled が true に設定されているタスクです。

--quiet

stderrへの進捗状況やその他の情報の報告を行いません。

--task=<task>

このオプションを1回以上指定すると、指定されたタスクを指定された順序で実行するのみとなります。--task=<task>引数が指定されていない場合、maintenance.<task>.enabledtrue として設定されているタスクのみが考慮されます。受け入れられる<task>値の一覧については、「タスク」セクションを参照してください。

--scheduler=auto|crontab|systemd-timer|launchctl|schtasks

start サブコマンドと組み合わせると、git maintenance run の毎時、毎日、毎週の実行のためのスケジューラを指定します。<scheduler> の可能な値は、autocrontab (POSIX)、systemd-timer (Linux)、launchctl (macOS)、および schtasks (Windows) です。auto を指定すると、適切なプラットフォーム固有のスケジューラが使用されます。Linux では、systemd-timer が使用可能な場合はそれを使用し、そうでない場合は crontab を使用します。デフォルトは auto です。

トラブルシューティング

git maintenance コマンドは、Gitコマンド実行時のユーザー待機時間を最小限に抑えながら、リポジトリメンテナンスパターンを簡素化するために設計されています。このプロセスをカスタマイズするために、さまざまな設定オプションが用意されています。デフォルトのメンテナンスオプションは、大規模なリポジトリでも迅速に完了する操作に重点を置いています。

スケジュールされたメンテナンスタスクが意図した頻度で実行されない場合があることに、ユーザーは気付くかもしれません。各git maintenance run コマンドはリポジトリのオブジェクトデータベースにロックをかけ、これにより、同じリポジトリで他の同時実行中のgit maintenance run コマンドの実行を防ぎます。この安全策がないと、競合するプロセスによってリポジトリが予測できない状態になる可能性があります。

バックグラウンドメンテナンススケジュールは、1時間ごとにgit maintenance runプロセスを実行します。各実行では、「hourly」タスクが実行されます。真夜中になると、そのプロセスは「daily」タスクも実行します。週の最初の日の真夜中になると、そのプロセスは「weekly」タスクも実行します。単一のプロセスは、登録された各リポジトリを繰り返し処理し、その頻度に対するスケジュールされたタスクを実行します。登録されているリポジトリの数とそれらのサイズによっては、このプロセスは1時間以上かかる場合があります。この場合、同じリポジトリで複数のgit maintenance runコマンドが同時に実行され、オブジェクトデータベースロックで競合する可能性があります。これにより、2つのタスクのいずれかが実行されません。

メンテナンスウィンドウの完了に1時間以上かかることが判明した場合は、メンテナンスタスクの複雑さを軽減することを検討してください。たとえば、gc タスクはincremental-repack タスクよりもはるかに遅いです。ただし、これはオブジェクトデータベースがわずかに大きくなるというコストを伴います。よりコストのかかるタスクは、実行頻度を減らすようにしてください。

上級ユーザーは、git maintenance start と Git 設定オプションで利用可能なものとは異なるスケジュールを使用して、独自のメンテナンスタスクをスケジュールすることを検討できます。これらのユーザーは、オブジェクトデータベースロックと、同時実行中のgit maintenance run コマンドの動作を理解しておく必要があります。さらに、git gc コマンドはgit maintenance run コマンドと組み合わせるべきではありません。git gc はオブジェクトデータベースを変更しますが、git maintenance run と同じ方法でロックを取得しません。可能であれば、git gc の代わりにgit maintenance run --task=gcを使用してください。

以下のセクションでは、git maintenance startによるバックグラウンドメンテナンスの実行に備えられたメカニズムと、それらをカスタマイズする方法について説明します。

POSIX システムでのバックグラウンドメンテナンス

POSIXシステムでバックグラウンドタスクをスケジュールするための標準的なメカニズムはcron(8)です。このツールは、指定されたスケジュールに基づいてコマンドを実行します。ユーザーがスケジュールしたタスクの現在のリストは、crontab -l を実行することで確認できます。git maintenance startによって書き込まれるスケジュールはこれと似ています。

# BEGIN GIT MAINTENANCE SCHEDULE
# The following schedule was created by Git
# Any edits made in this region might be
# replaced in the future by a Git command.

0 1-23 * * * "/<path>/git" --exec-path="/<path>" for-each-repo --config=maintenance.repo maintenance run --schedule=hourly
0 0 * * 1-6 "/<path>/git" --exec-path="/<path>" for-each-repo --config=maintenance.repo maintenance run --schedule=daily
0 0 * * 0 "/<path>/git" --exec-path="/<path>" for-each-repo --config=maintenance.repo maintenance run --schedule=weekly

# END GIT MAINTENANCE SCHEDULE

コメントは、Gitによって書き込まれたスケジュールをマークする領域として使用されます。この領域内の変更は、git maintenance stop によって完全に削除されるか、git maintenance start によって上書きされます。

crontab エントリは、git 実行可能ファイルの完全パスを指定して、実行された git コマンドが、PATH に関係なく、git maintenance start が発行されたものと同じであることを保証します。同じユーザーが複数のGit実行可能ファイルでgit maintenance startを実行した場合、最後に使用された実行可能ファイルのみが使用されます。

これらのコマンドは、git for-each-repo --config=maintenance.repoを使用して、複数値のmaintenance.repo 設定オプションにリストされている各リポジトリでgit maintenance run --schedule=<frequency>を実行します。これらは通常、ユーザー固有のグローバル設定からロードされます。次に、git maintenance プロセスは、maintenance.<task>.schedule 設定オプションを使用して、各<frequency>で各リポジトリで実行するように構成されているメンテナンスタスクを決定します。これらの値は、グローバルまたはリポジトリの設定値からロードされます。

設定値が目的のバックグラウンドメンテナンススケジュールを達成するのに不十分な場合は、独自のスケジュールを作成できます。crontab -e を実行すると、ユーザー固有の cron スケジュールを含むエディターがロードされます。そのエディターで、独自のスケジュール行を追加できます。最初に、先にリストされているデフォルトのスケジュールを適用するか、crontab(5) のドキュメントを読んで高度なスケジューリング技術を確認できます。スケジュールで正しいバイナリを実行するには、デフォルトのスケジュールから完全パスと--exec-path の手法を使用してください。

Linux systemd システムでのバックグラウンドメンテナンス

Linux は cron をサポートしていますが、ディストリビューションによっては、cron は必ずしもインストールされていないオプションのパッケージである場合があります。最新のLinuxディストリビューションでは、systemd タイマーがそれを置き換えています。

ユーザーの systemd タイマーが利用可能な場合、それらは cron の代わりに使用されます。

この場合、git maintenance start はユーザーの systemd タイマーユニットを作成し、タイマーを開始します。ユーザーがスケジュールしたタスクの現在のリストは、systemctl --user list-timers を実行することで確認できます。git maintenance start によって書き込まれるタイマーはこれと似ています。

$ systemctl --user list-timers
NEXT                         LEFT          LAST                         PASSED     UNIT                         ACTIVATES
Thu 2021-04-29 19:00:00 CEST 42min left    Thu 2021-04-29 18:00:11 CEST 17min ago  git-maintenance@hourly.timer git-maintenance@hourly.service
Fri 2021-04-30 00:00:00 CEST 5h 42min left Thu 2021-04-29 00:00:11 CEST 18h ago    git-maintenance@daily.timer  git-maintenance@daily.service
Mon 2021-05-03 00:00:00 CEST 3 days left   Mon 2021-04-26 00:00:11 CEST 3 days ago git-maintenance@weekly.timer git-maintenance@weekly.service

--schedule=<frequency> オプションごとに1つのタイマーが登録されます。

systemd ユニットの定義は、以下のファイルで確認できます。

~/.config/systemd/user/git-maintenance@.timer
~/.config/systemd/user/git-maintenance@.service
~/.config/systemd/user/timers.target.wants/git-maintenance@hourly.timer
~/.config/systemd/user/timers.target.wants/git-maintenance@daily.timer
~/.config/systemd/user/timers.target.wants/git-maintenance@weekly.timer

git maintenance start はこれらのファイルを上書きし、systemctl --user でタイマーを再度開始するため、カスタマイズは、.conf サフィックスのファイルを ~/.config/systemd/user/git-maintenance@.service.d ディレクトリに作成することによって行う必要があります。

git maintenance stop はユーザーの systemd タイマーを停止し、上記のファイルを削除します。

詳細については、systemd.timer(5) を参照してください。

macOS システムでのバックグラウンドメンテナンス

macOS は技術的には cron をサポートしていますが、crontab -e を使用するには昇格された権限が必要であり、実行されたプロセスには完全なユーザーコンテキストがありません。完全なユーザーコンテキストがないと、Gitとその資格情報ヘルパーは保存された資格情報にアクセスできないため、一部のメンテナンスタスクは機能しません。

代わりに、git maintenance startlaunchctl ツールと対話します。これは、macOS で時間指定ジョブをスケジュールする推奨方法です。git maintenance (start|stop) を使用してメンテナンスをスケジュールするには、macOS 10.11 以降でのみ利用可能な launchctl の機能が必要です。

ユーザー固有のスケジュールされたタスクは、XML 形式の .plist ファイルとして ~/Library/LaunchAgents/ に保存されます。次のコマンドを使用して、現在登録されているタスクを確認できます。

$ ls ~/Library/LaunchAgents/org.git-scm.git*
org.git-scm.git.daily.plist
org.git-scm.git.hourly.plist
org.git-scm.git.weekly.plist

--schedule=<frequency> オプションごとに1つのタスクが登録されます。XML形式が各スケジュールをどのように記述しているかを確認するには、これらの.plistファイルの1つをエディターで開き、<key>StartCalendarInterval</key> 要素の後の <array> 要素を調べます。

git maintenance start はこれらのファイルを上書きし、launchctl でタスクを再度登録するため、カスタマイズは、独自の .plist ファイルを異なる名前で作成することによって行う必要があります。同様に、git maintenance stop コマンドは launchctl でタスクの登録を解除し、.plist ファイルを削除します。

バックグラウンドタスクに高度なカスタマイズを行うには、詳細については launchctl.plist(5) を参照してください。

Windows システムでのバックグラウンドメンテナンス

Windows は cron をサポートしておらず、代わりにバックグラウンドタスクのスケジュールのための独自のシステムを持っています。git maintenance start コマンドは schtasks コマンドを使用して、このシステムにタスクを送信します。タスクスケジューラアプリケーションを使用して、すべてのバックグラウンドタスクを確認できます。Gitによって追加されたタスクの名前は、Git Maintenance (<frequency>) という形式になっています。タスクスケジューラGUIにはこれらのタスクを確認する方法がありますが、タスクをXMLファイルにエクスポートして詳細を表示することもできます。

Gitはコンソールアプリケーションであるため、これらのバックグラウンドタスクは現在のユーザーに表示されるコンソールウィンドウを作成することに注意してください。これは、タスクスケジューラで「ユーザーがログインしているかどうかに関係なく実行する」オプションを選択することで手動で変更できます。この変更にはパスワードの入力が必要なため、git maintenance start はデフォルトでは選択しません。

バックグラウンドタスクをカスタマイズする場合は、将来の git maintenance (start|stop) の呼び出しでカスタムタスクが上書きされないように、タスクの名前を変更してください。

設定

このセクションのこの行以下のすべては、git-config[1] ドキュメントから選択的に含まれています。内容はそこに記載されているものと同じです。

maintenance.auto

このブール型の設定オプションは、一部のコマンドが通常の作業後にgit maintenance run --autoを実行するかどうかを制御します。デフォルトは true です。

maintenance.autoDetach

多くのGitコマンドは、リポジトリにデータを書込んだ後に自動メンテナンスをトリガーします。このブール型の設定オプションは、この自動メンテナンスをフォアグラウンドで行うか、メンテナンスプロセスをデタッチしてバックグラウンドで実行し続けるかを制御します。

設定されていない場合、gc.autoDetach の値がフォールバックとして使用されます。どちらも設定されていない場合はデフォルトで true になり、メンテナンスプロセスはデタッチされます。

maintenance.strategy

この文字列のconfigオプションは、バックグラウンドメンテナンスのためのいくつかの推奨スケジュールを指定する方法を提供します。これは、`--task=<task>`引数が提供されていない場合に限り、`git maintenance run --schedule=X`コマンドの実行タスクにのみ影響します。さらに、`maintenance.<task>.schedule` config値が設定されている場合、`maintenance.strategy`で提供される値の代わりに、その値が使用されます。可能な戦略文字列は次のとおりです。

  • none: このデフォルト設定は、スケジュールどおりにタスクが実行されないことを意味します。

  • incremental: この設定は、データを削除しない小さなメンテナンスアクティビティの実行を最適化します。これは`gc`タスクをスケジュールしませんが、`prefetch`と`commit-graph`タスクを毎時、`loose-objects`と`incremental-repack`タスクを毎日、そして`pack-refs`タスクを毎週実行します。

maintenance.<task>.enabled

このブール型のconfigオプションは、`git maintenance run`に`--task`オプションが指定されていない場合に、名前が`<task>`であるメンテナンスタスクを実行するかどうかを制御します。`--task`オプションが存在する場合は、これらのconfig値は無視されます。デフォルトでは、`maintenance.gc.enabled`のみがtrueです。

maintenance.<task>.schedule

このconfigオプションは、指定された`<task>`が`git maintenance run --schedule=<frequency>`コマンド中に実行されるかどうかを制御します。値は「hourly」、「daily」、または「weekly」のいずれかでなければなりません。

maintenance.commit-graph.auto

この整数型のconfigオプションは、`git maintenance run --auto`の一部として`commit-graph`タスクをどのくらいの頻度で実行するかを制御します。0の場合、`commit-graph`タスクは`--auto`オプションでは実行されません。負の値は、タスクを毎回実行するように強制します。それ以外の場合は、正の値は、コミットグラフファイルにない到達可能なコミットの数が`maintenance.commit-graph.auto`の値以上の場合にコマンドを実行することを意味します。デフォルト値は100です。

maintenance.loose-objects.auto

この整数型のconfigオプションは、`git maintenance run --auto`の一部として`loose-objects`タスクをどのくらいの頻度で実行するかを制御します。0の場合、`loose-objects`タスクは`--auto`オプションでは実行されません。負の値は、タスクを毎回実行するように強制します。それ以外の場合は、正の値は、ルーズオブジェクトの数が`maintenance.loose-objects.auto`の値以上の場合にコマンドを実行することを意味します。デフォルト値は100です。

maintenance.incremental-repack.auto

この整数型のconfigオプションは、`git maintenance run --auto`の一部として`incremental-repack`タスクをどのくらいの頻度で実行するかを制御します。0の場合、`incremental-repack`タスクは`--auto`オプションでは実行されません。負の値は、タスクを毎回実行するように強制します。それ以外の場合は、正の値は、マルチパックインデックスにないパックファイルの数が`maintenance.incremental-repack.auto`の値以上の場合にコマンドを実行することを意味します。デフォルト値は10です。

GIT

git[1]スイートの一部

scroll-to-top