248

Core.autocrlf設定のしくみに関するgitドキュメントだけでなく、スタック オーバーフローに関するさまざまな質問と回答も読みました。

これは私が読んだことからの私の理解です:

Unix および Mac OSX (OSX より前は CR を使用) クライアントは LF の行末を使用します。
Windows クライアントは CRLF 行末を使用します。

クライアントで core.autocrlf が true に設定されている場合、git リポジトリは常にファイルを LF 行末形式で保存し、クライアント上のファイルの行末は、チェックアウト/コミット時に前後に変換されます。 -LF 行末。クライアントの行末ファイルの形式に関係なく (これは、Tim Clem の定義と一致しません。以下の更新を参照してください)。

これは、core.autocrlf の 'input' および 'false' 設定について同じことを文書化しようとするマトリックスであり、行末の変換動作が不明な場合は疑問符が付いています。

私の質問は次のとおりです。

  1. クエスチョンマークはどうあるべきですか?
  2. このマトリックスは「非疑問符」に対して正しいですか?

コンセンサスが形成されているように見えるので、回答から疑問符を更新します。

                       core.autocrlf 値
            真入力偽
-------------------------------------------------- --------
コミット | 変換 ??
新しい | to LF (LFに変換?) (無変換?)

コミット | に変換 ?番号
既存 | LF(LFに変換?)変換

チェックアウト | に変換 ?番号
既存 | CRLF (無変換?) 変換

さまざまな設定の長所と短所について意見を求めているわけではありません。私は、git が 3 つの設定のそれぞれで動作することを期待する方法を明確にするデータを探しています。

--

2012 年 4 月 17 日更新: コメントで JJD によってリンクされた Tim Clem の記事を読んだ後、上の表の「不明な」値の一部を変更し、「checkout existing | true to convert」を変更しました。クライアントに変換する代わりに CRLF に変換します。」これは彼が与えた定義であり、私が他の場所で見たものよりも明確です:

core.autocrlf = false

これはデフォルトですが、ほとんどの人はこれをすぐに変更することをお勧めします。false を使用した結果、Git がファイルの行末を台無しにすることはありません。LF、CRLF、CR、またはこれら 3 つのランダムな組み合わせでファイルをチェックインでき、Git は気にしません。これにより、差分が読みにくくなり、マージが難しくなる可能性があります。Unix/Linux の世界で働くほとんどの人は、CRLF の問題がなく、ファイルがオブジェクト データベースに書き込まれたり、作業ディレクトリに書き出されたりするたびに Git が余分な作業を行う必要がないため、この値を使用します。

core.autocrlf = true

これは、Git がすべてのテキスト ファイルを処理し、そのファイルをオブジェクト データベースに書き込むときに CRLF が LF に置き換えられ、作業ディレクトリに書き出すときにすべての LF が CRLF に戻されることを意味します。これは、作業ディレクトリに CRLF を保持しながら、他のプラットフォームでリポジトリを使用できるようにするため、Windows で推奨される設定です。

core.autocrlf = 入力

これは、Git がすべてのテキスト ファイルを処理し、そのファイルをオブジェクト データベースに書き込むときに CRLF が LF に置き換えられることを確認することを意味します。ただし、その逆は行いません。オブジェクト データベースからファイルを読み込んで作業ディレクトリに書き込むと、行末を示す LF がまだ残っています。この設定は通常、Unix/Linux/OS X で CRLF がリポジトリに書き込まれないようにするために使用されます。Web ブラウザーからコードを貼り付けて、誤って CRLF をファイルの 1 つに取り込んだ場合、Git は、オブジェクト データベースに書き込むときに、それらが LF に置き換えられることを確認します。

Tim の記事は素晴らしいものです。唯一欠けていると思うのは、リポジトリが LF 形式であると彼が想定していることです。これは、特に Windows のみのプロジェクトの場合、必ずしもそうではありません。

