日本語 ▾ トピック ▾ 最新バージョン ▾ git-maintenance は最終更新が 2.47.1

名前

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サブコマンドと同じ設定更新を実行し、その後、バックグラウンドスケジューラーを更新して、git maintenance run --scheduledを1時間ごとに実行するようにします。

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/内に配置するように変更されます。また、タグは更新されません。

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

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

gc

不要なファイルをクリーンアップし、ローカルリポジトリを最適化します。"GC"は"garbage collection"の略ですが、このタスクは多くの小さなタスクを実行します。このタスクは、すべてのGitオブジェクトを単一のパックファイルに再パックするため、大規模なリポジトリではコストが高くなる可能性があります。また、古いデータを削除するため、状況によっては破壊的な影響を与えることもあります。Gitにおけるガーベージコレクションの詳細については、git-gc[1]を参照してください。

loose-objects

loose-objectsジョブは、ルーズオブジェクトをクリーンアップし、それらをパックファイルに配置します。同時Gitコマンドとの競合状態を防ぐために、2段階のプロセスに従います。まず、パックファイルにすでに存在するルーズオブジェクトを削除します。同時Gitプロセスは、ルーズオブジェクトの代わりにパックファイルでオブジェクトデータを調べます。次に、ルーズオブジェクトのバッチを含む新しいパックファイル("loose-"で始まる)を作成します。バッチサイズは、多くのルーズオブジェクトを持つリポジトリでジョブが長くなりすぎないように、5万オブジェクトに制限されています。gcタスクは、到達不能なオブジェクトがパックファイルに再追加されない場合にのみ、後でクリーンアップされるルーズオブジェクトとして書き込みます。このため、loose-objectsタスクとgcタスクを同時に有効にすることはお勧めできません。

incremental-repack

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

pack-refs

pack-refsタスクは、ルーズな参照ファイルを集め、それらを単一のファイルにまとめます。これにより、多くの参照をイテレートする必要がある操作が高速化されます。詳細については、git-pack-refs[1]を参照してください。

オプション

--auto

runサブコマンドと組み合わせると、特定のしきい値が満たされた場合にのみメンテナンス・タスクを実行します。例えば、gcタスクは、ルーズオブジェクトの数がgc.auto設定値に格納された数を超えるか、パックファイルの数が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プロセスを実行します。各実行は「毎時」タスクを実行します。真夜中には、そのプロセスは「毎日」タスクも実行します。週の最初の日の真夜中には、そのプロセスは「毎週」タスクも実行します。単一のプロセスが、各登録済みリポジトリを繰り返し処理し、その頻度でスケジュールされたタスクを実行します。プロセスは、複数のクライアントが生成する負荷(例えばプリフェッチから)を分散させるために、クライアントごとにランダムな分にスケジュールされます。登録されたリポジトリの数とそのサイズによっては、このプロセスが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コマンドが、PATHとは無関係にgit maintenance startが発行されたものと同じであることを保証するために、git実行可能ファイルのフルパスを指定します。同じユーザーが複数の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でタイマーを再度開始します。したがって、カスタマイズは、~/.config/systemd/user/git-maintenance@.service.dディレクトリに.confサフィックスの付いたドロップインファイルを作成することで行うべきです。

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ファイルのいずれかをエディタで開き、<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

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

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

  • incremental: この設定は、データを削除しない小さなメンテナンス活動の実行を最適化します。gcタスクはスケジュールされませんが、prefetchcommit-graphタスクは毎時、loose-objectsincremental-repackタスクは毎日、pack-refsタスクは毎週実行されます。

maintenance.<task>.enabled

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

maintenance.<task>.schedule

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

maintenance.commit-graph.auto

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

maintenance.loose-objects.auto

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

maintenance.incremental-repack.auto

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

GIT

git[1] スイートの一部

scroll-to-top