SYNOPSIS

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

DESCRIPTION

タスクを実行してGitリポジトリデータを最適化し、他のGitコマンドを高速化し、リポジトリのストレージ使用量を減らします。

リポジトリのデータを追加するGitコマンド、例えば git addgit fetch は、応答性の良いユーザー体験(user experience)を実現するために最適化されています。これらのコマンドは、Gitデータを最適化するのに時間がかかりません。なぜなら、これらのユーザーコマンドはそれぞれ比較的小さなアクションを実行するのに対して、その最適化はリポジトリのフルサイズでスケールするからです。

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

SUBCOMMANDS

run

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

start

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

stop

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

register

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

register サブコマンドは、maintenance.strategy 構成値が以前に設定されていない場合、maintenance.strategyincremental に設定します。 incremental 戦略では、メンテナンスタスクごとに以下のスケジュールを使用します:

  • gc: disabled.

  • commit-graph: hourly.

  • prefetch: hourly.

  • loose-objects: daily.

  • incremental-repack: daily.

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

unregister

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

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

TASKS

commit-graph

commit-graph ジョブは commit-graph ファイルを段階的に更新し、書き込まれたデータが正しいことを確認します。段階的書き込みは、前の commit-graph-chain ファイルにあった .graph ファイルを期限切れにしないため、並行Gitプロセスと一緒に安全に実行できます。 それらは、有効期限延長に基づいて、のちの実行で削除されます。

prefetch

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

これは、リモート追跡ブランチの一時不通(disrupting)を回避するために行われます。 エンドユーザーは、フェッチを開始しない限り、これらのrefが移動されないままになることを期待しています。 ただし、prefetchタスクでは、後で実際のフェッチを完了するために必要なオブジェクトがすでに取得されているため、実際のフェッチはより高速になります。 理想的なケースでは、オブジェクトを転送せずに、一連のリモート追跡ブランチの更新ができます。

gc

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

loose-objects

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

incremental-repack

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

pack-refs

pack-refs タスクは、緩い参照ファイル(loose reference files)を収集し、それらを1つのファイルに纏めます。 これにより、多くの参照間で反復する必要のある操作が高速化されます。 詳細については、 git-pack-refs(1) を参照してください。

OPTIONS

--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> 値のリストについては、「TASKS」セクションを参照してください。

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

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

TROUBLESHOOTING

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

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

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

一部のメンテナンスウィンドウの完了に1時間以上かかる場合は、メンテナンスタスクの複雑さを軽減することを検討してください。 たとえば、 incremental-repack タスクは gc タスクよりもはるかに高速です。しかし、その代償として、オブジェクトデータベースが若干大きくなってしまいます。 より高価なタスクを移動して、実行頻度を減らすことを検討してください。

エキスパートユーザーは、 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 によるバックグラウンドメンテナンスを実行するために導入されたメカニズムとそれらをカスタマイズする方法について説明します。

BACKGROUND MAINTENANCE ON POSIX SYSTEMS

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

# 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 の手法を流用してください。

BACKGROUND MAINTENANCE ON LINUX SYSTEMD SYSTEMS

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 でタイマーを再開するため、カスタマイズは差し込み式ファイル(drop-in file)ドロップインファイル、つまり ~/.config/systemd/user/git-maintenance@.service.d ディレクトリに .conf 拡張子のファイルを作成して行う必要があります。

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

詳細は systemd.timer(5) を参照して下さい。

BACKGROUND MAINTENANCE ON MACOS SYSTEMS

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

代わりに、 git maintenance startlaunchctl ツールと相呼応します。これはmacOSで時限ジョブをスケジュールするための推奨される方法です。 git maintenance (start|stop) によるメンテナンスのスケジュールには、macOS10.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) を参照してください。

BACKGROUND MAINTENANCE ON WINDOWS SYSTEMS

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

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

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

CONFIGURATION

このセクションの以下のすべては、 git-config(1) ドキュメントの抜粋です。 内容は git-config(1) ドキュメント にあるものと同一です:

maintenance.auto

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

maintenance.strategy

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

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

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

maintenance.<task>.enabled

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

maintenance.<task>.schedule

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

maintenance.commit-graph.auto

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

maintenance.loose-objects.auto

この整数値構成オプションは、 git maintenance run --auto の一部として loose-objects タスクを実行する頻度を制御します。 ゼロの場合、 loose-objects タスクは --auto オプションでは実行されません。 負の値を指定すると、タスクは毎回実行されます。 それ以外の場合、正の値は、緩いオブジェクト(loose objects)の数が maintenance.loose-objects.auto の値以上であるときにコマンドを実行する必要があることを意味します。 デフォルト値は100です。

maintenance.incremental-repack.auto

この整数値構成オプションは、 git maintenance run --auto の一部として incremental-repack タスクを実行する頻度を制御します。 ゼロの場合、 incremental-repack タスクは --auto オプションでは実行されません。 負の値を指定すると、タスクは毎回実行されます。 それ以外の場合、正の値は、multi-pack-indexにないpack-fileの数が maintenance.incremental-repack.auto の値以上であるときにコマンドを実行する必要があることを意味します。 デフォルト値は10です。

GIT

Part of the git(1) suite