Tim の記事をjmlane によるこれまでの最高投票数の回答と比較すると、true 設定と入力設定が完全​​に一致し、false 設定が一致していないことがわかります。

4

8 に答える 8

144

どのように機能するかについての最良の説明はcore.autocrlfgitattributesの man ページのtext属性セクションにあります。

これは、core.autocrlf現在(または少なくとも私が認識しているv1.7.2以降)どのように機能するように見えるかです:

  • core.autocrlf = true
  1. 文字のみを含むリポジトリからチェックアウトされたテキスト ファイルは、作業ツリーLFに正規化さCRLFれます。リポジトリに含まれるファイルは変更されCRLFません
  2. リポジトリに文字しかないテキスト ファイルは、リポジトリにコミットされたときにからにLF正規化されます。リポジトリに含まれるファイルはそのままコミットされます。CRLFLFCRLF
  • core.autocrlf = input
  1. リポジトリからチェックアウトされたテキスト ファイルは、元の EOL 文字を作業ツリーに保持します。
  2. 文字を含む作業ツリー内のテキスト ファイルは、リポジトリにコミットされたときにCRLF正規化されます。LF
  • core.autocrlf = false
  1. core.eol作業ツリーのテキスト ファイルで EOL 文字を指定します。
  2. core.eol = nativeCRLFデフォルトでは、作業ツリーの EOL は、git が実行されている場所 (Windows マシンまたはLF*nix ) に依存することを意味します。
  3. リポジトリgitattributes設定は、リポジトリへのコミットの EOL 文字の正規化を決定します (デフォルトはLF文字の正規化です)。

私は最近この問題を調査したばかりで、状況が非常に複雑であることもわかりました。このcore.eol設定は、EOL 文字が git によってどのように処理されるかを明確にするのに役立ちました。

于 2010-12-13T02:45:27.843 に答える
72

混合プラットフォーム プロジェクトにおける EOL の問題は、長い間私の人生を惨めなものにしてきました。通常、この問題は、異なる EOL が混在するファイルがリポジトリに既に存在する場合に発生します。この意味は:

  1. リポジトリには、異なる EOL の異なるファイルが含まれる場合があります
  2. リポジトリ内の一部のファイルには EOL が混在している場合があります。たとえば、同じファイル内でCRLFとが組み合わされている場合です。LF

これがどのように発生するかはここでは問題ではありませんが、実際に発生します。

さまざまなモードとその組み合わせについて、Windows でいくつかの変換テストを実行しました。
わずかに変更された表で、私が得たものは次のとおりです。

                 | | | の場合の結果の変換 結果の変換
                 | | さまざまな | でファイルをコミットする FROM レポのチェックアウト -
                 | | EOL INTO リポジトリと | その中に混合ファイルがあり、
                 | | core.autocrlf 値: | core.autocrlf 値:           
-------------------------------------------------- ------------------------------
ファイル | 真 | 入力 | 偽 | 真 | 入力 | 間違い
-------------------------------------------------- ------------------------------
Windows-CRLF | CRLF -> LF | CRLF -> LF | そのまま | そのまま | そのまま | そのまま
Unix-LF | そのまま | そのまま | そのまま | LF -> CRLF | そのまま | そのまま
マック -CR | そのまま | そのまま | そのまま | そのまま | そのまま | そのまま
混合 CRLF+LF | そのまま | そのまま | そのまま | そのまま | そのまま | そのまま
混合 CRLF+LF+CR | そのまま | そのまま | そのまま | そのまま | そのまま | そのまま

ご覧のとおり、コミット時に変換が発生するケースが 2 つあります (左側の 3 列)。残りの場合、ファイルはそのままコミットされます。

チェックアウト時 (右側の 3 列)、次の場合にコンバージョンが発生するケースは 1 つだけです。

  1. core.autocrlfでありtrue
  2. リポジトリ内のファイルにはLFEOL があります。

