セットアップと設定
プロジェクトの取得と作成
基本的なスナップショット
ブランチとマージ
プロジェクトの共有と更新
検査と比較
パッチ適用
デバッグ
メール
外部システム
サーバー管理
-
2.49.0
2025-03-14
- 2.46.1 → 2.48.1 変更なし
-
2.46.0
2024-07-29
- 2.44.1 → 2.45.3 変更なし
-
2.44.0
2024-02-23
- 2.43.1 → 2.43.6 変更なし
-
2.43.0
2023-11-20
- 2.42.1 → 2.42.4 変更なし
-
2.42.0
2023-08-21
- 2.41.1 → 2.41.3 変更なし
-
2.41.0
2023-06-01
- 2.40.1 → 2.40.4 変更なし
-
2.40.0
2023-03-12
- 2.36.1 → 2.39.5 変更なし
-
2.36.0
2022-04-18
- 2.32.1 → 2.35.8 変更なし
-
2.32.0
2021-06-06
- 2.30.1 → 2.31.8 変更なし
-
2.30.0
2020-12-27
- 2.27.1 → 2.29.3 変更なし
-
2.27.0
2020-06-01
- 2.25.1 → 2.26.3 変更なし
-
2.25.0
2020-01-13
- 2.24.1 → 2.24.4 変更なし
-
2.24.0
2019-11-04
- 2.23.1 → 2.23.4 変更なし
-
2.23.0
2019-08-16
- 2.22.1 → 2.22.5 変更なし
-
2.22.0
2019-06-07
- 2.21.1 → 2.21.4 変更なし
-
2.21.0
2019-02-24
- 2.19.3 → 2.20.5 変更なし
-
2.19.2
2018-11-21
- 2.18.1 → 2.19.1 変更なし
-
2.18.0
2018-06-21
- 2.17.1 → 2.17.6 変更なし
-
2.17.0
2018-04-02
-
2.16.6
2019-12-06
- 2.15.4 変更なし
-
2.14.6
2019-12-06
-
2.13.7
2018-05-22
- 2.12.5 変更なし
-
2.11.4
2017-09-22
-
2.10.5
2017-09-22
-
2.9.5
2017-07-30
- 2.7.6 → 2.8.6 変更なし
-
2.6.7
2017-05-05
-
2.5.6
2017-05-05
-
2.4.12
2017-05-05
- 2.3.10 変更なし
-
2.2.3
2015-09-04
- 2.1.4 変更なし
-
2.0.5
2014-12-17
説明
gitattributes
ファイルは、パス名に属性
を与える単純なテキストファイルです。
gitattributes
ファイルの各行は、次の形式です。
pattern attr1 attr2 ...
つまり、パターンに続いて属性リストが空白で区切られて並びます。先頭と末尾の空白は無視されます。# で始まる行は無視されます。二重引用符で始まるパターンはC言語スタイルで引用されます。パターンが問題のパスに一致すると、行にリストされた属性がパスに与えられます。
各属性は、特定のパスに対して以下のいずれかの状態になります。
- 設定済み (Set)
-
パスは特殊値「true」の属性を持ちます。これは、属性リストに属性の名前のみを記述することで指定されます。
- 未設定 (Unset)
-
パスは特殊値「false」の属性を持ちます。これは、属性リストで属性の名前の前にダッシュ
-
を付けて記述することで指定されます。 - 値に設定済み (Set to a value)
-
パスは指定された文字列値の属性を持ちます。これは、属性リストで属性の名前の後に等号
=
とその値を付けて記述することで指定されます。 - 未指定 (Unspecified)
-
どのパターンもパスに一致せず、パスが属性を持つか持たないかを何も示さない場合、そのパスの属性は未指定であると言われます。
複数のパターンがパスに一致する場合、後続の行が以前の行を上書きします。この上書きは属性ごとに行われます。
パターンがパスに一致する規則は、.gitignore
ファイル (参照: gitignore[5]) と同じですが、いくつかの例外があります。
-
否定パターンは禁止されています。
-
ディレクトリに一致するパターンは、そのディレクトリ内のパスに再帰的に一致しません(したがって、属性ファイルで末尾のスラッシュ
path/
構文を使用するのは無意味です。代わりにpath/**
を使用してください)。
パスに割り当てられる属性を決定する際、Gitは$GIT_DIR/info/attributes
ファイル(最高の優先順位を持つ)、問題のパスと同じディレクトリにある.gitattributes
ファイル、およびワークツリーの最上位までの親ディレクトリ(.gitattributes
を含むディレクトリが問題のパスから遠いほど優先順位は低くなります)を参照します。最後にグローバルファイルとシステム全体のファイルが考慮されます(これらは最低の優先順位を持ちます)。
ワークツリーから.gitattributes
ファイルが見つからない場合、インデックス内のパスが代替として使用されます。チェックアウトプロセス中は、インデックス内の.gitattributes
が使用され、その後、作業ツリー内のファイルが代替として使用されます。
単一のリポジトリのみに影響を与えたい場合(つまり、あるユーザーのワークフローに固有のファイルに属性を割り当てる場合)は、属性を$GIT_DIR/info/attributes
ファイルに配置する必要があります。バージョン管理され、他のリポジトリに配布されるべき属性(つまり、すべてのユーザーに関心のある属性)は、.gitattributes
ファイルに入れるべきです。単一ユーザーのすべてのリポジトリに影響を与えるべき属性は、core.attributesFile
設定オプション(git-config[1]を参照)で指定されたファイルに配置する必要があります。そのデフォルト値は$XDG_CONFIG_HOME/git/attributesです。$XDG_CONFIG_HOMEが設定されていないか空の場合、$HOME/.config/git/attributesが代わりに使用されます。システム上のすべてのユーザーに対する属性は、$(prefix)/etc/gitattributes
ファイルに配置する必要があります。
時として、パスの属性設定を未指定
状態に上書きする必要がある場合があります。これは、属性の名前の前に感嘆符!
を付けて記述することで可能です。
効果
Gitの特定の操作は、パスに特定の属性を割り当てることで影響を受けることがあります。現在、以下の操作が属性を認識します。
チェックアウトとチェックイン
これらの属性は、git switch、git checkout、git mergeなどのコマンドが実行される際に、リポジトリに保存された内容がどのようにワーキングツリーファイルにコピーされるかに影響します。また、git addおよびgit commitによってワーキングツリーで準備した内容をGitがリポジトリにどのように保存するかにも影響します。
text
この属性はパスをテキストファイルとしてマークし、行末変換を有効にします。一致するファイルがインデックスに追加されると、ファイルの行末はインデックスでLFに正規化されます。逆に、ファイルがインデックスから作業ディレクトリにコピーされると、eol
属性、Gitの設定、およびプラットフォームに応じて、行末がLFからCRLFに変換される場合があります(以下のeol
の説明を参照)。
- 設定済み (Set)
-
パスに
text
属性を設定すると、上述の通り、チェックインおよびチェックアウト時に行末変換が有効になります。ファイルがCRLF行末でGitに以前追加されていたとしても、ファイルがチェックインされるたびに行末はインデックスでLFに正規化されます。 - 未設定 (Unset)
-
パスの
text
属性を未設定にすると、チェックインまたはチェックアウト時にGitが行末変換を試みないように指示します。 - 文字列値 "auto" に設定済み (Set to string value "auto")
-
text
が「auto」に設定されている場合、Gitはファイルがテキストかバイナリかを自動で判断します。テキストファイルであり、CRLF行末でGitにまだ存在しないファイルの場合、上記のとおりチェックインおよびチェックアウト時に行末が変換されます。それ以外の場合、チェックインまたはチェックアウト時に変換は行われません。 - 未指定 (Unspecified)
-
text
属性が未指定の場合、Gitはcore.autocrlf
設定変数を使用して、ファイルを変換すべきかどうかを判断します。
その他の値は、Gitがtext
が未指定のままになっているかのように動作させます。
eol
この属性は、パスをチェックアウトする際に、ワーキングツリーで特定の行末スタイルを使用するようにマークします。これは、text
またはtext=auto
が設定されている場合にのみ効果があります(上記参照)が、eol
を指定すると、text
が未指定のままであった場合に自動的にtext
を設定します。
- 文字列値 "crlf" に設定済み (Set to string value "crlf")
-
この設定は、ファイルがチェックアウトされる際に、ワーキングディレクトリ内のファイルの行末をCRLFに変換します。
- 文字列値 "lf" に設定済み (Set to string value "lf")
-
この設定は、ファイルがチェックアウトされる際に、ワーキングディレクトリの行末をインデックス内と同じにします。
- 未指定 (Unspecified)
-
ファイルの
eol
属性が未指定の場合、ワーキングディレクトリ内の行末はcore.autocrlf
またはcore.eol
設定変数によって決定されます(git-config[1]のそれらのオプションの定義を参照)。text
が設定されているが、これらの変数のどちらも設定されていない場合、Windowsではデフォルトでeol=crlf
、その他のすべてのプラットフォームではeol=lf
となります。
行末変換
Gitは通常、ファイルの内容をそのままにしますが、リポジトリで行末をLFに正規化し、オプションでファイルをチェックアウトする際にCRLFに変換するように設定することができます。
使用しているリポジトリに関係なく、ワーキングディレクトリでCRLF行末にしたいだけなら、属性を使用せずに「core.autocrlf」設定変数を設定できます。
[core] autocrlf = true
これはテキストファイルの正規化を強制するものではありませんが、リポジトリに導入するテキストファイルが追加時に行末がLFに正規化されること、およびリポジトリにすでに正規化されているファイルが正規化されたままであることを保証します。
貢献者がリポジトリに導入するテキストファイルの行末が正規化されることを確実にしたい場合は、すべてのファイルに対して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
注
|
text=auto 変換が中央リポジトリへのプッシュとプルを使用するクロスプラットフォームプロジェクトで有効になっている場合、CRLFを含むテキストファイルは正規化されるべきです。 |
クリーンなワーキングディレクトリから
$ echo "* text=auto" >.gitattributes $ git add --renormalize . $ git status # Show files that will be normalized $ 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またはそのスーパーセット(例:UTF-8、ISO-8859-1など)でエンコードされたファイルをテキストファイルとして認識します。特定の他のエンコーディング(例:UTF-16)でエンコードされたファイルはバイナリとして解釈され、結果として組み込みのGitテキスト処理ツール(例:git diff)やほとんどのGitウェブフロントエンドは、デフォルトではこれらのファイルの内容を視覚化しません。
このような場合、working-tree-encoding
属性を使って、ワーキングディレクトリ内のファイルのエンコーディングをGitに伝えることができます。この属性を持つファイルがGitに追加されると、Gitは指定されたエンコーディングからUTF-8にコンテンツを再エンコードします。最後に、GitはUTF-8でエンコードされたコンテンツを内部データ構造(「インデックス」と呼ばれます)に保存します。チェックアウト時には、コンテンツは指定されたエンコーディングに再エンコードされます。
working-tree-encoding
属性の使用には、いくつかの落とし穴があることに注意してください。
-
代替のGit実装(例:JGitやlibgit2)や古いGitバージョン(2018年3月時点)は、
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
BOMなしでUTF-16リトルエンディアンでエンコードされた*.ps1ファイルがあり、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はチェックアウト時にBLOBオブジェクト内の$Id$
を$Id:
に置き換え、その後40文字の16進数BLOBオブジェクト名が続き、最後にドル記号$
が続きます。作業ツリーファイル内で$Id:
で始まり$
で終わるバイトシーケンスは、チェックイン時に$Id$
に置き換えられます。
filter
filter
属性は、設定で指定されたフィルタードライバーの名前である文字列値に設定できます。
フィルタードライバーはclean
コマンドとsmudge
コマンドから成り、どちらか一方を未指定にすることができます。チェックアウト時、smudge
コマンドが指定されている場合、そのコマンドは標準入力からBLOBオブジェクトを受け取り、その標準出力がワークツリーファイルの更新に使用されます。同様に、clean
コマンドはチェックイン時にワークツリーファイルの内容を変換するために使用されます。デフォルトでは、これらのコマンドは単一のBLOBのみを処理し、終了します。もし、clean
および/またはsmudge
フィルターの代わりに長時間実行されるprocess
フィルターが使用される場合、Gitは単一のGitコマンドの全ライフサイクル(例:git add --all
)の間、単一のフィルターコマンド呼び出しで全てのBLOBを処理できます。もし長時間実行されるprocess
フィルターが設定されている場合、それは常に設定された単一BLOBフィルターよりも優先されます。process
フィルターとの通信に使用されるプロトコルの説明については、以下のセクションを参照してください。
コンテンツフィルタリングの用途の一つは、コンテンツをプラットフォーム、ファイルシステム、およびユーザーにとってより便利な形式に調整することです。この操作モードでは、「より便利」というキーワードが重要であり、「使用不能なものを使用可能にする」ことではありません。言い換えれば、意図としては、誰かがフィルタードライバーの定義を解除したり、適切なフィルタープログラムを持っていなかったりしても、プロジェクトは依然として使用可能であるべきだということです。
コンテンツフィルタリングのもう一つの用途は、リポジトリで直接使用できないコンテンツ(例:Gitの外部に保存された実際のコンテンツを参照するUUID、または暗号化されたコンテンツ)を保存し、チェックアウト時に使用可能な形式に変換することです(例:外部コンテンツのダウンロード、または暗号化されたコンテンツの復号化)。
これら2つのフィルターは異なる動作をし、デフォルトでは前者の、内容をより便利な形式に調整するフィルターとみなされます。設定にフィルタードライバーの定義がない場合、またはゼロ以外のステータスで終了するフィルタードライバーは、エラーではなく、フィルターを何もしないパススルーにします。
フィルターがそれ自体では使用できないコンテンツを使用可能なコンテンツに変えることを、filter.<driver>.required
設定変数をtrue
に設定することで宣言できます。
注意:クリーンフィルターを変更するたびに、リポジトリを再正規化する必要があります:$ 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」と同等であるべきです)。以下のマージに関するセクションを参照してください。
「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コマンドはディスク上のファイルにアクセスしようとせず、標準入力に提供されたコンテンツのフィルターとしてのみ機能すべきです。
長時間実行フィルタープロセス
フィルターコマンド(文字列値)がfilter.<driver>.process
を介して定義されている場合、Gitは単一のGitコマンドの全ライフサイクルにわたって、単一のフィルター呼び出しですべてのBLOBを処理できます。これは、長時間実行プロセスプロトコル(Documentation/technical/long-running-process-protocol.adocに記載)を使用することで実現されます。
Gitはクリーニングまたはスマッジが必要な最初のファイルに遭遇すると、フィルターを開始し、ハンドシェイクを実行します。ハンドシェイクでGitが送信するウェルカムメッセージは「git-filter-client」であり、バージョン2のみがサポートされており、サポートされる機能は「clean」、「smudge」、「delay」です。
その後、Gitはフラッシュパケットで終了する「キー=値」のペアのリストを送信します。このリストには、少なくともフィルターコマンド(サポートされる機能に基づく)と、リポジトリのルートに対するフィルター対象ファイルのパス名が含まれます。フラッシュパケットの直後、Gitは0個以上のpkt-lineパケットで分割されたコンテンツと、コンテンツを終了させるためのフラッシュパケットを送信します。フィルターはコンテンツと最終的なフラッシュパケットを受信する前に、いかなる応答も送信してはならないことに注意してください。また、「キー=値」ペアの「値」は「=」文字を含むことができますが、キーはこの文字を絶対に含みません。
packet: git> command=smudge packet: git> pathname=path/testfile.dat packet: git> 0000 packet: git> CONTENT packet: git> 0000
フィルターは、フラッシュパケットで終了する「キー=値」のペアのリストで応答することが期待されます。フィルターが問題を経験しない場合、リストには「成功」ステータスが含まれている必要があります。これらのパケットの直後、フィルターは0個以上のpkt-lineパケットでコンテンツを送信し、最後にフラッシュパケットを送信することが期待されます。最後に、フラッシュパケットで終了する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!
結果のコンテンツが空の場合、フィルターは「成功」ステータスとフラッシュパケットで応答し、空のコンテンツを通知することが期待されます。
packet: git< status=success packet: git< 0000 packet: git< 0000 # empty content! packet: git< 0000 # empty list, keep "status=success" unchanged!
フィルターがコンテンツを処理できない、または処理したくない場合は、「エラー」ステータスで応答することが期待されます。
packet: git< status=error packet: git< 0000
処理中にフィルターがエラーを経験した場合、コンテンツが(部分的または完全に)送信された後にステータス「エラー」を送信できます。
packet: git< status=success packet: git< 0000 packet: git< HALF_WRITTEN_ERRONEOUS_CONTENT packet: git< 0000 packet: git< status=error packet: git< 0000
フィルターがコンテンツ、およびGitプロセスのライフタイムにおける将来のコンテンツを処理できない、または処理したくない場合、プロトコルの任意の時点で「中止」ステータスで応答することが期待されます。
packet: git< status=abort packet: git< 0000
Gitは、「error」/「abort」ステータスが設定されている場合でも、フィルタープロセスを停止したり再起動したりしません。ただし、Gitはfilter.<driver>.required
フラグに従って終了コードを設定し、filter.<driver>.clean
/ filter.<driver>.smudge
メカニズムの動作を模倣します。
通信中にフィルターが終了したり、プロトコルに従わなかったりした場合、Gitはフィルタープロセスを停止し、次に処理する必要があるファイルで再起動します。filter.<driver>.required
フラグによっては、Gitはそれをエラーと解釈します。
遅延
フィルターが「delay」機能をサポートしている場合、Gitはフィルターコマンドとパス名の後に「can-delay」フラグを送信できます。このフラグは、フィルターが現在のBLOBのフィルタリングを遅延できる(例:ネットワーク遅延を補償するため)ことを示し、コンテンツなしで「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がこのコマンドを送信した場合、フィルターは以前に遅延され、現在利用可能になっているBLOBを表すパス名のリストを返すことが期待されます。リストはフラッシュパケットで終了し、それに続く「成功」ステータスもフラッシュパケットで終了しなければなりません。遅延されたパスのBLOBがまだ利用可能でない場合、フィルターは少なくとも1つのBLOBが利用可能になるまで応答をブロックすることが期待されます。フィルターは空のリストを送信することで、遅延されたBLOBがもうないとGitに伝えることができます。フィルターが空のリストで応答するとすぐに、Gitは問い合わせを停止します。この時点でGitが受信していないすべてのBLOBは不足していると見なされ、エラーになります。
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がパス名を受け取った後、対応するBLOBを再度要求します。これらの要求にはパス名と空のコンテンツセクションが含まれます。フィルターは上記で説明した通常の方法でsmudgedされたコンテンツで応答することが期待されます。
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!
例
長時間実行フィルターのデモ実装は、Gitコアリポジトリのcontrib/long-running-filter/example.pl
にあります。独自の長時間実行フィルタープロセスを開発する場合、GIT_TRACE_PACKET
環境変数はデバッグに非常に役立ちます(git[1]を参照)。
既存のfilter.<driver>.clean
またはfilter.<driver>.smudge
コマンドをfilter.<driver>.process
と一緒に使用することはできません。これら2つは後者とは異なるプロセス間通信プロトコルを使用するためです。
チェックイン/チェックアウト属性間の相互作用
チェックインのコードパスでは、ワークツリーファイルはまずfilter
ドライバー(指定され、対応するドライバーが定義されていれば)で変換され、次にident
(指定されていれば)で処理され、最後にtext
(再度、指定され、適用可能であれば)で処理されます。
チェックアウトのコードパスでは、BLOBの内容はまずtext
で変換され、次にident
で変換されてfilter
に供給されます。
異なるチェックイン/チェックアウト属性を持つブランチのマージ
クリーン/スマッジフィルターやtext/eol/ident属性の追加など、ファイルの正規リポジトリ形式を変更する属性をファイルに追加した場合、属性が適用されていないものをマージすると、通常はマージ競合が発生します。
これらの不要なマージ競合を防ぐため、merge.renormalize
設定変数を設定することで、Gitに3-wayコンテンツマージが必要な各ファイルの3つのステージすべてについて仮想チェックアウトとチェックインを実行するように指示できます。これにより、変換されたファイルが未変換のファイルとマージされる際に、チェックイン変換によって引き起こされる偽のマージ競合が防止されます。
「smudge→clean」がすでにsmudgedされたファイルでも「clean」と同じ出力を生成する限り、この戦略はすべてのフィルター関連の競合を自動的に解決します。このように動作しないフィルターは、手動で解決する必要がある追加のマージ競合を引き起こす可能性があります。
差分テキストの生成
diff
属性diff
は、Gitが特定のファイルの差分を生成する方法に影響を与えます。パスに対してテキストパッチを生成するか、パスをバイナリファイルとして扱うかをGitに指示できます。また、Hunkヘッダー@@ -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
に設定されたパスの差分を表示する必要がある場合、上記の構成で指定されたコマンド、つまりj-c-diff
を、GIT_EXTERNAL_DIFF
プログラムが呼び出されるのと同様に7つのパラメータで呼び出します。詳細はgit[1]を参照してください。
プログラムが特定の変更を無視できる場合(git diff --ignore-space-change
と同様)、オプションtrustExitCode
もtrueに設定します。この場合、重要な変更が見つかった場合は終了コード1を、見つからない場合は0を返すことが期待されます。
内部diffアルゴリズムの設定
diffアルゴリズムはdiff.algorithm
設定キーを介して設定できますが、パスごとにdiffアルゴリズムを設定すると便利な場合があります。たとえば、.jsonファイルにはminimal
diffアルゴリズムを、.cファイルにはhistogram
を、といったように、毎回コマンドラインでアルゴリズムを渡す必要がありません。
まず、.gitattributes
で、パスのdiff
属性を割り当てます。
*.json diff=<name>
次に、"diff.<name>.algorithm" の設定を定義して、myers
, patience
, minimal
, histogram
の中から選択したdiffアルゴリズムを指定します。
[diff "<name>"] algorithm = histogram
このdiffアルゴリズムは、git-diff(1) や git-show(1) のようなユーザー向けdiff出力に適用され、--stat
出力にも使用されます。マージ機構はこの方法で設定されたdiffアルゴリズムを使用しません。
注
|
diff=<name> 属性を持つパスに対してdiff.<name>.command が定義されている場合、それは外部diffドライバーとして実行され(上記参照)、diff.<name>.algorithm を追加しても効果はありません。アルゴリズムが外部diffドライバーに渡されないためです。 |
カスタムhunkヘッダーの定義
テキスト差分出力の各変更グループ(「hunk」と呼ばれる)は、次の形式の行でプレフィックスされます。
@@ -k,l +n,m @@ TEXT
これはhunkヘッダーと呼ばれます。「TEXT」部分は、デフォルトではアルファベット、アンダースコア、またはドル記号で始まる行です。これはGNU diff -pの出力が使用するものと一致します。しかし、このデフォルトの選択は一部のコンテンツには適しておらず、カスタムパターンを使用して選択を行うことができます。
まず、.gitattributesで、パスのdiff
属性を割り当てます。
*.tex diff=tex
次に、「diff.tex.xfuncname」設定を定義し、hunkヘッダー「TEXT」として表示させたい行に一致する正規表現を指定します。$GIT_DIR/config
ファイル(または$HOME/.gitconfig
ファイル)に次のようなセクションを追加します。
[diff "tex"] xfuncname = "^(\\\\(sub)*section\\{.*)$"
注意:設定ファイルのパーサーによってバックスラッシュが1レベル消費されるため、バックスラッシュを2重にする必要があります。上記のパターンは、バックスラッシュで始まり、0個以上のsub
の後にsection
、さらにオープンブレースが続き、行末まで続く行を選択します。
これを容易にするためのいくつかの組み込みパターンがあり、tex
はそのうちの一つなので、設定ファイルに上記を記述する必要はありません(.gitattributes
を介して属性メカニズムでこれを有効にする必要はあります)。以下の組み込みパターンが利用可能です。
-
ada
Ada言語のソースコードに適しています。 -
bash
Bourne-Again SHell言語のソースコードに適しています。POSIXシェル関数定義のスーパーセットをカバーします。 -
bibtex
BibTeXでコード化された参照ファイルに適しています。 -
cpp
CおよびC++言語のソースコードに適しています。 -
csharp
C#言語のソースコードに適しています。 -
css
カスケーディングスタイルシートに適しています。 -
dts
デバイスツリー (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ドキュメントのソースコードに適しています。
ワード差分のカスタマイズ
git diff --word-diff
が1行内で単語を分割するために使用するルールは、"diff.*.wordRegex" 設定変数で適切な正規表現を指定することでカスタマイズできます。例えば、TeXではバックスラッシュの後に一連の文字が続くことでコマンドを形成しますが、いくつかのこのようなコマンドは間に空白を入れずに続けて実行できます。それらを分離するには、$GIT_DIR/config
ファイル(または$HOME/.gitconfig
ファイル)に次のような正規表現を使用します。
[diff "tex"] wordRegex = "\\\\[a-zA-Z]+|[{}]|\\\\.|[^\\{}[:space:]]+"
前のセクションに記載されているすべての言語に対して、組み込みのパターンが提供されています。
バイナリファイルのテキスト差分を実行する
バイナリファイルのテキスト変換バージョンの差分を見ることが望ましい場合があります。たとえば、ワードプロセッサのドキュメントをASCIIテキスト表現に変換し、そのテキストの差分を表示できます。この変換では一部の情報が失われますが、結果の差分は人間が見るのに役立ちます(ただし、直接適用することはできません)。
textconv
設定オプションは、そのような変換を実行するプログラムを定義するために使用されます。このプログラムは、変換するファイル名を単一の引数として受け取り、その結果のテキストを標準出力に出力する必要があります。
たとえば、ファイルのバイナリ情報の代わりにexif情報の差分を表示するには(exifツールがインストールされていると仮定して)、$GIT_DIR/config
ファイル(または$HOME/.gitconfig
ファイル)に次のセクションを追加します。
[diff "jpg"] textconv = exif
注
|
テキスト変換は通常、一方向の変換です。この例では、実際の画像コンテンツを失い、テキストデータにのみ焦点を当てています。これは、textconvによって生成された差分が適用に適していないことを意味します。このため、git diff とgit log ファミリーのコマンド(つまり、log、whatchanged、show)のみがテキスト変換を実行します。git format-patch は決してこの出力を生成しません。バイナリファイルのテキスト変換された差分を誰かに送信したい場合(例えば、変更点を素早く伝えるため)、通常送信するバイナリ差分に加えて、別途生成してコメントとして送信する必要があります。 |
テキスト変換は、特にgit log -p
で大量に実行する場合に遅くなる可能性があるため、Gitは出力をキャッシュし、将来の差分で使用するメカニズムを提供します。キャッシュを有効にするには、diffドライバーの設定で「cachetextconv」変数を設定します。例えば:
[diff "jpg"] textconv = exif cachetextconv = true
これにより、各BLOBに対して「exif」を実行した結果が無期限にキャッシュされます。diffドライバーのtextconv設定変数を変更すると、Gitは自動的にキャッシュエントリを無効にし、textconvフィルターを再実行します。手動でキャッシュを無効にしたい場合(例えば、「exif」のバージョンが更新され、より良い出力を生成するようになったため)、git update-ref -d refs/notes/textconv/jpg
(「jpg」は上記の例のようにdiffドライバーの名前)で手動でキャッシュを削除できます。
textconvと外部diffの選択
リポジトリ内のバイナリまたは特殊な形式のBLOB間の違いを表示したい場合、外部diffコマンドを使用するか、textconvを使用してdiff可能なテキスト形式に変換するかを選択できます。どちらの方法を選択するかは、状況によって異なります。
外部diffコマンドを使用する利点は柔軟性です。行指向の変更を見つけることに縛られず、出力が統合diffに似ている必要もありません。データ形式に最適な方法で変更を特定し報告することができます。
一方、textconvははるかに制限されています。データを行指向のテキスト形式に変換する機能を提供し、Gitは通常のdiffツールを使用して出力を生成します。この方法を選択する利点はいくつかあります。
-
使いやすさ。バイナリからテキストへの変換を記述する方が、独自のdiffを実行するよりもはるかに単純であることが多いです。多くの場合、既存のプログラムをtextconvフィルターとして使用できます(例:exif、odt2txt)。
-
Git diff機能。変換ステップ自体のみを実行することで、色付け、ワードdiff、マージのための結合diffなど、Gitの多くのdiff機能を依然として利用できます。
-
キャッシュ。Textconvキャッシュは、
git log -p
を実行してトリガーする可能性のある繰り返しのdiffを高速化できます。
ファイルをバイナリとしてマークする
Gitは通常、内容の冒頭を調べて、BLOBがテキストデータかバイナリデータかを正しく推測します。しかし、時にはその決定を上書きしたい場合があります。BLOBがファイルの後方でバイナリデータを含んでいるため、または内容が技術的にはテキスト文字で構成されているものの、人間には不透明であるためです。たとえば、多くのPostScriptファイルはASCII文字のみを含んでいますが、ノイズが多く無意味な差分を生成します。
ファイルをバイナリとしてマークする最も簡単な方法は、.gitattributes
ファイルでdiff属性を未設定にすることです。
*.ps -diff
これにより、Gitは通常の差分ではなく、Binary files differ
(またはバイナリパッチが有効な場合はバイナリパッチ)を生成します。
ただし、他のdiffドライバ属性も指定したい場合があります。たとえば、PostScriptファイルを人間が見るためにASCII表現に変換するためにtextconv
を使用したいが、それ以外はバイナリファイルとして扱いたい場合です。-diff
とdiff=ps
の両方の属性を同時に指定することはできません。この解決策は、diff.*.binary
設定オプションを使用することです。
[diff "ps"] textconv = ps2ascii binary = true
三方マージの実行
merge
merge
属性は、git merge
や、git revert
、git cherry-pick
などの他のコマンド中にファイルレベルのマージが必要になったときに、ファイルの3つのバージョンがどのようにマージされるかに影響します。
- 設定済み (Set)
-
組み込みの3-wayマージドライバは、
RCS
スイートのmergeコマンドと同様の方法でコンテンツをマージするために使用されます。これは通常のテキストファイルに適しています。 - 未設定 (Unset)
-
現在のブランチのバージョンを暫定的なマージ結果とし、マージに競合があることを宣言します。これは、明確なマージセマンティクスを持たないバイナリファイルに適しています。
- 未指定 (Unspecified)
-
デフォルトでは、
merge
属性が設定されている場合と同じ組み込みの3-wayマージドライバが使用されます。ただし、merge.default
設定変数は、merge
属性が未指定のパスで使用される異なるマージドライバを指定できます。 - 文字列 (String)
-
指定されたカスタムマージドライバを使用して3-wayマージが実行されます。組み込みの3-wayマージドライバは「text」ドライバを要求することで明示的に指定でき、組み込みの「現在のブランチを使用する」ドライバは「binary」で要求できます。
組み込みマージドライバ
merge
属性を介して要求できる、いくつかの組み込み低レベルマージドライバが定義されています。
- text
-
テキストファイルの通常の3-wayファイルレベルマージ。競合する領域は、競合マーカー
<<<<<<<
、=======
、および>>>>>>>
でマークされます。あなたのブランチからのバージョンは=======
マーカーの前に表示され、マージされたブランチからのバージョンは=======
マーカーの後に表示されます。 - binary
-
作業ツリー内のブランチのバージョンを保持しますが、ユーザーが解決するためにパスを競合状態のままにします。
- union
-
テキストファイルの3-wayファイルレベルマージを実行しますが、競合マーカーを残す代わりに、両方のバージョンから行を取り込みます。これにより、結果ファイル内の追加された行はランダムな順序になりがちであり、ユーザーは結果を検証する必要があります。意味を理解していない場合はこれを使用しないでください。
カスタムマージドライバーの定義
マージドライバの定義は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によって終了した場合)、128より高いゼロ以外のステータスで終了することが期待され、そのような場合、マージは失敗に終わります(競合を生成するのとは異なります)。
merge.*.recursive
変数は、共通の祖先が複数ある場合に、マージドライバが内部マージのために呼び出されたときに使用する他のマージドライバを指定します。未指定の場合、ドライバ自体が内部マージと最終マージの両方に使用されます。
マージドライバは、マージ結果が保存されるパス名をプレースホルダー%P
を介して知ることができます。共通祖先、ローカルヘッド、および他のヘッドに使用される競合ラベルは、それぞれ%S
、%X
、および%Y
を使用して渡すことができます。
空白エラーのチェック
whitespace
core.whitespace
設定変数を使用すると、diffおよびapplyがプロジェクト内のすべてのパスについて空白エラーとみなすべきものを定義できます(git-config[1]を参照)。この属性により、パスごとにきめ細かな制御が可能になります。
アーカイブの作成
export-subst
ファイルのexport-subst
属性が設定されている場合、Gitはこのファイルをアーカイブに追加する際にいくつかのプレースホルダーを展開します。展開はコミットIDの利用可能性に依存します。つまり、git-archive[1]にコミットまたはタグの代わりにツリーが与えられた場合、置換は行われません。プレースホルダーはgit-log[1]のオプション--pretty=format:
と同じですが、ファイル内で$Format:PLACEHOLDERS$
のようにラップする必要があります。例として、文字列$Format:%H$
はコミットハッシュに置き換えられます。ただし、サービス拒否攻撃を避けるため、アーカイブごとに1つの%(describe)
プレースホルダーのみが展開されます。
GUIツールでのファイルの表示
encoding
この属性の値は、GUIツール(例: gitk[1]およびgit-gui[1])が関連ファイルの内容を表示するために使用すべき文字エンコーディングを指定します。パフォーマンス上の考慮から、gitk[1]はオプションでファイルごとのエンコーディングを手動で有効にしない限り、この属性を使用しないことに注意してください。
この属性が設定されていないか無効な値の場合、代わりにgui.encoding
設定変数の値が使用されます(git-config[1]を参照)。
マクロ属性の使用
追跡するバイナリファイルには、行末変換を適用したり、テキスト差分を生成したりしたくないでしょう。例えば、次のように指定する必要があります。
*.jpg -text -diff
しかし、属性が多数ある場合、これは煩わしくなる可能性があります。マクロ属性を使用すると、設定されたときに他の多数の属性を同時に設定または解除する属性を定義できます。システムには組み込みのマクロ属性binary
があります。
*.jpg binary
"binary"属性を設定すると、上記のように"text"および"diff"属性も未設定になります。マクロ属性は「設定済み」しかできないことに注意してください。ただし、設定することで他の属性が設定または未設定になったり、他の属性が「未指定」状態に戻る効果が生じたりする場合があります。
マクロ属性の定義
カスタムマクロ属性は、トップレベルのgitattributesファイル($GIT_DIR/info/attributes
、ワークツリーのトップレベルにある.gitattributes
ファイル、またはグローバル/システム全体のgitattributesファイル)でのみ定義でき、ワークツリーのサブディレクトリにある.gitattributes
ファイルでは定義できません。組み込みのマクロ属性「binary」は、次のものと同等です。
[attr]binary -diff -merge -text
注記
Gitは、作業ツリー内の.gitattributes
ファイルにアクセスする際に、シンボリックリンクを追跡しません。これにより、ファイルがインデックスまたはツリーからアクセスされる場合と、ファイルシステムからアクセスされる場合とで動作の一貫性が保たれます。
例
以下の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
属性が未設定になることを見つけます。 -
次に、
.gitattributes
(親ディレクトリにある)を調べると、最初の行が一致しますが、t/.gitattributes
ファイルはすでにこのパスにmerge
、foo
、bar
属性をどのように与えるかを決定しているため、foo
とbar
は未設定のままになります。属性baz
は設定されます。 -
最後に
$GIT_DIR/info/attributes
を調べます。このファイルはツリー内の設定を上書きするために使用されます。最初の行が一致し、foo
は設定され、bar
は未指定状態に戻され、baz
は未設定になります。
結果として、t/abc
への属性割り当ては次のようになります。
foo set to true bar unspecified baz set to false merge set to string value "filfre" frotz unspecified
GIT
git[1]スイートの一部