.gitattributes ファイルで拡張子ごとの改行コードなどを明示

無料ソースコード管理 (SCM: software configuration management) ソフト Git で、バージョン管理する各ファイルごとにそのファイルがテキストバイナリか、改行コード明示が行える .gitattributes ファイルの作成例と、その際に用いた text, -text, -diff, binary, eol 属性について紹介します。
# gitattributes は、とても多くの設定ができるため、本記事では実際に用いた部分だけを紹介します。

git-scm 公式サイトの一部 20250408

※Git-2.49.0 (64 bit) を使用します。

.gitattributes ファイルとは

.gitattributes ファイルは、 Gitファイルパスに属性を与えるテキストファイルです。
1行ごとに、ファイルパス( *.txt のようなワイルドカードも可能)と与える属性群を指定します。

gitattributes file is a simple text file that gives attributes to pathnames.
gitattributes ファイルは、パス名に属性を与える単純なテキスト ファイルです。

Each line in gitattributes file is of form:
gitattributes ファイルの各行の形式は次のとおりです。

pattern attr1 attr2 ...
Git – gitattributes Documentation と Google 翻訳

# で始まる行は無視されるのでコメントに使用できます。

That is, a pattern followed by an attributes list, separated by whitespaces. Leading and trailing whitespaces are ignored. Lines that begin with # are ignored. Patterns that begin with a double quote are quoted in C style. When the pattern matches the path in question, the attributes listed on the line are given to the path.

つまり、パターンの後に空白で区切られた属性リストが続きます。先頭と末尾の空白は無視されます。 # で始まる行は無視されます。二重引用符で始まるパターンは、C スタイルで引用符で囲まれます。パターンが問題のパスと一致すると、その行にリストされている属性がパスに与えられます。

Git – gitattributes Documentation と Google 翻訳

作業ディレクトリ内の拡張子を列挙するプログラム

この章は、作業ディレクトリにあるファイルの拡張子を PowerShell プログラムで列挙する手順を紹介します。
特に列挙する必要がない場合は読み飛ばしてください。

今回は、個別のファイルパスではなく、*.txt のようなワイルドカードを用いて拡張子ごとに、テキスト・バイナリ、改行コードの属性設定します。

そのために、作成した PowerShell プログラムで、作業ディレクトリ内に存在する拡張子を列挙します。
※除外指定したフォルダや拡張子は、列挙から除かれます。

プログラムに関しては以下の記事を参照してください。

プログラムの実行

Windows PowerShell アプリを起動して、作業ディレクトリに移動してから、以下のプログラムをコピーして Ctrl + V で貼り付けて Enter キーを押して実行することで、先頭に *. がついた拡張子のリストが出力されます。
※以降の SS は、プログラムの2行目の ‘.//.godot’ が追加されていない状態での実行結果です。

# 除外するフォルダ、拡張子を指定します。
$excludeDirsRelative = @('./output', './build', './/.godot')  # 相対パスで指定
$excludeExtensions = @('.dll', '.fnt')  # 拡張子の除外リスト

# フォルダパス $dir は、除外するフォルダパスのリスト $excludeDirs に含まれているか確認します。
function IsExcluded($dir, $excludeDirs) {
    $fullPath = [System.IO.Path]::GetFullPath($dir)
    return $excludeDirs | Where-Object { $fullPath -like "$_*" }
}

#-relativePaths パラメータに割り当てた配列の全ての相対パスを絶対パスに変換した配列を返します。
# 変換に失敗したパスは返り値の配列に含まれません。
function DirsRelativeToAbsolute {
    param (
        [string[]]$relativePaths
    )
    return $relativePaths | ForEach-Object {
        try {
            [System.IO.Path]::GetFullPath((Resolve-Path -LiteralPath $_).ProviderPath)
        } catch {
            Write-Warning "除外対象のパス '$_' が見つかりませんでした。スキップします。"
            $null
        }
    } | Where-Object { $_ -ne $null }
}