私にとって最も驚くべきことは、多くの EOL の問題の原因は、CRLF+のような混合 EOLLFが正規化される構成がないことです。

また、「古い」Mac EOLCRのみが変換されないことにも注意してください。
これは、不適切に記述された EOL 変換スクリプトがs をsに変換するだけでCRLFs+ s が混在するエンディング ファイルを変換しようとすると、aが に変換された場所でファイルが「孤独な」s の混在モードのままになることを意味します。 モードであっても Git は何も変換せず、EOL の大混乱が続きます。一部のエディタやコンパイラ (VS2010 など) は Mac の EOL を好まないため、これは実際に私に起こり、私のファイルをひどく台無しにしました。LFLFCRLFCRCRLFCRCRLF
true

これらの問題を実際に処理する唯一の方法は、すべてのファイルをorモードでチェックアウトし、適切な正規化を実行して、変更されたファイル (存在する場合) を再コミットすることによって、リポジトリ全体を時々正規化することだと思います。Windows では、おそらく での作業を再開します。inputfalsecore.autocrlf true

于 2012-12-26T11:23:42.983 に答える
50

core.autocrlf値は OS タイプに依存しませんが、Windows のデフォルト値はtrueLinux の場合と -inputです。コミットとチェックアウトのケースで考えられる 3 つの値を調べた結果、次の表が表示されます。

╔═══════════════╦══════════════╦══════════════╦══════════════╗
║ core.autocrlf ║     false    ║     input    ║     true     ║
╠═══════════════╬══════════════╬══════════════╬══════════════╣
║               ║ LF   => LF   ║ LF   => LF   ║ LF   => LF   ║
║ git commit    ║ CR   => CR   ║ CR   => CR   ║ CR   => CR   ║
║               ║ CRLF => CRLF ║ CRLF => LF   ║ CRLF => LF   ║
╠═══════════════╬══════════════╬══════════════╬══════════════╣
║               ║ LF   => LF   ║ LF   => LF   ║ LF   => CRLF ║
║ git checkout  ║ CR   => CR   ║ CR   => CR   ║ CR   => CR   ║
║               ║ CRLF => CRLF ║ CRLF => CRLF ║ CRLF => CRLF ║
╚═══════════════╩══════════════╩══════════════╩══════════════╝
于 2016-12-22T11:41:34.533 に答える
40

今後のGit1.7.2で、「eol変換」の面で状況が変わりつつあります。

新しい構成設定core.eolが追加/進化しています:

これは、現在(私のシリーズの最後のもの)にある「Add」core.eol「configvariable」コミットの代わりです。「 」が「」の 代わりであることを意味する代わりに、テキストファイルの正規化がないリポジトリの作業ディレクトリでCRLFを操作したいユーザーのみが対象であるという事実を明示します。 有効にすると、「core.eol」は無視されます。pu
core.autocrlf=true* text=autoautocrlf

新しい構成変数" core.eol"を導入します。これにより、ユーザーは、作業ディレクトリー内の行末正規化ファイルに使用する行末を設定できます。
デフォルトは「native」です。これは、WindowsではCRLF、その他の場所ではLFを意味します。core.autocrlf「 」はをオーバーライドすることに注意してくださいcore.eol
この意味は:

[core]
  autocrlf = true

core.eolが""に設定されている場合でも、CRLFを作業ディレクトリに配置しlfます。

core.eol:

textプロパティが設定されているファイルの作業ディレクトリで使用する行末タイプを設定します。
代替手段は、「lf」、「crlf」、および「native」であり、プラットフォームのネイティブ行末を使用します。
デフォルト値はですnative


他の進化が検討されています:

1.8の場合、core.autocrlf正規化をオンにして、作業ディレクトリの行終了の決定をcore.eolに任せることを検討しますが、それでは人々の設定が壊れます。


git 2.8(2016年3月)はcore.autocrlf、eolに影響を与える方法を改善します。

