SYNOPSIS
$GIT_DIR/info/attributes, .gitattributes
DESCRIPTION
gitattributes
ファイルは、パス名に属性(attributes)を与える単純なテキストファイルです。
gitattributes
ファイルの各行は以下の形式です:
pattern attr1 attr2 ...
つまり、パターンの後に空白(whitespaces)で区切られた属性リストが続きます。先頭と末尾の空白は無視されます。 #
で始まる行は無視されます。 二重引用符("
)で始まるパターンは、Cスタイルでクォートされます。パターンが問題のパスと一致すると、その行にリストされている属性がそのパスに与えられます。
各属性は、特定のパスに対して以下のいずれかの状態になる可能性があります:
- 設定(set)
-
パスには、特別な値
true
を持つ属性があります。これは、属性リストにその属性の名前のみをリストすることによって指定されます。 - 設定解除(unset)
-
パスには、特別な値
false
を持つ属性があります。 これは、属性リストにマイナス記号-
(\x2d)で始まる属性の名前をリストすることによって指定されます。 - 値を設定
-
パスには、指定の文字列値を持つ属性があります。これは、属性の名前の後に等号
=
とその値を、属性リストにリストすることによって指定されます。 - 未指定(unspecified)
-
パスに一致するパターンはなく、パスに属性があるかどうかはわかりません。パスの属性は未指定(unspecified)であると言われます。
複数のパターンがパスに一致する場合、後の行が前の行をオーバーライドします。このオーバーライドは属性ごとに行われます。
パターンがパスと一致するルールは、以下のいくつかの例外を除いて、 .gitignore
ファイル(gitignore(5) 参照)と同じです:
-
否定パターンは使えません
-
ディレクトリに一致するパターンは、そのディレクトリ内のパスに再帰的に一致しません(したがって、属性ファイルで末尾のスラッシュの
path/
構文を使用しても意味がありません。代わりにpath/**
を使用してください)
パスに割り当てる属性を決定するとき、Gitは、(優先順位が最も高い) $GIT_DIR/info/attributes
ファイルと、問題のパスと同じディレクトリにある .gitattributes
ファイルと、作業ツリーの最上位までその親ディレクトリを参照します(.gitattributes
を含むディレクトリが問題のパスから離れるほど、優先順位は低くなります)。最後に、(優先順位が最も低い)グローバルファイルとシステム全体のファイルが考慮されます。
.gitattributes
ファイルが作業ツリーにない場合、インデックス内のパスがフォールバックとして使用されます。チェックアウト処理では、インデックスの .gitattributes
が使用され、作業ツリーのファイルがフォールバックとして使用されます。
単一のリポジトリのみに影響を与えたい(つまり、そのリポジトリの1人のユーザーのワークフローに固有のファイルに属性を割り当てる)場合は、属性を $GIT_DIR/info/attributes
ファイルに配置する必要があります。バージョン管理して他のリポジトリに配布する必要がある属性(つまり、すべてのユーザーが関心を持つ属性)は、 .gitattributes
ファイルに入れる必要があります(git-config(1) を参照)。 あるユーザーのすべてのリポジトリに影響を与える属性は、 core.attributesFile
構成オプションで指定されたファイルに配置する必要があり、そのデフォルト値は $XDG_CONFIG_HOME/git/attributes です。 $XDG_CONFIG_HOME が設定されていないか空の場合、代わりに $HOME/.config/git/attributes が使用されます。システム上のすべてのユーザーの属性は、 $(prefix)/etc/gitattributes
ファイルに配置する必要があります。
しばしばあなたは、 Unspecified(未指定)状態へのパスの属性の設定をオーバーライドする必要があります。これは、感嘆符 !
が前に付いた属性の名前をリストすることで行えます。
EFFECTS
Gitによる特定の操作は、特定の属性をパスに割り当てることによって影響を受ける可能性があります。 現在、以下の操作は属性対応(attributes-aware)です。
Checking-out and checking-in
これらの属性は、 git switch
や git checkout
や git merge
などのコマンドが実行されたときに、リポジトリに保存されているコンテンツが作業ツリーファイルにコピーされる方法に影響します。 また、Gitが git add
や git commit
する時に準備したコンテンツをリポジトリの作業ツリーに保存する方法にも影響します。
text
この属性はパスをテキスト・ファイルとしてマークし、行末変換を有効にします。これにマッチするファイルがインデックスに追加されると、ファイルの行末はインデックス内で LF に正規化されます。逆に、ファイルがインデックスから作業ディレクトリ(working directory)にコピーされるとき、その行末は eol
属性と Git 設定とプラットフォームに応じて、 LF から CRLF に変換される場合があります(下記の eol
の説明を参照)。
- 設定(set)
-
パスに
text
属性を設定すると、上記のようにチェックインおよびチェックアウト時の行末変換が有効になります。以前にそのファイルが Git に追加された時は CRLF 行末であった場合でも、そのファイルがチェックインされるたびに、インデックス内の行末は LF に正規化されます。 - 設定解除(unset)
-
パスの
text
属性を設定解除(unset)すると、チェックインまたはチェックアウト時に行末変換を試行しないようにGitに指示します。 -
文字列値
auto
を設定 -
text
がauto
に設定されている場合、 Git はファイルがテキストであるかバイナリであるかを自動的に決定します。 ファイルがテキストであり、かつ、ファイルが CRLF 末尾でまだ Git に存在していない場合、 行末は上記のようにチェックインおよびチェックアウト時に変換されます。それ以外の場合、チェックインまたはチェックアウト時に変換は行われません。 - 未指定(unspecified)
-
text
属性が指定されていない場合、Gitはcore.autocrlf
構成変数を使用してファイルを変換する必要があるかどうかを判断します。
その他の値の場合、Gitは text
が未指定(unspecified)であるかのように動作します。
eol
この属性は、チェックアウト時に作業ツリー内で指定の行末スタイルを使用するパスをマークします。これは、 text
または text=auto
が設定されている場合にのみ有効です(上記参照)。ただし、 text
が指定されていない場合、 eol
を指定すると自動的に text
が設定されます。
-
文字列値
crlf
を設定 -
この設定により、ファイルがチェックアウトされるときに、作業ディレクトリ内のファイルの行末が CRLF に変換されます。
-
文字列値
lf
を設定 -
この設定により、ファイルがチェックアウトされるときに、作業ディレクトリ内でインデックス内と同じ行末が使用されます。
- 未指定(unspecified)
-
ファイルの
eol
属性が指定されていない場合、作業ディレクトリ内の行末はcore.autocrlf
またはcore.eol
設定変数によって決定されます(git-config(1) のこれらのオプションの定義を参照してください)。text
が設定されているが、 これらの変数のどちらも設定されていない場合、 デフォルトは Windows ではeol=crlf
、他のすべてのプラットフォームではeol=lf
になります。
crlf
属性との下位互換性
下位互換性のために、 crlf
属性は以下のように解釈されます:
crlf text
-crlf -text
crlf=input eol=lf
行末変換
Gitは通常、ファイルの内容をそのままにしますが、リポジトリ内で行末をLFに正規化し、オプションで、ファイルがチェックアウトされたときにCRLFに変換するように構成できます。
あなたが作業しているリポジトリに関係なく、あなたの作業ディレクトリ内でCRLF行末を設定したいだけの場合は、属性を使用せずに構成変数 core.autocrlf
を設定できます。
[core]
autocrlf = true
これにより、テキストファイルの正規化は強制されませんが、リポジトリに導入するテキストファイルの行末は、追加時にLFに正規化され、リポジトリですでに正規化されているファイルは正規化されたままになります。
貢献者(contributor)がリポジトリに導入するテキストファイルの行末が正規化されていることを確認する場合は、「全て」のファイルに対して text
属性を "auto" に設定できます。
* text=auto
属性を使用すると、行末の変換方法をきめ細かく制御できます。以下は、Gitが .txt
と、.vcproj
と .sh
ファイルを正規化し、 .vcproj
ファイルがCRLFを持ち、 .sh
ファイルが作業ディレクトリでLFを持っていることを確認し、.jpg
ファイルがその内容に関係なく正規化されないようにする例です。
* text=auto
*.txt text
*.vcproj text eol=crlf
*.sh text eol=lf
*.jpg -text
Note
|
中央リポジトリへのプッシュとプルを使用してクロスプラットフォームプロジェクトで text = auto 変換が有効になっている場合、CRLFを含むテキストファイルを正規化する必要があります。 |
クリーンな作業ディレクトリから始めます:
$ echo "* text=auto" >.gitattributes
$ git add --renormalize .
$ git status # 正規化されるファイルを表示
$ git commit -m "Introduce end-of-line normalization"
正規化してはならないファイルが git status
に表示される場合は、 git add -u
を実行する前に、以下のように text
属性の設定を解除してください。
manual.pdf -text
逆に、Gitが検出しないテキストファイルは、以下のように正規化を手動で有効にすることができます。
weirdchars.txt text
core.safecrlf
が "true" または "warn" に設定されている場合、Gitは変換が core.autocrlf
の現在の設定に対して可逆的であるかどうかを確認します。 "true" の場合、Gitは不可逆的な変換を拒否します。 "warn" の場合、Gitは警告を出力するだけで、元に戻せない変換を受け入れます。作業ツリー内のファイルに対してこのような変換が行われるのを防ぐための安全トリガーがありますが、いくつかの例外がありますが、しかし…
-
git add
自体は作業ツリー内のファイルに影響を与えません。その次に行うチェックアウトは影響を与えるため、セーフティーがトリガーされます: -
パッチでテキストファイルを更新するための
git apply
は作業ツリー内のファイルに影響を与えますが、操作はテキストファイルに関するものであり、CRLF変換は行末の不整合の修正に関するものであるため、セーフティーはトリガーされません。 -
git diff
自体は作業ツリー内のファイルに影響を与えません。多くの場合、次にgit add
する予定の変更を検査するために実行されます。潜在的な問題を早期に発見するために、セーフティーがトリガーされます。
working-tree-encoding
Gitは、ASCIIまたはそのスーパーセットの1つ(UTF-8、ISO-8859-1など)でエンコードされたファイルをテキストファイルとして認識します。他の特定のエンコーディング(UTF-16など)でエンコードされたファイルはバイナリとして解釈されるため、組み込みのGitテキスト処理ツール(git diff
など)や、ほとんどのGitWebフロントエンドはデフォルトでこれらのファイルのコンテンツを視覚化しません 。
このような場合、 working-tree-encoding
属性を使用して作業ディレクトリ内のファイルのエンコーディングをGitに指示できます。この属性を持つファイルがGitに追加されると、Gitは指定されたエンコーディングからUTF-8にコンテンツを再エンコードします。最後に、GitはUTF-8でエンコードされたコンテンツを内部データ構造(「インデックス」と呼ばれます)に格納します。チェックアウト時に、コンテンツは指定されたエンコーディングに再エンコードされます。
注意: working-tree-encoding
属性を使用すると、いくつかの落とし穴があることに注意してください:
-
(2018年3月現在、)代替のGit実装(JGitやlibgit2など)やGit古いバージョンは、
working-tree-encoding
属性をサポートしていません。リポジトリでworking-tree-encoding
属性を使用する場合は、リポジトリを使用するすべてのクライアントがそれをサポートしていることを確認することを強くお勧めします。たとえば、Microsoft Visual Studio リソースファイル(
*.rc
)またはPowerShellスクリプトファイル(*.ps1
)は、UTF-16でエンコードされる場合があります。*.ps1
をUTF-16のファイルとして宣言し、working-tree-encoding
が有効なGitクライアントでfoo.ps1
を追加すると、foo.ps1
はUTF-8として内部に保存されます。working-tree-encoding
をサポートしていないクライアントは、foo.ps1
をUTF-8でエンコードされたファイルとしてチェックアウトします。これは通常、このファイルのユーザーに問題を引き起こします。working-tree-encoding
属性をサポートしないGitクライアントが新しいファイルbar.ps1
を追加した場合、bar.ps1
は内部に「現状のまま」(この例ではおそらくUTF-16として)保存されます。そしてそれに対して、working-tree-encoding
をサポートするクライアントは、内部コンテンツをUTF-8として解釈し、チェックアウト時にUTF-16に変換しようとします。その操作は失敗し、エラーが発生します。 -
コンテンツを非UTFエンコーディングに再エンコードすると、変換がUTF-8ラウンドトリップセーフではない可能性があるため、エラーが発生する可能性があります。 エンコーディングがラウンドトリップセーフではないと思われる場合は、それを
core.checkRoundtripEncoding
に追加して、Gitにラウンドトリップエンコーディングをチェックさせます(git-config(1) を参照)。 SHIFT-JIS(日本語文字セット)はUTF-8でラウンドトリップ問題があることが知られており、デフォルトでチェックされています。 -
コンテンツを再エンコードするには、計算機資源が必要なため、特定のGit操作(
git checkout
やgit add
など)の速度を低下させる可能性があります。
working-tree-encoding
属性は、ファイルをUTF-8エンコーディングで保存できない場合や、Gitでコンテンツをテキストとして処理できるようにする場合にのみ使用してください。
例として、 あなたの *.ps1
ファイルがバイトオーダーマーク(BOM)付きでUTF-16エンコードされており、Gitであなたのプラットフォームに基づいて自動行末変換を実行する場合、以下の属性を使用します。
*.ps1 text working-tree-encoding=UTF-16
あなたの * .ps1
ファイルがBOMなしでUTF-16リトルエンディアンでエンコードされており、Gitで作業ディレクトリのWindows行末を使用する場合は、以下の属性を使用します(BOMを使用したUTF-16リトルエンディアンが必要な場合、 UTF-16LE
の代わりに UTF-16LE-BOM
を使用します)。あいまいさを避けるために working-tree-encoding
属性を使用する場合は、行末を eol
で明示的に定義することを強くお勧めします。
*.ps1 text working-tree-encoding=UTF-16LE eol=CRLF
あなたは以下のコマンドを使用して、あなたのプラットフォームで使用可能なすべてのエンコーディングのリストを取得できます:
iconv --list
ファイルのエンコーディングがわからない場合、あなたは file
コマンドを使用してエンコーディングを推測できます:
file foo.ps1
ident
パスに属性 ident
が設定されている場合、Gitはチェックアウト時にブロブオブジェクト内の $Id$
を $Id:
に置き換え、その後に40文字の16進ブロブオブジェクト名が続き、その後にドル記号 $
が続きます。ワークツリーファイルで $Id:
で始まり、 $
で終わるバイトシーケンスは、チェックイン時に $Id$
に置き換えられます。
filter
filter
属性には、構成で指定されたフィルタドライバの名前を文字列で指定することができます。
フィルタドライバは、 clean
コマンドと smudge
コマンドで構成されており、どちらも指定しないでおくことができます。チェックアウト時に、 smudge
コマンドが指定されると、コマンドはその標準入力からブロブオブジェクトを供給され、その標準出力はワークツリーファイルを更新するために使用されます。同様に、 clean
コマンドはチェックイン時にワークツリーファイルの内容を変換するために使用されます。デフォルトでは、これらのコマンドは単一のブロブのみを処理して終了します。長時間実行される process
フィルターが clean
および/または smudge
フィルターの代わりに使用される場合、Gitは単一のGitコマンドの存続期間中、単一のフィルターコマンド呼び出しですべてのブロブを処理できます。例えば git --all
を追加します。長時間実行される process
フィルターが構成されている場合、構成された単一のブロブフィルターよりも常に優先されます。 process
フィルターとの通信に使用されるプロトコルの説明については、以下のセクションを参照してください。
コンテンツフィルタリングの用途の1つは、プラットフォームやファイルシステムやユーザーが使用しやすい形にコンテンツをもみもみ(massage)することです。この操作モードでは、ここでのキーワードは「より便利」であり、「使用できないものを使用可能にする」ではありません。 つまり、誰かがフィルタードライバーの定義を設定解除した場合、または適切なフィルタープログラムを持っていない場合でも、プロジェクトは引き続き使用可能である必要があります。
コンテンツフィルタリングのもう1つの用途は、リポジトリに直接使用できないコンテンツ(Gitの外部に保存されている実際のコンテンツを参照するUUIDや暗号化されたコンテンツなど)を保存し、チェックアウト時に使用可能な形式に変換することです(例: 外部コンテンツをダウンロードする、または暗号化されたコンテンツを復号化する)。
これらの2つのフィルターの振る舞いは異なり、デフォルトでは、フィルターは前者と見なされ、コンテンツをより便利な形にもみもみ(massage)します。構成にフィルタードライバー定義がないか、ゼロ以外のステータスで終了するフィルタードライバーはエラーではありませんが、フィルターを無操作パススルーにします。
filter.<driver>.required 構成変数を true
に設定することにより、フィルター自体が使用できないコンテンツを使用可能なコンテンツに変換することを宣言できます。
注意: clean フィルターを変更するたびに、リポジトリを再正規化する必要があります: $ git add --renormalize
たとえば、 .gitattributes
で、あなたはパスに filter
属性を割り当てるとします。
*.c filter=indent
次に、あなたは以下のように .git/config
で filter.indent.clean
と filter.indent.smudge
構成を定義して、ソースファイルがチェックインされたとき(clean
が実行されます)と、チェックアウトされたとき(コマンドが cat
であるため、変更は行われません)、にCプログラムの内容を変更するコマンドのペアを指定します。
[filter "indent"]
clean = indent
smudge = cat
最良の結果を得るには、 clean
を2回実行しても出力を変更しないでください("clean→clean" は "clean" と同等である必要があります)。また、複数の smudge
コマンドで clean
の出力を変更しないでください("smudge→smudge→clean" は "clean” と同等である必要があります)。 以下のmergingセクションを参照してください。
"indent" フィルターは、この点で適切に動作します。すでに正しくインデントされている入力は変更されません。この場合、smudgeフィルターがないということは、cleanフィルターが自身の出力を変更せずに受け入れる必要があることを意味します。
保存されたコンテンツを使用可能にするためにフィルターが成功する必要がある場合は、構成でフィルターが required
(必須)であることを宣言できます:
[filter "crypt"]
clean = openssl enc ...
smudge = openssl enc -d ...
required
フィルタコマンドラインのシーケンス %f
は、フィルタが機能しているファイルの名前に置き換えられます。フィルタはこれをキーワード置換で使用する場合があります。例えば:
[filter "p4"]
clean = git-p4-filter --clean %f
smudge = git-p4-filter --smudge %f
注意: %f
は、作業中のパスの名前であることに注意してください。フィルタリングされているバージョンによっては、ディスク上の対応するファイルが存在しないか、内容が異なる場合があります。したがって、smudgeおよびcleanコマンドは、ディスク上のファイルにアクセスしようとするのではなく、標準入力で提供されるコンテンツのフィルターとしてのみ機能する必要があります。
Long Running Filter Process
フィルタコマンド(文字列値)が filter.<driver>.process
を介して定義されている場合、Gitは単一のGitコマンドの存続期間中、単一のフィルタ呼び出しですべてのブロブを処理できます。 これは、長時間実行プロセスプロトコル( technical/long-running-process-protocol.txt にて説明)を使用して実現されます。
Gitは、クリーニング(cleaned)またはスマッジング(smudged)が必要な最初のファイルを検出すると、フィルターを開始してハンドシェイクを実行します。ハンドシェイクでは、Gitによって送信されるウェルカムメッセージは "git-filter-client" であり、プロトコルバージョン2("version=2")のみがサポートされ、サポートされる機能は "clean" と "smudge" と ”delay" です。
その後、Gitはフラッシュパケットで終了する "key=value" ペアのリストを送信します。リストには、少なくとも(サポートされている機能に基づく)フィルターコマンドと、リポジトリルートを基準にしてフィルタリングするファイルのパス名が含まれます。フラッシュパケットの直後に、Gitはコンテンツを0個以上のpkt-lineパケットに分割して送信し、フラッシュパケットを送信してコンテンツを終了します。フィルタは、コンテンツと最終的なフラッシュパケットを受信する前に、応答を送信してはならないことに注意してください。 また、 "key=value" ペアの「value」には「=」文字を含めることができますが、キーには含めることはできません。
packet: git> command=smudge
packet: git> pathname=path/testfile.dat
packet: git> 0000
packet: git> CONTENT
packet: git> 0000
フィルタは、フラッシュパケットで終了する "key=value" ペアのリストで応答することが期待されます。フィルタで問題が発生しない場合は、リストに "success" ステータスが含まれている必要があります。これらのパケットの直後に、フィルターはコンテンツを0個以上のpkt-lineパケットで送信し、最後にフラッシュパケットを送信することが期待されます。最後に、フラッシュパケットで終了する "key=value" ペアの2番目のリストが必要です。フィルタは、2番目のリストのステータスを変更したり、空のリストでステータスをそのまま維持したりできます。空のリストは、フラッシュパケットで終了する必要があることに注意してください。
packet: git< status=success
packet: git< 0000
packet: git< SMUDGED_CONTENT
packet: git< 0000
packet: git< 0000 # empty list, keep "status=success" unchanged!
結果のコンテンツが空の場合、フィルターは "success" ステータスとフラッシュパケットで応答して、空のコンテンツを通知することが期待されます。
packet: git< status=success
packet: git< 0000
packet: git< 0000 # empty content!
packet: git< 0000 # empty list, keep "status=success" unchanged!
フィルタがコンテンツを処理できない、または処理したくない場合は、 "error" ステータスで応答することが期待されます。
packet: git< status=error
packet: git< 0000
フィルタの処理中にエラーが発生した場合、コンテンツが(部分的または完全に)送信された後、ステータス "error" を送信できます。
packet: git< status=success
packet: git< 0000
packet: git< HALF_WRITTEN_ERRONEOUS_CONTENT
packet: git< 0000
packet: git< status=error
packet: git< 0000
フィルタがGitプロセスの存続期間中、コンテンツと将来のコンテンツを処理できない、または処理したくない場合は、プロトコルの任意の時点で "abort" ステータスで応答することが期待されます。
packet: git< status=abort
packet: git< 0000
"error"/"abort" ステータスが設定されている場合、Gitはフィルタープロセスを停止も再開もしません。 ただし、Gitは filter.<driver>.required`フラグに従って終了コードを設定し、 `filter.<driver>.clean
/ filter.<driver>.smudge
メカニズムの振る舞いを真似っこします。
通信中にフィルターが停止した場合、またはプロトコルに準拠していない場合、Gitはフィルタープロセスを停止し、処理が必要な次のファイルでフィルターを再開します。 filter.<driver>.required
フラグの設定によっては、Gitはそれをエラーとして解釈します。
Delay
フィルタが "delay" 機能をサポートしている場合、Gitはフィルタコマンドとパス名の後にフラグ "can-delay" を送信できます。このフラグは、コンテンツなしでステータス "delayed" とフラッシュパケットで応答することにより、フィルターが現在のブロブのフィルタリングを遅らせることができることを示します(たとえば、ネットワーク遅延を補正するため)。
packet: git> command=smudge
packet: git> pathname=path/testfile.dat
packet: git> can-delay=1
packet: git> 0000
packet: git> CONTENT
packet: git> 0000
packet: git< status=delayed
packet: git< 0000
フィルタが "delay" 機能をサポートしている場合は、 "list_available_blobs" コマンドをサポートしている必要があります。Gitがこのコマンドを送信すると、フィルターは、以前に遅延されて現在使用可能なブロブを表すパス名のリストを返すことが期待されます。リストはフラッシュパケットで終了する必要があり、その後に "success" ステータスが続き、これもフラッシュパケットで終了します。 遅延パスのブロブがまだ利用できない場合、フィルターは少なくとも1つのブロブが利用可能になるまで応答をブロックすることが期待されます。フィルタは、空のリストを送信することで、遅延ブロブがなくなったことをGitに伝えることができます。フィルタが空のリストで応答するとすぐに、Gitは質問を停止します。この時点でGitが受信していないすべてのブロブは欠落していると見なされ、エラーが発生します。
packet: git> command=list_available_blobs
packet: git> 0000
packet: git< pathname=path/testfile.dat
packet: git< pathname=path/otherfile.dat
packet: git< 0000
packet: git< status=success
packet: git< 0000
Gitはパス名を受け取った後、対応するブロブを再度要求します。これらのリクエストには、パス名と空のコンテンツセクションが含まれています。フィルターは、上記で説明した通常の方法で汚れたコンテンツ(smudged content)に応答することが期待されます。
packet: git> command=smudge
packet: git> pathname=path/testfile.dat
packet: git> 0000
packet: git> 0000 # empty content!
packet: git< status=success
packet: git< 0000
packet: git< SMUDGED_CONTENT
packet: git< 0000
packet: git< 0000 # empty list, keep "status=success" unchanged!
Example
長時間実行されるフィルターのデモの実装は、Gitコアリポジトリにある contrib/long-running-filter/example.pl
にあります。 独自の長時間実行フィルタープロセスを開発する場合は、 GIT_TRACE_PACKET
環境変数がデバッグに非常に役立ちます(git(1) を参照)。
既存の filter.<driver>.clean
や filter.<driver>.smudge
コマンドを filter.<driver>.process
で使用できないことに注意してください。前者は後者とは異なるプロセス間通信プロトコルを使用するからです。
チェックイン/チェックアウト属性間の相互作用
チェックインのコードの流れでは、ワークツリーファイルは最初に(指定され、対応するドライバーが定義されている場合、) filter
ドライバーで変換され、次に結果が(指定されている場合) ident
で処理され、最後に(指定されて適用可能な場合) text
で処理されます。
チェックアウトのコードの流れでは、ブロブコンテンツは最初に text
で変換され、次に ident
で変換され、 filter
に送られます。
チェックイン/チェックアウト属性が異なるブランチをマージする
clean/smudge フィルターや text/eol/ident 属性の追加など、そのファイルの正規リポジトリ形式を変更する属性をファイルに追加した場合、属性が配置されていない場所で何かをマージすると、通常、マージの競合が発生します。
これらの不必要なマージの競合を防ぐために、Gitは、 merge.renormalize
構成変数を設定することにより、3方向マージを解決するときに、ファイルの3つのステージすべての仮想チェックアウトとチェックインを実行するように指示できます。これにより、チェックイン変換によって引き起こされた変更によって、変換されたファイルが変換されていないファイルとマージされるときに、誤ったマージの競合が発生するのを防ぐことができます。
「smudge→clean」の結果がすでに汚されている(smudged)ファイルでも「clean」と同じ出力になる限り、この戦略はすべてのフィルター関連の競合を自動的に解決します。このように機能しないフィルターは、手動で解決する必要がある追加のマージ競合を引き起こす可能性があります。
Generating diff text
diff
属性 diff
は、Gitが特定のファイルのdiffを生成する方法に影響を与えます。パスのテキストパッチを生成するか、パスをバイナリファイルとして扱うかをGitに指示できます。 また、ハンクヘッダーの @@ -k,l +n,m @@
行に表示される行に影響を与えたり、外部コマンドを使用して差分を生成するようにGitに指示したり、差分を生成する前にバイナリファイルをテキスト形式に変換するようにGitに依頼したりすることもできます。
- 設定(set)
-
diff
属性が設定されているパスは、NULなどのテキストファイルには通常表示されないバイト値が含まれている場合でも、テキストとして扱われます。 - 設定解除(unset)
-
diff
属性が設定されていないパスは、Binary files differ
(バイナリファイル差分) (または、バイナリパッチが有効になっている場合、バイナリパッチ) を生成します。 - 未指定(unspecified)
-
diff
属性が指定されていないパスは、最初にその内容が検査され、テキストのように見え、 core.bigFileThreshold よりも小さい場合は、テキストとして扱われます。さもなければBinary files differ
(バイナリファイル差分) が生成されます。 - String(文字列値)
-
指定されたdiffドライバーを使用してdiffが表示されます。以下のセクションで説明するように、各ドライバーは1つ以上のオプションを指定できます。diffドライバー「foo」のオプションは、Git構成ファイルの「diff.foo」セクションの構成変数によって定義されます。
外部diffドライバーの定義
diffドライバの定義は gitattributes
ファイルではなく gitconfig
で行われるため、厳密に言えば、このマニュアルページはそれについて話すのには間違った場所はありますが…
外部diffドライバー jcdiff
を定義するには、以下のように $GIT_DIR/config
ファイル(または $HOME/.gitconfig
ファイル)にセクションを追加します:
[diff "jcdiff"]
command = j-c-diff
Git は diff
属性が jcdiff
に設定されているパスの diff を表示する必要がある場合、上記の設定で指定したコマンド、つまり j-c-diff
を 7 つのパラメータで、 GIT_EXTERNAL_DIFF
プログラムが呼ばれるのと同じように呼び出します。 詳しくは git(1) を参照してください。
内部diffアルゴリズムの設定
diff アルゴリズムは diff.algorithm
設定キーを介して設定できますが、場合によってはパスごとに diff アルゴリズムを設定すると便利な場合があります。たとえば、毎回コマンド・ラインから diff アルゴリズムを渡すことなく、 .json
ファイルには minimal
diff アルゴリズムを使用し、 .c ファイルには histogram
diff アルゴリズムを使用するようなことができます。
最初に、 .gitattributes
で、パスに diff
属性を割り当てます。
*.json diff=<name>
次に、 diff.<name>.algorithm
構成を定義して、 diff アルゴリズムを、 myers
または patience
または minimal
または histogram
から選んで指定します。
[diff "<name>"]
algorithm = histogram
この diff アルゴリズムは、 git-diff(1) や git-show(1) などのユーザー向けの diff 出力に適用され、 --stat
出力にも使用されます。 マージ機構は、このメソッドで設定された diff アルゴリズムを使用しません。
Note
|
diff.<name>.command が diff=<name> 属性を持つパスに定義されている場合、外部 diff ドライバーとして実行され(上記参照)、そして、 diff.<name>.algorithm を追加してもそのアルゴリズムは外部 diff ドライバーに渡されないため、効果ありません。 |
Defining a custom hunk-header
テキストdiff出力の変更の各グループ(ハンク(hunk)と呼ばれます)には、以下の形式の行が接頭辞として付けられます:
@@ -k,l +n,m @@ TEXT
これはハンクヘッダー(hunk header)と呼ばれます。 "TEXT" の部分は、デフォルトでは、アルファベットまたは、アンダースコア(_
)または、ドル記号($
)で始まる行です。 これは、GNU diff -p
出力が使用するものとマッチします。ただし、このデフォルトの選択は一部のコンテンツには適していないため、カスタマイズされたパターンを使用して選択を行うことができます。
最初に、 .gitattributesで、パスに diff
属性を割り当てます。
*.tex diff=tex
次に、 diff.tex.xfuncname
構成を定義して、ハンクヘッダー "TEXT" として表示する行にマッチする正規表現を指定します。以下のように、 $GIT_DIR/config
ファイル(または $HOME/.gitconfig
ファイル)にセクションを追加します:
[diff "tex"]
xfuncname = "^(\\\\(sub)*section\\{.*)$"
注意: 単一レベルのバックスラッシュは構成ファイルパーサーによって使用されるため、バックスラッシュを2重にする必要があります。 上記のパターンは、バックスラッシュで始まり、行の終わりまで、 sub
、 section
、 {
の順に0回以上出現する行を選択します。
これを簡単にするための組み込みパターンがいくつかあり、 tex
はその1つであるため、構成ファイルに上記を書き込む必要はありません(これは、 .gitattributes
を介して属性メカニズムで有効にする必要があります)。以下の組み込みパターンを使用できます:
-
ada
はAda言語のソースコードに適しています。 -
bash
はBourne-Againシェル言語(bash)のソースコードに適しています。POSIXシェル関数定義のスーパーセットをカバーしています。 -
bibtex
はBibTeXでコード化されたリファレンスを持つファイルに適しています。 -
cpp
はC言語とC++言語のソースコードに適しています。 -
csharp
はC#言語のソースコードに適しています。 -
css
はCSS(cascading style sheets)に適しています。 -
dts
は devicetree (DTS) ファイルに適しています。 -
elixir
はElixir言語のソースコードに適しています。 -
fortran
はFORTRAN言語のソースコードに適しています。 -
fountain
はFountain文書に適しています。 -
golang
はGo言語のソースコードに適しています。 -
html
は HTML/XHTML 文書に適しています。 -
java
はJava言語のソースコードに適しています。 -
kotlin
はKotlin言語のソースコードに適しています。 -
markdown
はMarkdown文書に適しています。 -
matlab
はMATLABとOctave言語のソースコードに適しています。 -
objc
はObjective-C言語のソースコードに適しています。 -
pascal
は Pascal/Delphi 言語のソースコードに適しています。 -
perl
はPerl言語のソースコードに適しています。 -
php
はPHP言語のソースコードに適しています。 -
python
はPython言語のソースコードに適しています。 -
ruby
はRuby言語のソースコードに適しています。 -
rust
はRust言語のソースコードに適しています。 -
scheme
はScheme言語のソースコードに適しています。 -
tex
はLaTeX文書のソースコードに適しています。
Customizing word diff
diff.*.wordRegex
構成変数で適切な正規表現を指定することにより、 git diff --word-diff
が単語を1行に分割するために使用するルールをカスタマイズできます。たとえば、TeXでは、バックスラッシュとそれに続く一連の文字がコマンドを形成しますが、そのようなコマンドのいくつかは、空白を介さずに一緒に実行できます。それらを分離するには、以下のように $GIT_DIR/config
ファイル(または $HOME/.gitconfig
ファイル)で正規表現を使用します:
[diff "tex"]
wordRegex = "\\\\[a-zA-Z]+|[{}]|\\\\.|[^\\{}[:space:]]+"
前のセクションにリストされているすべての言語には組み込みのパターンが用意されています。
バイナリファイルのテキスト差分の取得
一部のバイナリファイルのテキスト変換バージョンの差分を確認することが望ましい場合があります。たとえば、ワードプロセッサ文書をASCIIテキスト表現に変換し、テキストの差分を表示することができます。この変換によって一部の情報が失われますが、結果のdiffは人間が見るのに役立ちます(ただし、直接適用(apply)することはできません)。
textconv
configオプションは、そのような変換を実行するためのプログラムを定義するために使用されます。プログラムは、変換するファイルの名前である単一の引数を取り、結果のテキストをstdoutに生成する必要があります。
たとえば、バイナリ情報の代わりにファイルのexif情報の差分を表示するには(exifツールがインストールされていると仮定して)、以下のセクションを $GIT_DIR/config
ファイル(または `$HOME/.gitconfig ファイル)に追加します:
[diff "jpg"]
textconv = exif
Note
|
テキスト変換は通常、一方向の変換です。この例では、実際の画像コンテンツを失い、テキストデータのみに焦点を当てています。これは、textconvによって生成されたdiffが適用(apply)に適していないことを意味します。このため、テキスト変換を実行するのは、 git diff と git log ファミリーのコマンド(つまり、log、whatchanged、show)のみです。 git format-patch はこの出力を生成しません。バイナリファイルのテキスト変換された差分を誰かに送信したい場合(たとえば、行った変更をすばやく伝達するため)、それを別個に生成し、送信する通常のバイナリ差分に加えてコメントとして送信する必要があります。 |
特に git log -p
を使用して大量のテキスト変換を行う場合、テキスト変換が遅くなる可能性があるため、Gitは出力をキャッシュし、将来の差分で使用するメカニズムを提供します。 キャッシュを有効にするには、diffドライバーの構成で「cachetextconv」変数を設定します。 例えば:
[diff "jpg"]
textconv = exif
cachetextconv = true
これにより、各ブロブで「exif」を実行した結果が無期限にキャッシュされます。diffドライバーのtextconv構成変数を変更すると、Gitはキャッシュエントリを自動的に無効にし、textconvフィルターを再実行します。キャッシュを手動で無効にしたい場合(たとえば、「exif」のバージョンが更新され、より良い出力が生成されようになった等)、 git update-ref -d refs/notes/textconv/jpg
を使用してキャッシュを手動で削除できます( ここで、「jpg」は上記の例のように、diffドライバーの名前です)。
textconvと外部diffの選択
あなたがリポジトリ内のバイナリまたは特別にフォーマットされたブロブの違いを表示したい場合は、外部のdiffコマンドを使用するか、textconvを使用してそれらを差分可能(diff-able)なテキストフォーマットに変換するかを選択できます。どちらの方法を選択するかは、状況に完全に依存します。
外部diffコマンドを使用する利点は、柔軟性です。行指向の変更を見つける必要はありません。また、出力が統一されたdiff(unified diff)に似ている必要もありません。あなたはあなたのデータ形式に最も適した方法で変更を自由に見つけて報告できます。
それと比較すると、textconvははるかに制限的です。データを行指向のテキスト形式に変換すると、Gitは通常のdiffツールを使用して出力を生成します。この方法を選択することにはいくつかの利点があります:
-
容易に使えます。多くの場合、独自の差分を実行するよりも、バイナリからテキストへの変換を作成する方がはるかに簡単です。多くの場合、既存のプログラム(つまり exif や odt2txt)をtextconvフィルターとして使用できます。
-
Gitのdiff機能。変換ステップのみを自分で実行することで、カラー化、単語diff、マージ用の複合diffなど、Gitのdiff機能の多くを引き続き利用できます。
-
キャッシュ機能。 textconvキャッシングは、
git log -p
を実行してトリガーするような、繰り返されるdiffを高速化できます。
ファイルをバイナリとしてマークする
Gitは通常、コンテンツの先頭を調べることで、ブロブにテキストデータとバイナリデータのどちらが含まれているかを正しく推測します。ただし、ブロブにファイルの後半にバイナリデータが含まれている、またはコンテンツが技術的にはテキスト文字で構成されているものの、人間の読者には不明瞭であるために、あなたは、その推測を上書きしたい場合があります。たとえば、多くのポストスクリプトファイルにはASCII文字しか含まれていません(つまりテキストデータです)が、ノイズが多く意味のないdiffが生成されます。
ファイルをバイナリとしてマークする最も簡単な方法は、 .gitattributes
ファイルでdiff属性を設定解除(unset)することです。
*.ps -diff
これにより、Gitは通常の差分ではなく Binary files differ
(バイナリファイルの差分)(またはバイナリパッチが有効になっている場合はバイナリパッチ)を生成します。
しかしながら、他のdiffドライバー属性を指定することもできます。 たとえば、 textconv
を使用してポストスクリプトファイルをASCII表現に変換し、人間が表示できるようにしたい場合があるけども、それ以外の場合はバイナリファイルとして扱いたいとします。 -diff
属性 と diff=ps
属性の両方を指定することはできません。 解決策は、 diff.*.binary
構成オプションを使用することです:
[diff "ps"]
textconv = ps2ascii
binary = true
Performing a three-way merge
merge
属性 merge
は、 git merge
中にファイルレベルのマージが必要な場合にファイルの3つのバージョンをマージする方法や、 gitr evert
や git cherry-pick
などの他のコマンドに、影響します。
- 設定(set)
-
組み込みの3方向マージドライバーは、
RCS
スイートのmerge
コマンドと同様の方法でコンテンツをマージするために使用されます。これは通常のテキストファイルに適しています。 - 設定解除(unset)
-
現在のブランチのバージョンを暫定的なマージ結果として取得し、マージに競合があることを宣言します。これは、明確に定義されたマージセマンティクスを持たないバイナリファイルに適しています。
- 未指定(unspecified)
-
デフォルトでは、これは
merge
属性が設定されている場合と同じ組み込みの3方向マージドライバーを使用します。 ただし、merge.default
構成変数は、merge
属性未指定(unspecified)のパスで使用される別のマージドライバーに名前を付けることができます。 - String(文字列値)
-
3方向マージは、指定のカスタムマージドライバーを使用して実行されます。組み込みの3方向マージドライバーは、「text」ドライバーを要求することで明示的に指定できます。 現在のブランチを取得する組み込みドライバーは、「binary」を要求することで指定できます。
Built-in merge drivers
merge
属性を介して要求できる、いくつかの組み込みの低レベルのマージドライバーが定義されています。
- text
-
テキストファイルの通常の3方向ファイルレベルのマージ。 競合する領域は、競合マーカー
<<<<<<<
と=======
と>>>>>>>
でマークされます。ブランチのバージョンは=======
マーカーの前に表示され、マージされたブランチのバージョンは=======
マーカーの後に表示されます。 - binary
-
ブランチのバージョンを作業ツリーに保持しますが、ユーザーが整理できるようにパスを競合状態のままにします。
- union
-
テキストファイルに対して3方向のファイルレベルのマージを実行しますが、競合マーカーを残すのではなく、両方のバージョンから行を取得します。これにより、結果のファイルに追加された行がランダムな順序で残る傾向があり、ユーザーは結果を確認すべきです。影響を理解していない場合は、これを使用してはいけません。
Defining a custom merge driver
マージドライバの定義は、 gitattributes
ファイルではなく .git/config
ファイルで行われるため、厳密に言えば、このマニュアルページはそれについて話すのに間違った場所ではありますが…
カスタムマージドライバー filfre
を定義するには、以下のように $GIT_DIR/config
ファイル(または $HOME/.gitconfig
ファイル)にセクションを追加します:
[merge "filfre"]
name = feel-free merge driver
driver = filfre %O %A %B %L %P
recursive = binary
merge.*.name
変数は、ドライバーに人間が読める名前を付けます。
merge.*.driver
変数の値は、祖先のバージョン(%O
)と、現在のバージョン(%A
)と、他のブランチのバージョン(%B
)をマージするために実行するコマンドを作成するために使用されます。これらの3つのトークンは、コマンドラインの構築時にこれらのバージョンの内容を保持する一時ファイルの名前に置き換えられます。さらに、 %L
は競合マーカーのサイズに置き換えられます(以下を参照)。
マージドライバーは、マージの結果を %A
という名前のファイルに上書きして残し、それらを正常にマージできた場合はゼロステータスで終了し、競合があった場合は非ゼロで終了することが期待されます。ドライバーがクラッシュした場合(SEGV によって kill された場合など)、ドライバーは 128 を超えるゼロ以外のステータスで終了(exit)すると期待され、かつ、そのような場合、マージは失敗(failure)します(これは競合の発生とは異なります)。
merge.*.recursive
変数は、複数の祖先が存在する場合に、共通の祖先間の内部マージのためにマージドライバーが呼び出されるときに使用する他のマージドライバーを指定します。指定しない場合、ドライバー自体が内部マージと最終マージの両方に使用されます。
マージドライバーは、プレースホルダー %P
を介して、マージされた結果が格納されるパス名を知ります。
conflict-marker-size
この属性は、競合するマージ中に作業ツリーファイルに残る競合マーカーの長さを制御します。値を正の整数に設定するだけで、意味のある効果があります。
たとえば、 ファイル Documentation/git-merge.txt
の結果をマージすると競合するときに、.gitattributes
で(通常の7文字の長さではなく)はるかに長い競合マーカーを残すようにマージ機構に指示できます。
Documentation/git-merge.txt conflict-marker-size=32
Checking whitespace errors
whitespace
`core.whitespace` 設定変数を使用すると、プロジェクト内のすべてのパスに対して `diff` と `apply` が空白エラー(whitespace errors)をどうみなすかを定義します(linkgit:git-config[1] を参照)。この属性では、あなたはパスごとに細かく制御できます。
- 設定(set)
-
Gitでチェックできる全てのタイプの潜在的な空白エラーを通知します。タブ幅は
core.whitespace
構成変数の値から取得されます。 - 設定解除(unset)
-
何もエラーとして通知しません。
- 未指定(unspecified)
-
core.whitespace
構成変数の値を使用して、エラーとして通知する内容を決定します。 - String(文字列値)
-
core.whitespace
構成変数と同じ形式で、通知すべき一般的な空白の問題(whitespace problems)の、コンマ区切りリストを指定します。
Creating an archive
export-ignore
属性 export-ignore
を持つファイルとディレクトリはアーカイブファイルに追加されません。
export-subst
属性 export-subst
がファイルに設定されている場合、Gitはこのファイルをアーカイブに追加するときにいくつかのプレースホルダーを展開します。展開は、コミットIDの可用性に依存します。たとえば git-archive(1) にコミットやタグの代わりにツリーが与えられている場合、置換は行われません。プレースホルダーは、 git-log(1) のオプション --pretty=format:
のプレースホルダーと同じですが、ファイル内で $Format:PLACEHOLDERS$
のようにラップする必要がある点が異なります。 例えば、 文字列 $Format:%H$
は、コミットハッシュに置き換えられます。ただし、DoS攻撃(denial-of-service attacks)を回避するために、アーカイブごとに1つの %(describe)
プレースホルダーのみが展開されます。
Packing objects
delta
属性 delta
がfalseに設定されているパスのブロブに対して、デルタ圧縮は試行されません。
Viewing files in GUI tools
encoding
この属性の値は、関連するファイルの内容を表示するためにGUIツール(gitk(1) や git-gui(1) など)で使用される文字エンコードを指定します。注意: パフォーマンス上の考慮事項により、 gitk(1) は、オプションでファイルごとのエンコーディングを手動で有効にしない限り、この属性を使用しないことに注意してください。
この属性が設定されていないか、値が無効な場合は、代わりに gui.encoding
構成変数の値が使用されます(git-config(1) を参照)。
USING MACRO ATTRIBUTES
追跡中のバイナリファイルに、行末変換を適用したり、テキストの差分を作成したりする必要はありません。あなたは、たとえば以下のように指定する必要があります。
*.jpg -text -diff
しかし、多くの属性がある場合、これはめんどくさいです。マクロ属性を使用すると、あなたは設定時に他の多くの属性を同時に設定または設定解除する属性を定義できます。システムは、組み込みのマクロ属性 binary
を認識します:
*.jpg binary
「binary」属性を設定すると、上記のように「text」属性と「diff」属性の設定も解除されます。マクロ属性は「set」のみであることに注意してください。ただし、1つを設定すると、他の属性をsetまたはunsetしたり、他の属性を「Unspecified」状態に戻したりする事があります。
DEFINING MACRO ATTRIBUTES
カスタムマクロ属性は、最上位のgitattributesファイル($GIT_DIR/info/attributes
または、作業ツリーの最上位にある ` .gitattributes` ファイルまたは、グローバルgitattributesファイルまたは、システム全体のgitattributesファイル)でのみ定義でき、作業ツリーサブディレクトリの .gitattributes
ファイルでは定義できません。 組み込みのマクロ属性「binary」は、以下のものと同等です:
[attr]binary -diff -merge -text
NOTES
作業ツリーの .gitattributes
ファイルにアクセスするとき、Gitはシンボリックリンクをたどりません。 これにより、ファイルシステムからではなく、インデックスまたはツリーからファイルにアクセスする場合の動作の一貫性が保たれます。
EXAMPLES
これらの以下の3つの gitattributes
ファイルがある場合:
(in $GIT_DIR/info/attributes)
a* foo !bar -baz
(in .gitattributes)
abc foo bar baz
(in t/.gitattributes)
ab* merge=filfre
abc -foo -bar
*.c frotz
パス t/abc
に与えられる属性は、以下のように計算されます:
-
(問題のパスと同じディレクトリにある)
t/.gitattributes
を調べることにより、Gitは最初の行が一致することを検出します。merge
属性が設定されます。 また、2行目が一致し、属性foo
と `bar`が設定解除(unseet)されていることもわかります。 -
次に (親ディレクトリにある)
.gitattributes
を調べ、最初の行がマッチすることを確認します。しかし、t/.gitattributes
ファイルでは、このパスに対してmerge
やfoo
やbar
属性をどのように与えるべきかを既に決めているので、foo
とbar
は設定解除(unset)のままにしています。属性baz
がsetされます。 -
最後に、
$GIT_DIR/info/attributes
を調べます。このファイルは、ツリー内の設定を上書きするために使用されます。最初の行がマッチしてfoo
がsetされ、bar
が指定解除(unset)の状態に戻され、baz
が設定解除(unset)されます。
その結果、 t/abc
への属性の割り当ては以下のようになります:
foo set to true
bar unspecified
baz set to false
merge set to string value "filfre"
frotz unspecified
SEE ALSO
GIT
Part of the git(1) suite