SYNOPSIS
frontend
| gitfast-import
[<options>]
DESCRIPTION
このプログラムは通常、 エンドユーザーが直接実行したいものではありません。 ほとんどのエンドユーザーは、 特定の種類の外部ソースを解析して、 その内容を git
fast-import
に渡す、 既存のフロントエンド・プログラムのいずれかを使います。
fast-importは、 標準入力から コマンド/データ が混在するストリームを読み取り、 1 つ以上のパック・ファイルを現在のリポジトリに直接書き込みます。 EOFが標準入力で受信されると、 fast-import は更新されたブランチとタグの refs を書き出し、 新しくインポートされたデータで現在のリポジトリを完全に更新します。
fast-import バックエンド自体は、 空のリポジトリ(git
init
によってすでに初期化されているリポジトリ)でインポートすることも、 既存の入力済みリポジトリを増分更新(incrementally update)することもできます。 特定の外部ソースからの増分インポートがサポートされているかどうかは、 使用しているフロントエンド・プログラムによって異なります。
OPTIONS
-
--force
-
コミットが失われる場合でも(新しいコミットには古いコミットが含まれていないため)、変更された既存のブランチを強制的に更新します。
-
--quiet
-
--stats
で示される出力を無効にし、正常に実行されると、通常、fast-importをサイレントにします。 ただし、インポート・ストリームに、 ユーザー出力を表示することを目的としたディレクティブ(`progress`ディレクティブなど)がある場合は、対応するメッセージが表示されます。 -
--stats
-
fast-import が作成したオブジェクトや、 それらが保存されたパックファイルや、 fast-import の実行中に fast-import によって使用されたメモリ、 に関するいくつかの基本的な統計を表示します。 この出力は表示が現在のデフォルトですが、
--quiet
を使用して無効にすることができます。 -
--allow-unsafe-features
-
feature
またはoption
コマンドを使用して、 fast-import ストリーム自体の一部として多くのコマンドライン・オプションを提供できます。 ただし、これらのオプションの一部は安全ではありません(たとえば、 fast-import でリポジトリの外部のファイルシステムにアクセスできるようにするなど)。 これらのオプションはデフォルトで無効になっていますが、 コマンドラインでこのオプションを指定することで許可できます。 これは現在、export-marks
とimport-marks
とimport-marks-if-exists
機能コマンドにのみ影響します。fast-import ストリームを生成するプログラムを信頼する場合にのみ、 このオプションを有効にしてください。 このオプションは、 独自のコードを実行することがすでに信頼されているため、
import
機能を使用するリモート・ヘルパーに対して自動的に有効になります。
Options for Frontends
-
--cat-blob-fd=
<fd> -
get-mark
とcat-blob
とls
クエリへの応答を、stdout
ではなくファイルデスクリプタ<fd>に書き込みます。 エンドユーザー向けのprogress
出力を他の出力から分離できるようにします。 -
--date-format=
<fmt> -
フロントエンドが高速インポートに提供する日付のタイプを、
author
とcommitter
と`tagger` コマンド内で指定します。 サポートされているフォーマットとその構文の詳細については、以下の「Date Formats」を参照してください。 -
--done
-
ストリームの最後に
done
コマンドがない場合は、エラーで終了(terminate)します。 このオプションは、フロントエンドがストリームの書き込みを開始する前に終了する原因となるエラーを検出するのに役立つ場合があります。
Locations of Marks Files
-
--export-marks=
<file> -
完了すると、内部マークテーブルを<file>にダンプします。 マークは1行に1つずつ
:markid
SHA-1
として書き込まれます。 フロントエンドは、このファイルを使用して、インポートが完了した後にインポートを検証したり、増分実行(incremental runs)全体でマークテーブルを保存したりできます。 <file>はチェックポイント(または完了)でのみ開かれ(open)、切り捨て(truncate)られるため、同じパスを--import-marks
に安全に指定することもできます。 -
--import-marks=
<file> -
入力を処理する前に、<file>で指定されたマークをロードします。 入力ファイルは存在し、読み取り可能であり、
--export-marks
によって生成されたものと同じ形式を使用する必要があります。 複数のマークのセットをインポートするために、オプションを複数回指定できます。 マークが異なる値に定義されている場合、最後のファイルが優先されます。 -
--import-marks-if-exists=
<file> -
--import-marks
と同様ですが、エラーが発生する代わりに、ファイルが存在しない場合は黙ってスキップします。 -
--
[no-
]relative-marks
-
--relative-marks
を指定した後、--import-marks=
と--export-marks=
で指定されたパスは、現在のリポジトリの内部ディレクトリからの相対パスになります。 git-fast-importでは、これはパスが.git/info/fast-import
ディレクトリから相対的であることを意味します。 ただし、他のインポーターは別の場所を使用する場合があります。--
(no-
)-relative-marks
を--
(import
|export
)-marks=
と織り交ぜることで、相対マークと非相対マークを組み合わせることができます。
Submodule Rewriting
-
--rewrite-submodules-from=
<name>:
<file> -
--rewrite-submodules-to=
<name>:
<file> -
<name> で指定されたサブモジュールのオブジェクト ID を、from <file> で使用されている値から to <file> で使用されている値に書き換えます。 同一サブモジュールをインポートするときに、 from マークは
git
fast-export
によって作成され、 to マークはgit
fast-import
によって作成されている必要があります。<name>は、コロン文字を含まない任意の文字列にすることができますが、対応するマークを指定するときは、両方のオプションで同じ値を使用する必要があります。 <name>の値が異なる複数のサブモジュールを指定できます。 対応するペアでこれらのオプションを使用しないのはエラーです。
これらのオプションは、リポジトリをあるハッシュアルゴリズムから別のハッシュアルゴリズムに変換するときに主に役立ちます。 それらがないと、オブジェクトIDを新しいハッシュアルゴリズムに書き込む方法がないため、サブモジュールが検出された場合、fast-importは失敗します。
Performance and Compression Tuning
-
--active-branches=
<n> -
一度にアクティブを維持するブランチの最大数。 詳細については、下記「Memory Utilization」(メモリ使用率)を参照してください。 デフォルトは5です。
-
--big-file-threshold=
<n> -
fast-importがデルタを作成しようとするブロブの最大サイズ(バイト単位)。 デフォルトは512m(512 MiB)です。 一部のインポーターは、メモリが制限されているシステムでこの値を下げることを希望する事があります。
-
--depth=
<n> -
ブロブとツリーの差分化(deltification)の最大デルタ深度。 デフォルトは50です。
-
--export-pack-edges=
<file> -
パックファイルを作成した後、データの行を<file>に出力して、パックファイルのファイル名と、そのパックファイルに書き込まれた各ブランチの最後のコミットをリストします。 この情報は、オブジェクトセットの合計が4 GiBパックファイルの制限を超えるプロジェクトをインポートした後に役立つ場合があります。 これらのコミットは、
git
pack-objects
の呼び出し中にエッジポイントとして使用できるためです。 -
--max-pack-size=
<n> -
各出力パックファイルの最大サイズ。 デフォルトは無制限です。
- fastimport.unpackLimit
PERFORMANCE
fast-import の設計により、最小限のメモリ使用量と処理時間で大規模なプロジェクトをインポートできます。 フロントエンドが fast-import に対応し、コンスタントにデータ・ストリームをフィードできると仮定すると、 10年以上の履歴を保持し、 100,000以上の個別のコミットを含むプロジェクトのインポート時間は、 通常、 非常に控えめな(〜$2,000 USD)ハードウェアで、 わずか 1 〜 2 時間で完了します。
ほとんどのボトルネックは、 外部ソースデータ・アクセス(ソースがリビジョンを十分に速く抽出できない)、 またはディスク I/O(ディスクがデータを取得するのと同じ速さで fast-import に書き込みできない)にあるように見えます。 ソースデータが宛先 Git リポジトリとは異なるドライブに保存されている場合、 (I/Oの競合が少ないため)、 インポートはより高速に実行されます。
DEVELOPMENT COST
fast-import の一般的なフロントエンドは、 200 行程度の Perl/Python/Ruby コードを使用する傾向があります。 ほとんどの開発者は、 fast-import どころか Git に初めて触れたとしても、 わずか数時間で実用的なインポーターを作成することができました。 ほとんどの変換ツールが使い捨て(一度使用すると、決して振り返ることがない)であることを考えると、これは理想的な状況です。
PARALLEL OPERATION
git
push
や git
fetch
と同様に、fast-importによって処理されるインポートは、 並列の git
repack
-a
-d
や git
gc
の呼び出し、 またはその他のGit操作(git
prune
を含む。 そして fast-import では緩いオブジェクト(loose objects)は決して使用されない)と、 一緒に実行しても安全です。
fast-importは、アクティブにインポートしているブランチまたはタグ refs をロックしません。 インポート後、 ref の更新フェーズで、 fast-import は、 既存の各ブランチ ref をテストして、 更新が早送り更新(fast-forward update)になることを確認(verifty)します(ref に格納されているコミットは、書き込まれるコミットの新しい履歴に含まれます)。 更新が早送り更新でない場合、 fast-import はその ref の更新をスキップし、 代わりに警告メッセージを出力します。 fast-import は常にすべてのブランチ refs を更新しようとし、 最初の失敗で停止(stop)しません。
ブランチの更新は --force
を使用して強制できますが、それ以外の場合は静かなリポジトリ(quiet repository)でのみ使用することをお勧めします。 空のリポジトリへの最初のインポートには、 --force
を使用する必要はありません。
TECHNICAL DISCUSSION
fast-importは、メモリ内の一連のブランチを追跡します。 入力ストリームで commit
コマンドを送信することにより、インポートプロセス中の任意の時点で任意のブランチを作成または変更できます。 この設計により、フロントエンドプログラムは無制限の数のブランチを同時に処理し、ソースデータから利用可能な順序でコミットを生成できます。 また、フロントエンドプログラムを大幅に簡素化します。
fast-importは、現在の作業ディレクトリまたはその中のファイルを使用または変更しません。 (ただし、 GIT_DIR
で参照されるように、現在のGitリポジトリを更新します。) したがって、インポートフロントエンドは、外部ソースからファイルリビジョンを抽出するなど、独自の目的で作業ディレクトリを使用する場合があります。 この、作業ディレクトリの無感知により、ブランチを切り替えるときにコストのかかるファイル更新操作を実行する必要がないため、fast-importを非常に迅速に実行することもできます。
INPUT FORMAT
(Gitが解釈しない)生のファイルデータを除いて、fast-import入力形式はテキスト(ASCII)ベースです。 このテキストベースの形式は、特にPerl、Python、Rubyなどの高級言語が使用されている場合に、フロントエンドプログラムの開発とデバッグを簡素化します。
fast-importは、入力に関して非常に厳密です。 以下でSPと言う場合、「正確に」1つのスペースを意味します。 同様に、LFは1つ(そして1つだけ)の改行を意味し、HTは1つ(そして1つだけ)の水平タブを意味します。追加の空白文字を指定すると、名前の先頭または末尾にスペースが含まれるブランチ名やファイル名などの予期しない結果が発生したり、予期しない入力が発生した場合に高速インポートが早期に終了したりします。
Stream Comments
フロントエンドのデバッグを支援するために、fast-importは、 # (ASCII シャープ/ハッシュ) で始まり、LF
で終わる行を無視します。 コメント行には、LFを含まないバイトのシーケンスを含めることができるため、フロントエンドに固有でfast-importのデータストリームを検査するときに役立つ詳細なデバッグ情報を含めるために使用できます。
Date Formats
以下の日付形式がサポートされています。 フロントエンドは、--date-format=
<fmt> コマンドラインオプションで形式名を渡すことにより、このインポートに使用する形式を選択する必要があります。
-
raw
-
これはGitのネイティブ形式であり、 <time>
SP
<offutc> です。--date-format
が指定されていない場合は、fast-importのデフォルト形式でもあります。イベントの時刻は、UNIXエポック(1970年1月1日午前0時、UTC)からの秒数として <time> で指定され、ASCIIの10進整数として書き込まれます。
ローカルオフセットは、UTCからの正または負のオフセットとして <offutc> によって指定されます。 たとえば、EST(UTCから5時間遅れている)は、UTCが「+0000」であるのに対し、「<tz>」は「-0500」で表されます。 ローカルオフセットは <time> には影響しません。 これは、フォーマットルーチンがタイムスタンプを表示するのに役立つアドバイスとしてのみ使用されます。
ローカルオフセットがソース素材で使用できない場合は、「+0000」、または最も一般的なローカルオフセットを使用します。 たとえば、多くの組織には、同じ場所とタイムゾーンにいるユーザーだけがアクセスしたことのあるCVSリポジトリがあります。 この場合、UTCからの妥当なオフセットを想定できます。
rfc2822
形式とは異なり、この形式は非常に厳密です。 フォーマッティングに変化があると、fast-importが値を拒否し、数値の健全性チェックも実行される場合があります。 -
raw-permissive
-
これは、数値エポックとローカルオフセットの健全性チェックが実行されないことを除いて、
raw
と同じです。 これは、例えば、偽のタイムゾーン値を使用して既存の履歴をフィルタリングまたはインポートしようとする場合に役立ちます。 -
rfc2822
-
これは、RFC2822で説明されている標準の日付形式です。
この値は例えば
Tue
Feb
6
11:22:18
2007
-0500
です。 Gitパーサーは正確ですが、ちょっぴり寛大です。 これは、電子メールから受信したパッチを適用するときにgit
am
によって使用されるのと同じパーサーです。一部の不正な形式の文字列が、有効な日付として受け入れられる場合があります。 これらの場合のいくつかでは、Gitは不正な形式の文字列から正しい日付を取得できます。 また、Gitが誤ってパースし、それでも有効と見なす不正な形式の文字列の種類もあります。 ひどくおかしい文字列は拒否されます。
上記の`raw`形式とは異なり、RFC2822日付文字列に含まれる タイムゾーン/UTC オフセット情報は、保存前に日付値をUTCに調整するために使用されます。 したがって、この情報が可能な限り正確であることが重要です。
もしソース素材がRFC2822スタイルの日付を使っているなら、フロントエンドは(自分でやろうとするよりも、)fast-importにパースと変換を任せるべきです。なぜなら、Gitパーサーは実際によくテストされているからです。
フロントエンドは、ソース素材がすでに UNIX-epoch フォーマットを使っていて、そのフォーマットで日付を与えるように言いくるめられる場合、あるいはパースに曖昧さがないため、そのフォーマットが簡単に
raw
フォーマットに変換できる場合は、raw
フォーマットを優先するべきです。 -
now
-
常に現在の時間とタイムゾーンを使用します。 <when> には常に
now
というリテラルを指定しなければなりません。これはおもちゃのフォーマット(toy format)です。 このシステムの現在の時刻とタイムゾーンは、fast-importによって作成されるときに常にID文字列にコピーされます。 別の時間またはタイムゾーンを指定する方法はありません。
この特定の形式は、実装が簡単なために提供されており、作業ディレクトリや
git
update-index
を使用せずに、今すぐ新しいコミットを作成したいプロセスに役立つ場合があります。commit
で別々のauthor
コマンドとcommitter
コマンドが使用されている場合、システムクロックが2回(コマンドごとに1回)ポーリングされるため、タイムスタンプが一致しない可能性があります。 作者とコミッターの両方のID情報のタイムスタンプが同じであることを確認する唯一の方法は、author
を省略するか(したがってcommitter
からコピーする)、またはnow
以外の日付形式を使用することです。
Commands
fast-importは、現在のリポジトリを更新し、現在のインポートプロセスを制御するためのいくつかのコマンドを受け入れます。 各コマンドの詳細(例を含む)については後述します。
-
commit
-
新しいコミットを作成し、新しく作成されたコミットを指すようにブランチを更新することにより、新しいブランチを作成するか、既存のブランチを更新します。
-
tag
-
既存のコミットまたはブランチから注釈付きタグオブジェクト(annotated tag object)を作成します。 軽量タグ(Lightweight tags)は、意味のある時点を記録するためには推奨されていないため、このコマンドではサポートされていません。
-
reset
-
既存のブランチ(または新しいブランチ)を特定のリビジョンにリセットします。 このコマンドは、 ブランチを特定のリビジョンに変更する目的で、 コミットを作成せずに使用しなければなりません。
-
blob
-
将来
commit
コマンドで使用するために、生のファイルデータをブロブに変換します。 このコマンドはオプションであり、インポートを実行するために必要ではありません。 -
alias
-
最初に新しいオブジェクトを作成せずに、マークが特定のオブジェクトを参照していることを記録します。
--import-marks
を使用し、欠落しているマークを参照すると fast-import が失敗するため、エイリアスは、刈り込まれたコミットを有効な値(刈り込まれていない最も近い祖先など)に設定する方法を提供できます。 -
checkpoint
-
fast-importを強制して、現在のパックファイルを閉じ、一意のSHA-1チェックサムとインデックスを生成して、新しいパックファイルを開始します。 このコマンドはオプションであり、インポートを実行するために必須ではありません。
-
progress
-
fast-importにより、行全体が自身の標準出力にエコーされます。このコマンドはオプションであり、インポートを実行するために必要ではありません。
-
done
-
ストリームの終わりを示します。
--done
コマンドラインオプションまたはfeature
done
コマンドを使用してdone
機能が要求された場合を除き、このコマンドはオプションです。 -
get-mark
-
fast-import により、マークに対応するSHA-1が、
--cat-blob-fd
にて設定されたファイルデスクリプタへ出力されるか、または、指定されていない場合は stdout のファイルデスクリプタへ出力されます。 -
cat-blob
-
fast-importにより、
cat-file
--batch
形式のブロブが、--cat-blob-fd
にて設定されたファイルデスクリプタへ出力されるか、または、指定されていない場合は stdout のファイルデスクリプタへ出力されます。 -
ls
-
fast-importにより、ディレクトリエントリを
ls-tree
形式で記述した行が、--cat-blob-fd
にて設定されたファイルデスクリプタへ出力されるか、または、指定されていない場合は stdout のファイルデスクリプタへ出力されます。 -
feature
-
指定された機能を有効にします。 これには、fast-importが指定された機能をサポートしている必要があり、サポートしていない場合は中止(abort)されます。
-
option
-
フロントエンドのニーズに合わせて、 ストリームのセマンティックを変更しないオプションを「オプションの一覧」から指定してください。 このコマンドは任意であり、インポートを実行するために必要ではありません。
commit
新しいコミットでブランチを作成または更新し、プロジェクトへの1つの論理的な変更を記録します。
'commit' SP <ref> LF
mark?
original-oid?
('author' (SP <name>)? SP LT <email> GT SP <when> LF)?
'committer' (SP <name>)? SP LT <email> GT SP <when> LF
('encoding' SP <encoding>)?
data
('from' SP <commit-ish> LF)?
('merge' SP <commit-ish> LF)*
(filemodify | filedelete | filecopy | filerename | filedeleteall | notemodify)*
LF?
ここで、 <ref> はコミットを行うブランチの名前です。 通常、Gitではブランチ名の前に refs/heads/
が付いているため、CVSブランチシンボル RELENG-1_0
をインポートすると、 <ref> の値に refs/heads/RELENG-1_0
が使用されます。 <ref> の値は、Gitで有効なrefnameである必要があります。 LF
はGit refnameでは無効であるため、ここではクォートやエスケープ構文はサポートされていません。
mark
コマンドがオプションで表示され、フロントエンドで将来使用するために新しく作成されたコミットへの参照を保存するようにfast-importを要求する場合があります(形式については以下を参照)。 フロントエンドが作成するすべてのコミットにマークを付けることは非常に一般的であり、これにより、インポートされたコミットから将来のブランチを作成できます。
committer
に続く data
コマンドは、コミットメッセージを提供する必要があります(data
コマンドの構文については以下を参照してください)。 空のコミットメッセージをインポートするには、長さ0のデータを使用します。 コミットメッセージは自由形式であり、Gitによって解釈されません。 fast-importでは他のエンコードを指定できないため、現在はUTF-8でエンコードする必要があります。
コミットを作成する前にブランチの内容を更新するために、0個以上の filemodify
、 filedelete
、 filecopy
、 filerename
、 filedeleteall
、 notemodify
コマンドを含めることができます。 これらのコマンドは、任意の順序で指定できます。 ただし、 filedeleteall
はブランチをクリーンにワイプするため、 filedeleteall
コマンドを同じコミット内のすべての filemodify
、 filecopy
、 filerename
、 ` notemodify` コマンドの前に置くことをお勧めします(下記参照)。
コマンドの後の LF
はオプションです(以前は必須でした)。 下位互換性の理由から、コミットが data
コマンドで終了する場合(つまり、 from
、 merge
、 filemodify
、 filedelete
、 filecopy
、 filerename
、 filedeleteall
、 notemodify
コマンドがないことに注意してください)の場合、コマンドの最後に1つではなく2つの LF
コマンドが表示される場合があります。
author
作者情報がコミッター情報と異なる場合は、オプションで author
コマンドが表示されることがあります。 author
を省略すると、fast-importはコミットの作者部分にコミッターの情報を自動的に使用します。 author
のフィールドの説明については、 committer
と同じであるため、以下を参照してください。
committer
committer
コマンドは、誰がこのコミットを行ったのか、いつ行ったのかを示します。
ここで、 <name> は個人の表示名(たとえば、 "Com M Itter")であり、 <email> は個人の電子メールアドレス("cm@example.com")です。 LT
と GT
は、文字通りの小なり記号(<;\x3c)と大なり記号(>;\x3e)です。 これらは、行の他のフィールドから電子メールアドレスを区切るために必要です。 <name> と <email> は自由形式であり、 LT
、GT
、 LF
を除く任意のバイトシーケンスを含むことができることに注意してください。 <name> は通常UTF-8でエンコードされています。
変更時刻は、 --date-format=
<fmt> コマンドラインオプションで選択された日付形式を使用して <when> で指定されます。サポートされている形式のセットとその構文については、上記「Date Formats」を参照してください。
encoding
オプションの encoding
コマンドは、コミットメッセージのエンコーディングを示します。 ほとんどのコミットはUTF-8であり、エンコードは省略されていますが、これにより、最初に再エンコードせずにコミットメッセージをgitにインポートできます。
from
from
コマンドは、このブランチを初期化するコミットを指定するために使用されます。 このリビジョンは、新しいコミットの最初の祖先になります。 このコミットで構築されたツリーの状態は、 from
コミットでの状態で始まり、このコミットでのコンテンツの変更によって交換(alter)されます。
新しいブランチの最初のコミットで from
コマンドを省略すると、fast-importが祖先なしでそのコミットを作成します。 これは、プロジェクトの最初のコミットでのみ必要になる傾向があります。 新しいブランチを作成するときにフロントエンドがすべてのファイルを最初から作成する場合は、 from
の代わりに merge
コマンドを使用して、空のツリーでコミットを開始できます。 そのブランチの現在のコミットは自動的に新しいコミットの最初の祖先であると見なされるため、既存のブランチでは通常は from
コマンドを省略することが望まれます。
LF
は Git refname または SHA-1式では無効であるため、<commit-ish> 内でのクォートまたはエスケープ構文はサポートされていません。
ここで、<commit-ish> は以下のいずれかです:
-
fast-importの内部ブランチテーブルにすでに存在する既存のブランチの名前。 fast-importが名前を知らない場合は、SHA-1式として扱われます。
-
マーク参照は
:
<idnum> です。ここで、 <idnum> はマーク番号です。fast-import がマーク参照を示すために
:
を使用する理由は、 この文字が Git ブランチ名では無効であるためです。 先頭に:
を使用すると、 マーク42(:42
)と、 ブランチ42(42
またはrefs/heads/42
)と、 たまたま10進数で構成されていた省略形のSHA-1を、簡単に区別できます。マークは、使用する前に(
mark
を介して)宣言する必要があります。 -
完全な40バイトまたは省略された16進数のコミットSHA-1。
-
コミットに解決される有効な Git SHA-1式。 詳細については、 gitrevisions(7) の「SPECIFYING REVISIONS」を参照してください。
-
特別な null SHA-1(40個のゼロ)は、ブランチが削除されることを指定します。
現在のブランチ値から増分インポート(incremental import)を再スタートする特殊なケースは、以下のように記述する必要があります:
from refs/heads/branch^0
fast-importはブランチをそれ自体から開始することを許可しないため、 ^0
サフィックスが必要です。ブランチは、 from
コマンドが入力から読み取られる前にメモリに作成されます。 ^0
を追加すると、fast-importは、内部ブランチテーブルではなく、Gitのリビジョンパースライブラリを介してコミットを解決し、ブランチの既存の値をロードします。
merge
1つの追加の祖先コミットが含まれます。 追加の祖先リンクは、このコミットでツリー状態が構築される方法を変更しません。 新しいブランチを作成するときに from
コマンドを省略すると、最初の merge
コミットが現在のコミットの最初の祖先になり、ブランチはファイルなしで開始されます。 fast-importでは、コミットごとに無制限の数の merge
コマンドが許可されるため、n方向(n-way)マージが確立されます。
ここで、 <commit-ish> は、 from
でも受け入れられるコミット仕様式のいずれかです(上記参照)。
filemodify
新しいファイルを追加したり、既存のファイルの内容を変更したりするために commit
コマンドに含まれています。 このコマンドには、ファイルの内容を指定する2つの異なる方法があります。
- External data format
-
ファイルのデータコンテンツは、以前の
blob
コマンドによってすでに提供されています。フロントエンドはそれに接続する必要があります。'M' SP <mode> SP <dataref> SP <path> LF
ここで通常、 <dataref> は、前の
blob
コマンドによって設定されたマーク参照(:
<idnum>)か、既存のGitブロブオブジェクトの完全な40バイトのSHA-1である必要があります。 <mode> が040000
の場合、 <dataref> は既存のGitツリーオブジェクトの完全な40バイトのSHA-1または--import-marks
で設定されたマーク参照である必要があります。 - Inline data format
-
ファイルのデータコンテンツはまだ提供されていません。 フロントエンドは、この変更コマンドの一部としてそれを提供したいと考えています。
'M' SP <mode> SP 'inline' SP <path> LF data
data
コマンドの詳細については下記参照。
どちらの形式でも、 <mode> はファイルエントリのタイプであり、8進数で指定されます。 Gitは以下のモードのみをサポートします:
-
100644
または644
: 通常の(実行可能でない)ファイル。 ほとんどのプロジェクトのファイルの大部分はこのモードを使用しています。迷ったらコレ。 -
100755
または755
: 通常の、しかし実行可能なファイル。 -
120000
: シンボリックリンク。ファイルの内容がリンクターゲットになります。 -
160000
: gitlink 、オブジェクトのSHA-1は、他のリポジトリのコミットを参照しています。 Git リンクは、 SHA を介してか、 あるいは、 コミット・マークを通じてか、 のどちらかでのみ指定できます。 これらは、サブモジュールを実装するために使用されます。 -
040000
: サブディレクトリ。 サブディレクトリは、SHAによって、または--import-marks
で設定されたツリーマークを介してのみ指定できます。
どちらの形式でも、 <path> は、追加(まだ存在しない場合)または変更(すでに存在する場合)するファイルの完全なパスです。
<path> は、 引用符で囲まれていないバイト列、 または C 言語スタイルの引用符で囲まれた文字列として記述することができます。
<path> が二重引用符(")で始まらない場合、 それは非クォート文字列となり、 エスケープ・シーケンスなしのリテラル・バイトとしてパースされます。 しかしファイル名に LF
が含まれているか、または、二重引用符で始まる場合は、 非クォート文字列にすることはできず、 クォートする必要があります。 さらに、filecopy
または filerename
内の ソース <path> に SP が含まれる場合は、 クォートする必要があります。
<path> が二重の引用(")で始まる場合、 それは C スタイルのクォート文字列であり、 完全なファイル名が二重引用符のペアに囲まれ、 エスケープシーケンスが使用されます。 特定の文字はバックスラッシュ("\")を先行させることによりエスケープする必要があります: LF は \n 、 バックスラッシュは \\ 、 ダブルクォーテーションは \" と記述します。 一部の文字は、 オプションでエスケープシーケンスで書かれている場合があります: \a はビープ音(bell)、 \b はバックスペース、 \f は フォーム・フィード、\n はラインフィード、 \r はキャリッジリターン、 \t は水平タブ、 \v は垂直タブです。 任意のバイトは 3 桁の8進数コード(例: \033)で記述できます。 すべてのファイル名はクォート文字列として表すことができます
<path> は UNIX スタイルのディレクトリ区切り文字(逆じゃないスラッシュ /
)を使用する必要があり、 その値は正規形式(canonical form)である必要があります。つまり以下のことをしてはいけません:
-
空のディレクトリコンポーネントが含まれている(例:
foo//bar
は無効)、 -
ディレクトリ区切り文字で終了する(例:
foo/
は無効)、 -
ディレクトリ区切り文字で始まる(例:
/foo
は無効)、 -
特別なコンポーネント . または .. を含む(例:
foo/./bar
やfoo/
..
/bar
は無効)。
ツリーのルートは、 <path> に空の文字列を指定します。
<path> には、 その文字通り(literally)または \000 としてエスケープするかを問わず、 NUL を含めることはできません。 <path> は常にUTF-8を使用してエンコードすることをお勧めします。
filedelete
ファイルを削除したり、ブランチからディレクトリ全体を再帰的に削除したりするために commit
コマンドに含まれています。 ファイルまたはディレクトリを削除して、その親ディレクトリが空になると、親ディレクトリも自動的に削除されます。 これは、最初の空でないディレクトリまたはルートに到達するまで、ツリーを上流へ連鎖的にたどります(cascade up)。
'D' SP <path> LF
ここで、 <path> は、ブランチから削除されるファイルまたはサブディレクトリの完全なパスです。 <path> の詳細な説明については、上記の filemodify
を参照してください。
filecopy
既存のファイルまたはサブディレクトリをブランチ内の別の場所に再帰的にコピーします。 既存のファイルまたはディレクトリが存在する必要があります。 宛先が存在する場合は、ソースからコピーされたコンテンツに完全に置き換えられます。
'C' SP <path> SP <path> LF
ここで、最初の <path> はソースの場所であり、2番目の <path> は宛先です。 <path> がどのように見えるかの詳細な説明については、上記の filemodify
を参照してください。 SPを含むソースパスを使用するには、パスをクォートする必要があります。
filecopy
コマンドの効果は即時です。ソースの場所が宛先にコピーされると、ソースの場所に適用される以降のコマンドは、コピーの宛先に影響を与えません。
filerename
既存のファイルまたはサブディレクトリの名前をブランチ内の別の場所に変更します。 既存のファイルまたはディレクトリが存在する必要があります。 宛先が存在する場合は、ソースディレクトリに置き換えられます。
'R' SP <path> SP <path> LF
ここで、最初の <path> はソースの場所であり、2番目の <path> は宛先です。 <path> がどのように見えるかの詳細な説明については、上記の filemodify
を参照してください。 SPを含むソースパスを使用するには、パスをクォートする必要があります。
filerename
コマンドの効果は即時です。 ソースの場所の名前が宛先に変更されると、ソースの場所に適用される将来のコマンドは、そこに新しいファイルを作成し、名前変更の宛先に影響を与えません。
注意: filerename
は、 filecopy
の後にソースの場所の filedelete
が続くのと同じであることに注意してください。 filerename
を使用することにはわずかなパフォーマンス上の利点がありますが、その利点は非常に小さいため、ソース素材の、削除・追加のペアを、高速インポート用の名前変更に変換する価値はありません。 この filerename
コマンドは、名前変更情報がすでにあるフロントエンドを単純化するために提供されており、それを filecopy
とそれに続く filedelete
に分解する必要はありません。
filedeleteall
ブランチからすべてのファイル(およびすべてのディレクトリ)を削除するために commit
コマンドに含まれています。 このコマンドは、内部ブランチ構造をリセットしてファイルを含まないようにし、フロントエンドの関心あるすべてのファイルを最初から追加できるようにします。
'deleteall' LF
このコマンドは、フロントエンドが現在ブランチ上にあるファイルを知らない(あるいは知ろうとしない)ため、コンテンツを更新するための適切な filedelete
コマンドを生成できない場合に非常に役立ちます。
正しいコンテンツを設定するために filedeleteall
の後に必要な filemodify
コマンドを発行すると、必要な filemodify
および filedelete
コマンドのみを送信するのと同じ結果が得られます。 しかし、filedeleteall
のアプローチでは、fast-import がアクティブブランチごとに若干多くのメモリの使用を必要する場合があります(ほとんどの大規模プロジェクトでも1 MiB未満ではありますが)。 したがって、コミットの影響を受けるパスのみを簡単に取得できるフロントエンドは、コミットの影響を受けるパスのみを取得することをお勧めします。
notemodify
<commit-ish> に注釈する新しいノートを追加したり、この注釈の内容を変更したりするために commit
<notes-ref> コマンドに含まれています。 内部的には、 <commit-ish> パスの filemodify
100644
に似ています(サブディレクトリに分割されている可能性があります)。 filedeleteall
以外のコマンドを使用して <notes-ref> ツリーに書き込み、このツリー内の既存のノートをすべて削除することはお勧めしません。 このコマンドには、ノートの内容を指定する2つの異なる方法があります。
- External data format
-
ノートのデータコンテンツは、以前の
blob
コマンドによってすでに提供されています。 フロントエンドは、注釈を付けるコミットに接続する必要があります。'N' SP <dataref> SP <commit-ish> LF
ここで、 <dataref> は、前の
blob
コマンドによって設定されたマーク参照(:
<idnum>)、または既存のGitブロブオブジェクトの完全な40バイトのSHA-1のいずれかです。 - Inline data format
-
ノートのデータ内容はまだ提供されていません。 フロントエンドは、この変更コマンドの一部としてそれを提供したいと考えています。
'N' SP 'inline' SP <commit-ish> LF data
data
コマンドの詳細については下記参照。
どちらの形式でも、 <commit-ish> は、 from
でも受け入れられるコミット仕様式のいずれかです(上記参照)。
mark
fast-import を使って現在のオブジェクトへの参照を保存し、 フロントエンドが SHA-1 を知らなくても、 将来の時点でこのオブジェクトを呼び出すことができるようにします。 ここで、 現在のオブジェクトは、 mark
コマンドが含まれるオブジェクト作成コマンドです。 これは commit
や tag
や blob
にすることができますが、 commit
が最も一般的な使用法です。
'mark' SP ':' <idnum> LF
ここで、 <idnum> は、フロントエンドによってこのマークに割り当てられた番号です。 <idnum> の値は、ASCIIの10進整数として表されます。 値0は予約されており、マークとして使用することはできません。 1以上の値のみをマークとして使用できます。
新しいマークは自動的に作成されます。 同じ <idnum> を別の mark
コマンドで再利用するだけで、既存のマークを別のオブジェクトに移動できます。
original-oid
元のソース管理システムのオブジェクトの名前を提供します。 fast-import はこのディレクティブを単に無視しますが、fast-importにフィードする前にストリームを操作および変更するフィルタープロセスは、この情報を使用する場合があります。
'original-oid' SP <object-identifier> LF
ここで、 <object-identifier> は LF を含まない任意の文字列です。
tag
特定のコミットを参照する注釈付きタグ(annotated tag)を作成します。 軽量(注釈なし)タグ(lightweight tag)を作成するには、下記 reset
コマンドを参照してください。
'tag' SP <name> LF
mark?
'from' SP <commit-ish> LF
original-oid?
'tagger' (SP <name>)? SP LT <email> GT SP <when> LF
data
ここで、 <name> は作成するタグの名前です。
タグ名はGitに保存されるときに自動的に refs/tags/
のプレフィックスが付けられるため、CVSブランチシンボル RELENG-1_0-FINAL
をインポートすると、 <name> に RELENG-1_0-FINAL
だけが使用され、 fast-importは対応するrefを refs/tags/RELENG-1_0-FINAL
として書き込みます。
<name> の値は、Gitで有効なrefnameである必要があるため、スラッシュを含めることができます。 LF
はGit refnameでは無効であるため、ここではクォートやエスケープ構文はサポートされていません。
from
コマンドは commit
コマンドと同じです。 詳細については、上記を参照してください。
tagger
コマンドは、 commit
内の committer
と同じ形式を使用します。 詳細については、再度上記を参照してください。
tagger
に続く data
コマンドは、注釈付きのタグメッセージを提供する必要があります(data
コマンドの構文については以下を参照してください)。 空のタグメッセージをインポートするには、長さ0のデータを使用します。 タグメッセージは自由形式であり、Gitによって解釈されません。 fast-importでは他のエンコードを指定できないため、現在はUTF-8でエンコードする必要があります。
fast-import内からのインポート中に注釈付きタグに署名することはサポートされていません。 フロントエンドは通常そのような署名に入るバイトの完全なセットに(簡単に)アクセスできないため、独自の PGP/GPG 署名を含めることはお勧めしません。 署名が必要な場合は、 reset
を使用してfast-import内から軽量タグを作成し、標準の git
tag
プロセスを使用してそれらのタグの注釈付きバージョンをオフラインで作成します。
reset
名前付きブランチを作成(または再作成)します。オプションで、特定のリビジョンから開始します。 resetコマンドを使用すると、フロントエンドは既存のブランチに対して新しい from
コマンドを発行したり、新しいコミットを作成せずに既存のコミットから新しいブランチを作成したりできます。
'reset' SP <ref> LF
('from' SP <commit-ish> LF)?
LF?
<ref> と <commit-ish> の詳細については、上記 commit
と from
を参照してください。
コマンドの後の LF
はオプションです(以前は必須でした)。
reset
コマンドを使用して、軽量(注釈なし)タグ(lightweight tag)を作成することもできます。 例えば:
reset refs/tags/938
from :938
これはコミットマーク :938
が参照するものを参照して、軽量タグ refs/tags/938
を作成します。
blob
パックファイルに1つのファイルリビジョンを書き込むように要求します。 リビジョンはコミットに接続されていません。 この接続は、割り当てられたマークを介してブロブを参照することにより、後続の commit
コマンドで形成する必要があります。
'blob' LF
mark?
original-oid?
data
一部のフロントエンドが独自にブロブの Git SHA-1 を生成し、それを直接 commit
にフィードすることを選択したため、ここでは mark コマンドはオプションです。 ただし、マークは安価で保管しやすく、使い勝手も良いため、これは一般的にはマークより手間がかかると思われます。
data
生データ(ブロブやファイルの内容や、 コミット・メッセージや、 注釈付きタグ・メッセージとして使用するため)を fast-import に提供します。 データは、正確なバイト・カウントを使用して提供することも、 終了行で区切ることもできます。 本番品質の変換を目的とした実際のフロントエンドは、より堅牢で高いパフォーマンスのために、 常に正確なバイト・カウント形式を使用すべきです。 区切り形式(delimited format)は、 主に fast-import のテストを目的としています。
data
コマンドの <raw> 部分に表示されるコメント行は、常にデータの本文の一部と見なされるため、fast-importによって無視されることはありません。 これにより、行が # で始まる可能性のある ファイル/メッセージ コンテンツを安全にインポートできます。
- Exact byte count format
-
フロントエンドは、データのバイト数を指定する必要があります。
'data' SP <count> LF <raw> LF?
ここで、<count> は <raw> 内に現れるバイト・データの正確な数です。 <count> の値は ASCII の 10 進整数として表されます。 <raw> の前後の
LF
は <count> に含まれず、 インポートされたデータにも含まれません。<raw> の後の
LF
はオプションです(以前は必須でした)が、推奨されます。 <raw> がLF
で終わっている場合は、 次のコマンドは次の行の列 0 で開始するため、 常に <raw> の後のLF
省略しないようにすると、 fast-import ストリームのデバッグが容易になります。 - Delimited format
-
区切り文字列は、データの終わりを示すために使用されます。 fast-importは、区切り文字を検索して長さを計算します。 この形式は主にテストに役立ち、実際のデータにはお勧めしません。
'data' SP '<<' <delim> LF <raw> LF <delim> LF LF?
ここで、<delim> は選択された区切り文字列です。 文字列 <delim> は、 <raw> 内の行に単独で表示されてはなりません。そうしないと、fast-importはデータが実際よりも早く終了すると見なします。 <raw> の直後に続く
LF
は <raw> の一部です。 これは区切り形式の制限の1つであり、最後のバイトとしてLFを持たないデータチャンクを提供することはできません。<delim>
LF
の行の後のLF
はオプションです(以前は必須でした)。
alias
最初に新しいオブジェクトを作成せずに、マークが特定のオブジェクトを参照していることを記録します。
'alias' LF
mark
'to' SP <commit-ish> LF
LF?
<commit-ish> の詳細については、上記の from
を参照してください。
checkpoint
fast-importを強制して、現在のパックファイルを閉じ、新しいパックファイルを開始し、現在のすべてのブランチ参照とタグとマークを保存します。
'checkpoint' LF
LF?
注意: fast-importは、現在のパックファイルが --max-pack-size
または 4 GiB のいずれか小さい方の制限に達すると、パックファイルを自動的に切り替えることに注意してください。 自動パックファイル切り替え中、fast-importは、ブランチの参照またはタグまたはマーク を更新しません。
checkpoint
はかなりのCPU時間とディスクI/Oを必要とする可能性があるため(パック全体のSHA-1チェックサムを計算し、対応するインデックスファイルを生成し、refを更新するため)、単一の checkpoint
コマンド完了に数分かかる場合があります。
フロントエンドは、非常に大規模で長時間実行されるインポート中、または別のGitプロセスにブランチへのアクセスを許可する必要があるときにチェックポイントを発行することを選択できます。 ただし、30 GiB Subversion リポジトリを fast-import によって約3時間でGitにロードできることを考えると、明示的なチェックポイントは必要ない場合があります。
コマンドの後の LF
はオプションです(以前は必須でした)。
progress
コマンドが入力ストリームから処理されるときに、 fast-import は progress
行全体を変更せずに、 標準の出力チャネル(ファイルデスクリプタ 1)に出力します。 このコマンドは、それ以外の、 現在のインポートや fast-import の内部状態には影響を与えません。
'progress' SP <any> LF
LF?
コマンドの <any> 部分には、 LF
を含まないバイトシーケンスを含めることができます。 コマンドの後の LF
はオプションです。 呼び出し元は、sedなどのツールを使用して出力を処理し、行の先頭部分を削除したい場合があるかもしれません。以下に例を示します:
frontend | git fast-import | sed 's/^progress //'
checkpoint
の直後に progress
コマンドを配置すると、 checkpoint
が完了したときにリーダーに通知され、 fast-import で更新された ref に安全にアクセスできます。
get-mark
fast-importが、標準出力または --cat-blob-fd
引数であらかじめ指定されたファイルディスクリプタに、マークに対応するSHA-1を表示するようにします。 このコマンドは、 それ以外の影響をインポートに与えません。 その目的は、 後でコミットがコミット・メッセージで参照する可能性のある SHA-1 達を取得することです。
'get-mark' SP ':' <idnum> LF
この出力を安全に読み取る方法の詳細については、以下の「Responses To Commands」(コマンドへの応答)を参照してください。
cat-blob
fast-import により、以前に --cat-blob-fd
引数で設定されたファイル・デスクリプターにブロブが出力されます。 このコマンドは、 それ以外の影響を現在のインポートに与えません。 その主な目的は、 fast-import のメモリにある可能性があるが、 ターゲット・リポジトリーからはアクセスできないブロブを取得することです。
'cat-blob' SP <dataref> LF
<dataref> は、以前に設定されたマーク参照(:
<idnum>)か、既存または書き込みの準備ができているGitブロブの完全な40バイトのSHA-1のいずれかです。
出力は git
cat-file
--batch
と同一形式を使用します:
<sha1> SP 'blob' SP <size> LF
<contents> LF
このコマンドは、 filemodify
ディレクティブを表示できる場所で使用でき、コミットの途中で使用できます。 インラインディレクティブを使用する filemodify
の場合、 data
ディレクティブの直前に表示することもできます。
この出力を安全に読み取る方法の詳細については、以下の「Responses To Commands」(コマンドへの応答)を参照してください。
ls
パスにあるオブジェクトに関する情報を、事前に --cat-blob-fd
引数で指定したファイルディスクリプタへ出力します。 これにより、アクティブなコミットからブロブを表示したり(cat-blob
を使用)、以前のコミットからブロブやツリーをコピーして現在のコミットで使用したり(filemodify
を使用))することができます。
ls
コマンドは、 filemodify
ディレクティブを表示できる場所でも使用でき、コミットの途中で使用できます。
- Reading from the active commit
-
この形式は、
commit
の途中でのみ使用できます。 パスは、fast-importのアクティブなコミット内のディレクトリエントリに名前を付けます。 この場合、パスはクォートする必要があります。'ls' SP <path> LF
- Reading from a named tree
-
<dataref> は、マーク参照(
:
<idnum>)、またはGitタグ、コミット、ツリーオブジェクトの完全な40バイトのSHA-1であり、既存または書き込みを待機しています。 パスは、 <dataref> で指定されたツリーの最上位を基準にしています。'ls' SP <dataref> SP <path> LF
<path> の詳細な説明については、上記の filemodify
を参照してください。
出力は git
ls-tree
<tree> --
<path> と同一形式を使用します:
<mode> SP ('blob' | 'tree' | 'commit') SP <dataref> HT <path> LF
<dataref>は、<path>にあるblob、tree、またはcommitオブジェクトを表し、後の get-mark
、 cat-blob
、 filemodify
、 ls
コマンドで使用できます。
そのパスにファイルまたはサブツリーがない場合、 git
fast-import
が代わりに報告します
missing SP <path> LF
この出力を安全に読み取る方法の詳細については、以下の「Responses To Commands」(コマンドへの応答)を参照してください。
feature
fast-importが指定の機能をサポートすることを要求するか、サポートしない場合は中止(abort)します。
'feature' SP <feature> ('=' <argument>)? LF
コマンドの <feature> 部分は、以下のいずれかになります:
- date-format
- export-marks
- relative-marks
- no-relative-marks
- force
-
先頭に
--
が付いた対応するコマンドラインオプションが、コマンドラインで渡されたかのように動作します(上記 OPTIONS 参照)。 - import-marks
- import-marks-if-exists
-
--import-marks
と同様ですが、2つの点が異なります。まず、ストリームごとに1つのfeature
import-marks
またはfeature
import-marks-if-exists
コマンドのみが許可されます。 次に、--import-marks=
または--import-marks-if-exists
コマンドラインオプションは、ストリーム内のこれらの「feature」コマンドのいずれかをオーバーライドします。 第3に、対応するコマンドラインオプションのようなfeature
import-marks-if-exists
は、存在しないファイルを黙ってスキップします。 - get-mark
- cat-blob
- ls
-
バックエンドがそれぞれ
get-mark
またはcat-blob
またはls
コマンドをサポートしていることを要求します。 指定されたコマンドをサポートしていないバージョンのfast-importは、そのことを示すメッセージとともに終了します。 これにより、サポートされていないコマンドが検出される前にインポートの初期部分で時間を無駄にするのではなく、明確なメッセージでインポートエラーを早期に発生させることができます。 - notes
-
バックエンドが
commit
コマンドのnotemodify
(N) サブコマンドをサポートしていることを要求します。 ノートをサポートしていないfast-importのバージョンは、そのことを示すメッセージとともに終了します。 - done
-
done
コマンドなしでストリームが終了した場合はエラーになります。 この機能がないと、ストリーム内の便利なポイントでフロントエンドが突然終了する原因となるエラーが検出されなくなる可能性があります。 これは、たとえば、インポートフロントエンドがその下位のgit fast-importインスタンスでSIGTERMまたはSIGKILLを発行せずに、操作の途中で停止した場合に発生する可能性があります。
option
指定されたオプションを処理して、git fast-importがフロントエンドのニーズに合った方法で動作するようにします。 フロントエンドで指定されたオプションは、ユーザーがgit fast-import自体に指定したオプションによって上書きされることに注意してください。
'option' SP <option> LF
コマンドの <option> 部分には、OPTIONSセクションにリストされているオプションのいずれかを含めることができます。これらのオプションは、先頭の --
がなくても、インポートのセマンティクスを変更せず、同じように扱われます。
optionコマンドは、非オプションコマンドがエラーになった後にオプションコマンドを与えるために、入力の最初のコマンドである必要があります(featureコマンドはカウントされません)。
以下のコマンドラインオプションはインポートセマンティクスを変更するため、オプションとして渡されない場合があります:
-
date-format
-
import-marks
-
export-marks
-
cat-blob-fd
-
force
done
done
機能が使用されていない場合は、EOFが読み取られたかのように扱われます。 これを使用して、fast-importに早期に終了するように指示できます。
--done
コマンドラインオプションまたは feature
done
コマンドが使用されている場合、 done
コマンドは必須であり、ストリームの終わりを示します。
RESPONSES TO COMMANDS
fast-importによって作成された新しいオブジェクトはすぐには利用できません。 ほとんどのfast-importコマンドは、次のチェックポイント(または完了)まで目に見える効果はありません。 フロントエンドは、コマンドが有効になる速度を気にせずに、fast-importの入力パイプを埋めるためのコマンドを送信できます。これにより、スケジューリングが簡素化され、パフォーマンスが向上します。
ただし、一部のフロントエンドでは、更新中に現在のリポジトリからデータを読み戻すことができると便利です(たとえば、ソース素材が、以前にインポートされたオブジェクトに適用されるパッチの観点からオブジェクトを記述している場合)。 これは、フロントエンドとfast-importを双方向パイプを介して接続することで実現できます:
mkfifo fast-import-output
frontend <fast-import-output |
git fast-import >fast-import-output
このように設定されたフロントエンドは、 progress
、 get-mark
、 ls
、 cat-blob
コマンドを使用して、進行中のインポートから情報を読み取ることができます。
デッドロックを回避するために、このようなフロントエンドは、ブロックする可能性のあるfast-importへの書き込みを実行する前に、 progress
、 ls
、 get-mark
、 cat-blob
からの保留中の出力を完全に消費する必要があります。
CRASH REPORTS
fast-importに無効な入力が指定された場合、ゼロ以外の終了ステータスで終了し、インポート先のGitリポジトリのトップレベルにクラッシュレポートが作成されます。 クラッシュレポートには、内部のfast-import状態のスナップショットと、クラッシュにつながる最も最近のコマンドが含まれています。
最近のすべてのコマンド(ストリームコメント、ファイル変更、進行状況コマンドを含む)は、クラッシュレポート内のコマンド履歴に表示されますが、生のファイルデータとコミットメッセージはクラッシュレポートから除外されます。 この除外により、レポートファイル内のスペースが節約され、fast-importが実行中に実行する必要のあるバッファリングの量が削減されます。
クラッシュレポートを作成した後、fast-importは現在のパックファイルを閉じ、マークテーブルをエクスポートします。 これにより、フロントエンド開発者はリポジトリの状態を検査し、クラッシュしたポイントからインポートを再開できます。 インポートが正常に完了しなかったため、変更されたブランチとタグはクラッシュ時に更新されません。 ブランチとタグの情報はクラッシュレポートに記載されており、更新が必要な場合は手動で適用する必要があります。
クラッシュ例:
$ cat >in <<END_OF_INPUT
# my very first test commit
commit refs/heads/master
committer Shawn O. Pearce <spearce> 19283 -0400
# who is that guy anyway?
data <<EOF
this is my commit
EOF
M 644 inline .gitignore
data <<EOF
.gitignore
EOF
M 777 inline bob
END_OF_INPUT
$ git fast-import <in
fatal: Corrupt mode: M 777 inline bob
fast-import: dumping crash report to .git/fast_import_crash_8434
$ cat .git/fast_import_crash_8434
fast-import crash report:
fast-import process: 8434
parent process : 1391
at Sat Sep 1 00:58:12 2007
fatal: Corrupt mode: M 777 inline bob
Most Recent Commands Before Crash
---------------------------------
# my very first test commit
commit refs/heads/master
committer Shawn O. Pearce <spearce> 19283 -0400
# who is that guy anyway?
data <<EOF
M 644 inline .gitignore
data <<EOF
* M 777 inline bob
Active Branch LRU
-----------------
active_branches = 1 cur, 5 max
pos clock name
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1) 0 refs/heads/master
Inactive Branches
-----------------
refs/heads/master:
status : active loaded dirty
tip commit : 0000000000000000000000000000000000000000
old tree : 0000000000000000000000000000000000000000
cur tree : 0000000000000000000000000000000000000000
commit clock: 0
last pack :
-------------------
END OF CRASH REPORT
TIPS AND TRICKS
以下のヒントとコツは、fast-importのさまざまなユーザーから収集されたものであり、提案として提供されています。
Use One Mark Per Commit
リポジトリ変換を行うときは、コミットごとに一意のマーク(mark
:
<n>)を使用し、コマンドラインで --export-marks
オプションを指定します。 fast-importは、すべてのマークとそれに対応するGitオブジェクトSHA-1をリストするファイルをダンプします。 フロントエンドがマークをソースリポジトリに結び付けることができる場合、各Gitコミットを対応するソースリビジョンと比較することで、インポートの正確性と完全性を簡単に確認できます。
PerforceやSubversionなどのシステムから来る場合、これは非常に単純なはずです。fast-importマークは、Perforceのチェンジセット番号またはSubversionのリビジョン番号でもある可能性があるためです。
Freely Skip Around Branches
インポート中に一度に1つのブランチに固執するようにフロントエンドをわざわざ最適化しようとしないでください。 これを行うと、fast-importの場合は少し速くなる可能性がありますが、フロントエンドコードの複雑さが大幅に増す傾向があります。
高速インポートに組み込まれているブランチLRUは非常に適切に動作する傾向があり、非アクティブなブランチをアクティブ化するコストは非常に低いため、ブランチ間でのバウンスはインポートのパフォーマンスに実質的に影響しません。
Handling Renames
名前を変更したファイルまたはディレクトリをインポートするときは、対応するコミット中に古い名前を削除し、新しい名前を変更するだけです。 Gitは、コミット中に明示的にではなく、事後に名前変更の検出を実行します。
Use Tag Fixup Branches
他のいくつかのSCMシステムでは、ユーザーは同じ コミット/チェンジセット からではない複数のファイルからタグを作成できます。 または、リポジトリで使用可能なファイルのサブセットであるタグを作成します。
これらのタグをそのままGitにインポートするには、タグのコンテンツと一致するようにファイルを「修正」するコミットを少なくとも1つ実行する必要があります。 fast-importの reset
コマンドを使用して、通常のブランチスペースの外側にあるダミーブランチをタグのベースコミットにリセットし、1つ以上のファイル修正コミットをコミットして、最後にダミーブランチにタグを付けます。
たとえば、すべての通常のブランチは refs/heads/
の下に保存されるため、タグ修正ブランチには TAG_FIXUP
という名前を付けます。 このように、インポーターによって使用される修正ブランチが、ソースからインポートされた実際のブランチと名前空間の競合を持つことは不可能です(名前 TAG_FIXUP
は refs/heads/TAG_FIXUP
ではありません)。
フィックスアップ(fixup)をコミットするときは、 merge
を使用してファイルリビジョンを提供しているコミットをフィックスアップブランチに接続することを検討してください。 そうすることで、 git
blame
などのツールが実際のコミット履歴を追跡し、ソースファイルに適切に注釈を付けることができます。
fast-importが終了した後、フロントエンドはダミーブランチを削除するために rm
.git/TAG_FIXUP
を実行する必要があります。
Import Now, Repack Later
fast-importが完了するとすぐに、Gitリポジトリは完全に有効になり、使用できるようになります。 通常、これは非常に大規模なプロジェクト(100,000以上のコミット)の場合でも、非常に短い時間しかかかりません。
ただし、データの局所性とアクセスパフォーマンスを向上させるには、リポジトリを再パックする必要があります。 また、非常に大規模なプロジェクトでは数時間かかる場合があります(特に、 -f
および 大きな --window
パラメーターが使用されている場合)。 再パックはリーダーやライターと一緒に実行しても安全なので、バックグラウンドで再パックを実行し、再パックが終了したらリーダーやライターを終了させます。 あなたが新しいGitプロジェクトに挑戦するのを待たされる事はありません!
あなたが再パックを待つことを選択した場合は、再パックが完了するまでベンチマークやパフォーマンステストを実行しないでください。 その場合、 fast-importは、実際の使用状況では決して見られないような、最適でないパックファイルを出力します。
Repacking Historical Data
非常に古くにインポートされたデータ(たとえば、昨年より古い)を再パックする場合は、 git
repack
を実行するときに、 --window=50
(またはそれ以上)を指定して余分なCPU時間を費やすことを検討してください。 これには時間がかかりますが、作成されるパックファイルも小さくなります。 あなたが労力を費やす必要があるのは1回だけで、あなたのプロジェクトを使用するすべての人が小さくなったリポジトリの恩恵を受けることができます。
Include Some Progress Messages
時々、フロントエンドに progress
メッセージを送信してfast-importします。 メッセージの内容は完全に自由形式であるため、現在のコミット日が翌月に移動するたびに、現在の月と年を出力することをお勧めします。あなたのユーザーは、処理されたデータストリームの量をよりよく知ることができます。
PACKFILE OPTIMIZATION
ブロブを高速にパックする場合、インポートは常に最後に書き込まれたブロブに対して削除を試みます。 フロントエンドによって特別に調整されていない限り、これはおそらく同じファイルの以前のバージョンではないため、生成されるデルタは可能な限り最小にはなりません。 結果のパックファイルは圧縮されますが、最適ではありません。
単一のファイルのすべてのリビジョンに効率的にアクセスできるフロントエンド(たとえば、 RCS/CVS ,v file の読み取り)は、連続する blob
コマンドのシーケンスとして、そのファイルのすべてのリビジョンを提供することを選択できます。 これにより、fast-importでさまざまなファイルリビジョンを相互に区別し、最終的なパックファイルのスペースを節約できます。 マークは、後で一連の commit
コマンド中に個々のファイルリビジョンを識別するために使用できます。
fast-importによって作成されたパックファイルは、適切なディスクアクセスパターンを促進しません。 これは、標準入力で受信した順序でデータをfast-importで書き込むことが原因ですが、Gitは通常、パックファイル内のデータを整理して、最新の(現在の先端)データを履歴データの前に表示します。 Gitはまた、コミットをクラスター化し、キャッシュの局所性を向上させることでリビジョンのトラバーサルを高速化します。
このため、fast-importが完了した後、ユーザーがリポジトリを git
repack
-a
-d
で再パックし、Gitがパックファイルを再編成してデータアクセスを高速化できるようにすることを強くお勧めします。 ブロブデルタが最適ではない場合(上記参照)、すべてのデルタの再計算を強制するために -f
オプションを追加すると、最終的なパックファイルサイズを大幅に減らすことができます(ほとんどの場合30〜50%小さくなります)。
git
repack
を実行する代わりに、 git
gc
--aggressive
を実行することもできます。これにより、インポート後に他のものも最適化されます(たとえば、loose refs をパックします)。 git-gc(1) の「AGGRESSIVE」セクションに記載されているように、 --aggressive
オプションは、 git-repack(1) への -f
オプションを使用して新しいデルタを検索します。 上記で詳しく説明した理由により、fast-importの後に --aggressive
を使用することは、価値があることがわかっている数少ないケースの1つです。
MEMORY UTILIZATION
fast-import がインポートを実行するために必要なメモリの量に影響を与えるいくつかの要因があります。 コア Git のクリティカル・セクションと同様に、 fast-import は独自のメモリ・アロケータを使用して、 malloc に関連するオーバーヘッドを減らします。 実際には、 fast-import は、大きなブロック割り当てを使用するため、 malloc オーバーヘッドをほぼ0に平準化する傾向があります。
per object
fast-importは、この実行で書き込まれるすべてのオブジェクトのメモリ内構造を維持します。 32ビットシステムでは、構造は32バイトですが、64ビットシステムでは、構造は40バイトです(ポインタサイズが大きいため)。 テーブル内のオブジェクトは、fast-importが終了するまで割り当てが解除されません。 32ビットシステムに200万個のオブジェクトをインポートするには、約64MiBのメモリが必要です。
オブジェクトテーブルは、実際にはオブジェクト名(一意のSHA-1)をキーとするハッシュテーブルです。 このストレージ構成により、fast-importで既存または既に書き込まれたオブジェクトを再利用し、出力パックファイルへの重複の書き込みを回避できます。 インポートでは、ブロブの重複が驚くほど一般的です。これは通常、ソースでのブランチのマージが原因です。
per mark
マークは、マークごとに1つのポインター(ポインターのサイズに応じて4バイトまたは8バイト)を使用して、まばらな配列に格納されます。 配列はまばらですが、フロントエンドでは 1〜n のマークを使用することを強くお勧めします。ここで、n はこのインポートに必要なマークの総数です。
per branch
ブランチはアクティブと非アクティブにクラス分けされます。 2つのクラスのメモリ使用量は大幅に異なります。
非アクティブなブランチは、ブランチごとに96バイトまたは120バイト(それぞれ32ビットまたは64ビットシステム)とブランチ名の長さ(通常は200バイト未満)を使用する構造に格納されます。 fast-importは、2MiB未満のメモリで10,000もの非アクティブなブランチを簡単に処理します。
アクティブなブランチには非アクティブなブランチと同じオーバーヘッドがありますが、そのブランチで最近変更されたすべてのツリーのコピーも含まれています。 ブランチがアクティブになってからサブツリー include
が変更されていない場合、その内容はメモリに読み込まれませんが、ブランチがアクティブになってからコミットによってサブツリー src
が変更されている場合、その内容はメモリに読み込まれます。
アクティブなブランチは、そのブランチに含まれるファイルに関するメタデータを格納するため、メモリ内のストレージサイズがかなり大きくなる可能性があります(以下参照)。
fast-importは、単純な「最も最近使用されていない」アルゴリズム(least-recently-used algorithm)に基づいて、アクティブなブランチを自動的に非アクティブなステータスに移動します。 LRUチェーンは、commit
コマンドごとに更新されます。 アクティブなブランチの最大数は、コマンドラインで --active-branches=
を使用して増減できます。
per active tree
ツリー(別名ディレクトリ)は、エントリに必要なメモリに加えて、わずか12バイトのメモリを使用します(以下「per active file」参照)。 ツリーのオーバーヘッドは個々のファイルエントリで償却されるため、ツリーのコストは実質的に0です。
per active file entry
アクティブツリー内のファイル(およびサブツリーへのポインター)には、エントリごとに52バイトまたは64バイト(32/64 ビットプラットフォーム)が必要です。 スペースを節約するために、ファイル名とツリー名は共通の文字列テーブルにプールされ、ファイル名 Makefile
が(文字列ヘッダーのオーバーヘッドを含めた後)、プロジェクト内で何度発生しても、わずか16バイトしか使用しないようにします。
アクティブブランチLRUは、ファイル名文字列プールおよびサブツリーの遅延読み込みと組み合わせると、fast-importにより、非常に限られたメモリフットプリント(アクティブブランチあたり2.7 MiB未満)で2,000以上のブランチと45,114以上のファイルを持つプロジェクトを効率的にインポートできます。
SIGNALS
SIGUSR1 を git
fast-import
プロセスに送信すると、現在のパックファイルが早期に終了し、 checkpoint
コマンドがシミュレートされます。 せっかちなオペレーターは、この機能を使用して、実行時間の追加と圧縮率の低下を犠牲にして、進行中のインポートからオブジェクトとrefを確認できます。
CONFIGURATION
このセクションの以下のすべては、 git-config(1) ドキュメントの抜粋です。 内容は git-config(1) ドキュメント にあるものと同一です:
- fastimport.unpackLimit
-
git-fast-import(1) によってインポートされたオブジェクトの数がこの制限を下回る場合、オブジェクトは緩いオブジェクト(loose object)ファイルに解凍されます。 ただし、インポートされたオブジェクトの数がこの制限以上の場合、パックはパックとして保存されます。 fast-import(高速インポート)からパックを保存すると、特に低速のファイルシステムで、インポート操作をより速く完了することができます。 設定されていない場合は、代わりに
transfer.unpackLimit
の値が使用されます。
SEE ALSO
GIT
Part of the git(1) suite