commit 817a0c7(2016年2月23日)、commit 6e336a5commit df747b8commit df747b8(2016年2月10日)、commit df747b8commit df747b8(2016年2月10日)、およびcommit 4b4024fcommit bb211b4commit 92cce13commit 320d39c、 commit4b40を参照してくださいbb211b4コミット、92cce13をコミット、320d39cをコミット(2016年2月5日)byTorstenBögershausen(tboegi
(JunioCHamanoによってマージされました---コミットc6b94ebgitster、2016年2月26日)

convert.c:リファクタリングcrlf_action

の決定と使用法をリファクタリングしますcrlf_action
現在、crlfファイルに「」属性が設定されていない場合は、crlf_actionに設定され CRLF_GUESSます。代わりに使用して、前と同じように「 」または「 」CRLF_UNDEFINEDを検索してください。 texteol

古い使用法を置き換えCRLF_GUESSます:

CRLF_GUESS && core.autocrlf=true -> CRLF_AUTO_CRLF
CRLF_GUESS && core.autocrlf=false -> CRLF_BINARY
CRLF_GUESS && core.autocrlf=input -> CRLF_AUTO_INPUT

以下を定義することにより、何が何であるかをより明確にします。

- CRLF_UNDEFINED : No attributes set. Temparally used, until core.autocrlf
                   and core.eol is evaluated and one of CRLF_BINARY,
                   CRLF_AUTO_INPUT or CRLF_AUTO_CRLF is selected
- CRLF_BINARY    : No processing of line endings.
- CRLF_TEXT      : attribute "text" is set, line endings are processed.
- CRLF_TEXT_INPUT: attribute "input" or "eol=lf" is set. This implies text.
- CRLF_TEXT_CRLF : attribute "eol=crlf" is set. This implies text.
- CRLF_AUTO      : attribute "auto" is set.
- CRLF_AUTO_INPUT: core.autocrlf=input (no attributes)
- CRLF_AUTO_CRLF : core.autocrlf=true  (no attributes)

torekがコメントに追加するように:

これらすべての変換(eol=またはautocrlf設定から​​のEOL変換、および " clean"フィルター)は、ファイルが作業ツリーからインデックスに移動するとき、つまり、時間git addではなく実行中に実行されますgit commit
(ただし、git commit -aまたは--onlyまたは--includeその時点でインデックスにファイルを追加することに注意してください。)

詳細については、「autocrlfとeolの違い」を参照してください。

于 2010-07-09T04:21:44.443 に答える
7

これが誰かを助ける場合に備えて、これまでの私の理解です。

core.autocrlf=truecore.safecrlf = true

すべての行末が同じリポジトリがありますが、異なるプラットフォームで作業しています。Git は、行末がプラットフォームのデフォルトに変換されることを確認します。なぜこれが重要なのですか?新しいファイルを作成するとします。プラットフォームのテキスト エディターは、デフォルトの行末を使用します。チェックイン時に、core.autocrlf が true に設定されていない場合は、デフォルトで別の行末に設定されているプラ​​ットフォーム上の誰かに、行末の不一致が発生しています。crlf操作が可逆であることを知りたいので、常にsafecrlfも設定します。これら 2 つの設定により、git はファイルを変更しますが、変更が元に戻せることを確認します

core.autocrlf=false

既に複数の行末がチェックインされているリポジトリがあり、誤った行末を修正すると他の問題が発生する可能性があります。この場合、git に行末を変換するように指示しないのが最善です。なぜなら、git が解決するように設計された問題を悪化させ、差分を読みやすくし、マージの苦痛を軽減するからです。この設定では、git はファイルを変更しません

core.autocrlf=input

これは、デフォルトで LF の行末に設定されているプラ​​ットフォームで、CRLF の行末を持つファイルを作成したユース ケースをカバーするためであるため、使用しません。代わりに、テキスト エディターが常に新しいファイルをプラットフォームの行末の既定値で保存するようにすることを好みます。

于 2014-01-20T20:27:34.677 に答える