日本語 ▾ トピック ▾ 最新バージョン ▾ git-maintenance は 2.50.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が移動しないことを期待しています。しかし、プリフェッチタスクでは、後の実際のフェッチを完了するために必要なオブジェクトがすでに取得されているため、実際のフェッチが高速になります。理想的なケースでは、オブジェクト転送なしで、単に多数のリモートトラッキングブランチへの更新となるでしょう。

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

gc

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

loose-objects

loose-objects ジョブは、ルーズオブジェクトをクリーンアップし、パックファイルに配置します。並行する Git コマンドとの競合状態を防ぐため、2 段階のプロセスに従います。まず、すでにパックファイルに存在するルーズオブジェクトを削除します。並行する Git プロセスは、ルーズオブジェクトの代わりにパックファイルからオブジェクトデータを調べます。次に、ルーズオブジェクトのバッチを含む新しいパックファイル("loose-"で始まる)を作成します。

バッチサイズは、多くのルーズオブジェクトを持つリポジトリでジョブが長くなりすぎるのを防ぐために、デフォルトで5万オブジェクトに設定されています。このサイズを調整するには、maintenance.loose-objects.batchSize 設定オプションを使用します。制限をなくすには、値に 0 を指定します。

gc タスクは、到達不能なオブジェクトをルーズオブジェクトとして書き込み、後でパックファイルに再追加されない場合にのみクリーンアップされます。このため、loose-objectsgc の両方のタスクを同時に有効にすることは推奨されません。

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 の実行時に削除される準備ができます。小さなパックファイルの選択は、大きなパックファイルの予想サイズがバッチサイズ以上になるように行われます。詳細については、git-multi-pack-index[1]repack サブコマンドの --batch-size オプションを参照してください。デフォルトのバッチサイズは 0 で、これはすべてのパックファイルを単一のパックファイルに再パックしようとする特別なケースです。

pack-refs

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

reflog-expire

reflog-expire タスクは、期限切れのしきい値よりも古い reflog エントリを削除します。詳細については、git-reflog[1] を参照してください。

rerere-gc

rerere-gc タスクは、rerere キャッシュ内の古いエントリに対してガーベージコレクションを呼び出します。詳細については、git-rerere[1] を参照してください。

worktree-prune

worktree-prune タスクは、古くなったワークツリーまたは壊れたワークツリーを削除します。詳細については、git-worktree[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 を 1 時間ごと、毎日、毎週実行するためのスケジューラを指定します。<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 実行ファイルのフルパスを指定して、実行される 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 でタイマーを再度開始するため、カスタマイズはドロップインファイル、つまり ~/.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.loose-objects.batchSize

この整数設定オプションは、loose-objects タスク中にパックファイルに書き込まれるルーズオブジェクトの最大数を制御します。デフォルトは5万です。制限なしを示すには、値 0 を使用します。

maintenance.incremental-repack.auto

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

maintenance.reflog-expire.auto

この整数設定オプションは、git maintenance run --auto の一部として reflog-expire タスクをどのくらいの頻度で実行すべきかを制御します。ゼロの場合、reflog-expire タスクは --auto オプションでは実行されません。負の値は、タスクを毎回強制的に実行します。それ以外の場合、正の値は、「HEAD」reflog の期限切れ reflog エントリの数が maintenance.loose-objects.auto の値以上である場合にコマンドを実行すべきであることを意味します。デフォルト値は 100 です。

maintenance.rerere-gc.auto

この整数設定オプションは、git maintenance run --auto の一部として rerere-gc タスクをどのくらいの頻度で実行すべきかを制御します。ゼロの場合、rerere-gc タスクは --auto オプションでは実行されません。負の値は、タスクを毎回強制的に実行します。それ以外の場合、正の値は、"rr-cache" ディレクトリが存在し、古くなっているかどうかにかかわらず、少なくとも 1 つのエントリがある場合にコマンドが実行されることを意味します。このヒューリスティックは将来的に改善される可能性があります。デフォルト値は 1 です。

maintenance.worktree-prune.auto

この整数設定オプションは、git maintenance run --auto の一部として worktree-prune タスクをどのくらいの頻度で実行すべきかを制御します。ゼロの場合、worktree-prune タスクは --auto オプションでは実行されません。負の値は、タスクを毎回強制的に実行します。それ以外の場合、正の値は、剪定可能なワークツリーの数が値を超えた場合にコマンドを実行すべきであることを意味します。デフォルト値は 1 です。

GIT

git[1]スイートの一部

scroll-to-top