# $excludeDirsRelative で指定された除外するフォルダパスを上記関数で絶対パスに変換して格納します。
$excludeDirs = DirsRelativeToAbsolute -relativePaths $excludeDirsRelative

# 除外するフォルダ、拡張子を除いた、カレントディレクトリ以下に含まれる拡張子を表示します。
Get-ChildItem -Recurse -File -Force |
    Where-Object {
        $_.FullName -notmatch '\\\.git\\' -and
        -not (IsExcluded $_.DirectoryName $excludeDirs) -and
        $_.Extension -ne '' -and
        $_.Extension -notin $excludeExtensions
    } |
    Select-Object -ExpandProperty Extension |
    ForEach-Object { $_.TrimStart('.') } |
    Sort-Object -Unique |
    ForEach-Object { Write-Host "*.$_" }
gitattributes で設定する拡張子を powershell で列挙1

実行結果の拡張子のリストの部分をマウスドラッグで範囲選択して、 Ctrl + C でコピーします。

gitattributes で設定する拡張子を powershell で列挙2

テキストファイル新規作成して、.gitattributes にリネームします。
.gitattributes ファイルをテキストエディタで開いて、先ほどコピーした拡張子のリスト貼り付け保存します。
#テキストエディタ Mery さん、いつもありがとう。

gitattributes で設定する拡張子を powershell で列挙3

今回使う .gitattributes の属性

今回、拡張子ごとに指定する属性についてのみ紹介します。
他の項目や、詳細については「Git – gitattributes Documentation」を参照してください。

text 属性

text 属性は、該当するファイルをテキストファイルとして扱います。
これにより、後述する Git 設定 core.autocrlf が有効ならば、 OS に応じてリポジトリと作業ディレクトリの間で自動的に該当するファイルの改行コード変換します。
また、差分の比較やマージができます。

text

This attribute marks the path as a text file, which enables end-of-line conversion: When a matching file is added to the index, the file’s line endings are normalized to LF in the index. Conversely, when the file is copied from the index to the working directory, its line endings may be converted from LF to CRLF depending on the eol attribute, the Git config, and the platform (see explanation of eol below).

この属性はパスをテキスト ファイルとしてマークし、行末変換を有効にします。一致するファイルがインデックスに追加されると、ファイルの行末はインデックス内で LF に正規化されます。逆に、ファイルがインデックスから作業ディレクトリにコピーされると、eol 属性、Git 設定、プラットフォームに応じて、その行末が LF から CRLF に変換される場合があります(下記の eol の説明を参照)。

Git – gitattributes Documentation と Google 翻訳

text=auto で、テキストかバイナリかの判定Git行わせる属性なども指定できますが、今回は使用しないので割愛します。

eol 属性

eol 属性で、テキストの改行コードを指定できます。
これにより、チェックアウト時とコミット時で、LF と CRLF に相互に変える指定ができます。
# Mac の改行コードは CR ではないかと思いましたが、今は LF が使われているようです。

また、 text 属性を指定しないで eol 属性を指定すると、 text 属性を指定したことになります。

This attribute marks a path to use a specific line-ending style in the working tree when it is checked out. It has effect only if text or text=auto is set (see above), but specifying eol automatically sets text if text was left unspecified.

この属性は、チェックアウト時に作業ツリー内で特定の行末スタイルを使用するパスをマークします。 text または text=auto が設定されている場合にのみ効果がありますが(上記を参照)、eol を指定すると、text が指定されていない場合は自動的に text が設定されます。

Set to string value “crlf

This setting converts the file’s line endings in the working directory to CRLF when the file is checked out.

この設定は、ファイルがチェックアウトされるときに、作業ディレクトリ内のファイルの行末を CRLF に変換します。

Set to string value “lf

This setting uses the same line endings in the working directory as in the index when the file is checked out.

この設定では、ファイルのチェックアウト時にインデックスと同じ行末が作業ディレクトリ内で使用されます。

Unspecified

If the eol attribute is unspecified for a file, its line endings in the working directory are determined by the core.autocrlf or core.eol configuration variable (see the definitions of those options in git-config[1]). If text is set but neither of those variables is, the default is eol=crlf on Windows and eol=lf on all other platforms.

ファイルの eol 属性が指定されていない場合、作業ディレクトリ内の行末は core.autocrlf または core.eol 設定変数によって決定されます (git-config[1] のこれらのオプションの定義を参照)。 text が設定されているが、これらの変数のどちらも設定されていない場合、デフォルトは Windows では eol=crlf、他のすべてのプラットフォームでは eol=lf になります。

Git – gitattributes Documentation と Google 翻訳

-text 属性

-text 属性は、テキストではないことを表す属性です。
また、これを使用することで、改行コードの自動変換などの対象から外されます。

The attributes allow a fine-grained control, how the line endings are converted. Here is an example that will make Git normalize .txt, .vcproj and .sh files, ensure that .vcproj files have CRLF and .sh files have LF in the working directory, and prevent .jpg files from being normalized regardless of their content.

属性を使用すると、行末の変換方法を詳細に制御できます。ここでは、Git で .txt、.vcproj、および .sh ファイルを正規化し、作業ディレクトリ内で .vcproj ファイルに CRLF が含まれ、.sh ファイルに LF が含まれるようにし、.jpg ファイルが内容に関係なく正規化されないようにする例を示します。

*               text=auto
*.txt		text
*.vcproj	text eol=crlf
*.sh		text eol=lf
*.jpg		-text
Git – gitattributes Documentation と Google 翻訳

上記の説明の「正規化 (normalized)」は、改行コードの統一・変換を指すと考えられます。

This attribute enables and controls end-of-line normalization. When a text file is normalized, its line endings are converted to LF in the repository. To control what line ending style is used in the working directory, use the eol attribute for a single file and the core.eol configuration variable for all text files.

この属性は、行末の正規化を有効にし、制御します。テキスト ファイルが正規化されると、その行末はリポジトリ内で LF に変換されます。作業ディレクトリで使用される行末スタイルを制御するには、単一のファイルには eol 属性を使用し、すべてのテキスト ファイルには core.eol 構成変数を使用します。

Git – gitattributes Documentation と Google 翻訳

binary 属性

binary 属性は、2つの属性 -text -diff同じ意味を持つ、組み込みマクロ属性です。

You do not want any end-of-line conversions applied to, nor textual diffs produced for, any binary file you track. You would need to specify e.g.

追跡するバイナリ ファイルに行末変換を適用したり、テキストの差分を生成したりすることは望ましくありません。たとえば、次のように指定する必要があります。

*.jpg -text -diff

but that may become cumbersome, when you have many attributes. Using macro attributes, you can define an attribute that, when set, also sets or unsets a number of other attributes at the same time. The system knows a built-in macro attribute, binary:

しかし、多くの属性がある場合、それは面倒になる可能性があります。マクロ属性を使用すると、設定時に他の多数の属性も同時に設定または設定解除する属性を定義できます。システムは組み込みマクロ属性、バイナリを認識します。

*.jpg binary

Setting the “binary” attribute also unsets the “text” and “diff” attributes as above. Note that macro attributes can only be “Set”, though setting one might have the effect of setting or unsetting other attributes or even returning other attributes to the “Unspecified” state.

「binary」属性を設定すると、上記のように「text」属性と「diff」属性の設定も解除されます。マクロ属性は「設定」のみに設定できますが、マクロ属性を設定すると、他の属性を設定または設定解除したり、他の属性を「未指定」状態に戻したりする可能性があることに注意してください。

Git – gitattributes Documentation と Google 翻訳

公式では、例として、テキスト形式だけど、ユーザが直接編集することのないようなファイルに binary 属性を割り当てていました。

テキストファイルのように見えるファイルであっても、何らかの目的のために意図的にバイナリデータとして扱いたいことがあります。 
(中略)
すべての pbxproj ファイルをバイナリデータとして扱うよう Git に指定するには、次の行を .gitattributes ファイルに追加します。

*.pbxproj binary

これで、Git が CRLF 問題の対応をすることもなくなりますし、git show や git diff を実行したときにもこのファイルの diff を調べることはなくなります。

Git – Git の属性

-diff 属性

-diff は、テキスト差分を生成させない属性です。
※ git の設定によって、[diff “ps”] で ps 拡張子のファイルの差分について、さらに細かな設定ができるようですが、その必要が今はないため割愛します。

差分を表示しませんが、変更の有無確認できます。

Git usually guesses correctly whether a blob contains text or binary data by examining the beginning of the contents. However, sometimes you may want to override its decision, either because a blob contains binary data later in the file, or because the content, while technically composed of text characters, is opaque to a human reader. For example, many postscript files contain only ASCII characters, but produce noisy and meaningless diffs.

Git は通常、内容の先頭を調べることで、BLOB にテキスト データが含まれるかバイナリ データが含まれるかを正確に推測します。ただし、BLOB にはファイルの後半にバイナリ データが含まれているため、または内容が技術的にはテキスト文字で構成されているものの、人間の読者には不透明であるため、その決定をオーバーライドする必要がある場合があります。たとえば、多くの PostScript ファイルには ASCII 文字のみが含まれていますが、ノイズが多く意味のない差分が生成されます。

The simplest way to mark a file as binary is to unset the diff attribute in the .gitattributes file:

ファイルをバイナリとしてマークする最も簡単な方法は、.gitattributes ファイル内の diff 属性の設定を解除することです。

*.ps -diff

This will cause Git to generate Binary files differ (or a binary patch, if binary patches are enabled) instead of a regular diff.

これにより、Git は通常の差分ではなくバイナリ ファイル差分 (バイナリ パッチが有効な場合はバイナリ パッチ) を生成します。

However, one may also want to specify other diff driver attributes. For example, you might want to use textconv to convert postscript files to an ASCII representation for human viewing, but otherwise treat them as binary files. You cannot specify both -diff and diff=ps attributes. The solution is to use the diff.*.binary config option:

ただし、他の diff ドライバー属性を指定することもできます。たとえば、textconv を使用して postscript ファイルを人間が表示できるように ASCII 表現に変換し、それ以外の場合はバイナリ ファイルとして扱いたい場合があります。 -diff 属性と diff=ps 属性の両方を指定することはできません。解決策は、diff.*.binary 設定オプションを使用することです。

[diff "ps"]
textconv = ps2ascii
binary = true
Git – gitattributes Documentation と Google 翻訳

3つに分けた拡張子の属性

今回の例では、以下の3種類で、拡張子ごとに属性を設定します。

テキスト形式で直接編集するファイル

.txt や .md などのテキスト形式で直接編集するファイルについては、

  • チェックアウト・コミット時に CRLF, LF 改行コード自動変換する
  • 差分確認する

という要求にあわせて、 text 属性を割り当てます。

eol について

改行コードについては、拡張子ごと推奨されているもの、デフォルトの改行コードに合わせます。

Windows OS で作業を行うので、基本的には CRLF を改行コードにするものが多いですが、 .sh などの LF 改行コードを推奨しているファイルについては、 LF を指定します。

*.txt text eol=crlf
*.sh text eol=lf

eol の各属性を指定することで、 text 属性を指定する必要はなくなりますが、わかりやすいように text 属性も記述します。

テキスト形式だけど直接編集しないファイル

.tscn や .vcproj のようにテキスト形式だけど直接編集しないファイルについては、

  • チェックアウト・コミット時に CRLF, LF 改行コード自動変換しない
  • 差分確認する

という要求にあわせて、 -text 属性を割り当てます。
-diff 属性は割り当てないので、差分は表示されます。

.tscn は GodotEngine のシーン情報を保存するテキスト形式の拡張子ですが、直接編集することはないと思います。
また、改行コードを調べると LF だったので、チェックアウト時に CRLF に変更して無用な変更は行わない方が良いと判断しました。

gitattributes で設定する拡張子を powershell で列挙4

テキスト形式ではないファイル

.jpg や .dll などのテキスト形式ではないファイルについては

  • チェックアウト・コミット時に CRLF, LF 改行コード自動変換しない
  • 差分確認しない

という要求に合わせて、 -text -diff 属性を割り当てます。
binary マクロ属性でも同じですが、わかりやすいように -text -diff を使用します。

未設定の拡張子に対するデフォルトの設定

拡張子ごとの属性を指定する前に、全てのファイルのデフォルトの属性を以下のように設定します。

# 全てのファイルのデフォルトの設定です。
# text かどうかの判定を Git で自動的に行い、テキストと判定されれば 
# core.autocrlf などに従い改行コードを自動的に変換します。
# ただし、設定がこのあとにある場合は、そちらが優先されます。
* text=auto

When text is set to “auto”, Git decides by itself whether the file is text or binary. If it is text and the file was not already in Git with CRLF endings, line endings are converted on checkin and checkout as described above. Otherwise, no conversion is done on checkin or checkout.

text が「auto」に設定されている場合、Git はファイルがテキストであるかバイナリであるかを独自に決定します。ファイルがテキストであり、ファイルが CRLF 末尾でまだ Git に存在していない場合、行末は上記のようにチェックインおよびチェックアウト時に変換されます。それ以外の場合、チェックインまたはチェックアウト時に変換は行われません。

Git – gitattributes Documentation と Google 翻訳

拡張子単位で属性を指定した .gitattributes の例

作成した .gitattributes テキストファイルに *. から始まる拡張子のリストを記述します。
前の章のプログラムを実行した場合はその出力結果をコピーして貼り付けます。
※今回は、拡張子ごとの設定ですが、project/piyo/hoge.txt のように特定のファイルだけを個別に設定することもできます。

# 全てのファイルのデフォルトの設定です。
# text かどうかの判定を Git で自動的に行い、テキストと判定されれば 
# core.autocrlf などに従い改行コードを自動的に変換します。
# ただし、設定がこのあとにある場合は、そちらが優先されます。
* text=auto

# 拡張子単位の属性の割り当てです。
*.cfg -text
*.dylib -text -diff
*.exp -text -diff
*.gd text eol=crlf
*.gdextension -text -diff
*.gitattributes text eol=crlf
*.gitignore text eol=crlf
*.godot -text
*.import -text -diff
*.lib -text -diff
*.md text eol=crlf
*.piyopiyo -text -diff
*.png -text -diff
*.so -text -diff
*.svg -text
*.tmp -text -diff
*.tres -text
*.tscn -text
*.ttf -text -diff
*.txt text eol=crlf

まとめ

今回は、無料ソースコード管理 (SCM: software configuration management) ソフト Git で、バージョン管理する各ファイルごとにそのファイルがテキストバイナリか、改行コード明示が行える .gitattributes ファイルの作成例と、その際に用いた text, -text, -diff, binary, eol 属性について紹介しました。
# gitattributes は、とても多くの設定ができるため、本記事では実際に用いた部分だけを紹介しました。

参照サイト Thank You!

記事一覧 → Compota-Soft-Press

コメント

Ads Blocker Image Powered by Code Help Pro

お願い - Ads Blocker Detected

このサイトは広告を掲載して運営しています。

ポップアップを閉じて閲覧できますが、よろしければ

このサイト内の広告を非表示にする拡張機能をオフにしていただけませんか?

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

We have detected that you are using extensions to block ads. Please support us by disabling these ads blocker.

タイトルとURLをコピーしました