web-dev-qa-db-ja.com

Gitで最良のCRLF(キャリッジリターン、ラインフィード)処理方法は何ですか?

CRLFで終わる行でファイルをコミットしようとしましたが失敗しました。

私はWindowsコンピュータでさまざまな方法を試して一日中過ごしましたが、Gitを使用するのをやめて代わりに Mercurial を試してみました。

回答ごとにベストプラクティスを1つだけ共有してください。

573
Daniel Jomphe

この質問をしてから約4年後、私はついに私を完全に満足させる答えを見つけました

詳細については、github:help行末処理 のガイドを参照してください。

Gitでは、.gitattributesファイルで text attribute を使用して、リポジトリの行終了プロパティを直接設定できます。このファイルはリポジトリにコミットされ、core.autocrlf設定をオーバーライドします。これにより、git設定に関係なく、すべてのユーザーに一貫した動作を保証できます。

したがって

これの利点は、エンドオブライン設定がリポジトリとともに移動するようになり、共同編集者が適切なグローバル設定を持っているかどうかを心配する必要がないことです。

.gitattributesファイルの例を次に示します

# Auto detect text files and perform LF normalization
*        text=auto

*.cs     text diff=csharp
*.Java   text diff=Java
*.html   text diff=html
*.css    text
*.js     text
*.sql    text

*.csproj text merge=union
*.sln    text merge=union eol=crlf

*.docx   diff=astextplain
*.DOCX   diff=astextplain

# absolute paths are ok, as are globs
/**/postinst* text eol=lf

# paths that don't start with / are treated relative to the .gitattributes folder
relative/path/*.txt text eol=lf

最も一般的なプログラミング言語には、便利な すぐに使用できる.gitattributesファイルのコレクション があります。始めるのに便利です。

.gitattributesを作成または調整したら、一度だけ 行末の再正規化 を実行する必要があります=。

GitHub Desktop アプリは、アプリでプロジェクトのGitリポジトリを開いた後、.gitattributesファイルを提案および作成できることに注意してください。これを試すには、歯車アイコン(右上隅)>リポジトリ設定...>行末と属性をクリックします。推奨.gitattributesを追加するよう求められます。同意すると、アプリはリポジトリ内のすべてのファイルの正規化も実行します。

最後に、 Mind the End of Your Line の記事でより多くの背景を提供し、Gitが現在の問題でどのように進化したかを説明します。私はこれを考慮します必要な読み取り

チーム内にEGitまたはJGit(EclipseやTeamCityなどのツールを使用)を使用して変更をコミットするユーザーがいる可能性があります。 @gatinuetaがこの回答のコメントで説明したように、あなたは運が悪い。

チームでEgitまたはJGitを使用している人がいる場合、この設定は完全には満足しません。これらのツールは.gitattributesを無視し、CRLFファイルを喜んでチェックインするためです https://bugs.Eclipse.org/bugs/ show_bug.cgi?id = 342372

たとえば、 SourceTree のように、別のクライアントで変更をコミットさせることです。当時の私たちのチームは、多くのユースケースでEclipseのEGitよりもこのツールを好んでいました。

ソフトウェアは簡単だと誰が言ったのですか? :-/

720
Daniel Jomphe

行末を変換しません。データを解釈するのはVCSの仕事ではありません - 単にそれを保存してバージョン管理するだけです。いずれにせよ、現代のテキストエディタは両方の種類の行末を読むことができます。

112
John Millikin

本当に自分のしていることがわからない限り、ほとんどの場合autocrlf=inputが必要です。

以下にいくつかの追加のコンテキスト:

DOSのエンディングが好きならcore.autocrlf=true、unix-newlinesが好きならcore.autocrlf=inputのどちらかです。どちらの場合も、あなたのGitリポジトリはLFのみを持ち、それが正しいものです。 core.autocrlf=falseの唯一の議論は、自動ヒューリスティックが誤ってバイナリをテキストとして検出する可能性があり、それからあなたのタイルが破損するということでした。そのため、不可逆的な変更が発生した場合にユーザーに警告するためにcore.safecrlfオプションが導入されました。実際、元に戻すことができない変更には2つの可能性があります - テキストファイル内での行末の混在、この正規化が望ましいので、この警告は無視できます。それから、このファイルがバイナリであることをGitに伝えるために属性を使う必要があります。

上の段落はもともとgmane.orgのスレッドから引き出されたものですが、それ以降は停止しています。

80
Cory

に代わる2つの方法は、混在環境(Microsoft + Linux + Mac)での行末について一貫性のあるになることです。

A.全リポジトリ設定ごとのグローバル

1) をすべて1つの形式に変換する

find . -type f -not -path "./.git/*" -exec dos2unix {} \;
git commit -a -m 'dos2unix conversion'

2)Linux/UNIXの場合はcore.autocrlfinputに、MS Windowsの場合はtrueに設定します(リポジトリまたはグローバル)

git config --global core.autocrlf input

3)(オプション)反転改行変換によって同じファイルが生成される場合は、ガード比較を追加するためにcore.safecrlftrue(停止)またはwarn(sing :)に設定

git config --global core.safecrlf true


B.またはリポジトリ設定ごとに

1) をすべて1つの形式に変換する

find . -type f -not -path "./.git/*" -exec dos2unix {} \;
git commit -a -m 'dos2unix conversion'

2).gitattributesファイルをあなたのリポジトリに追加してください

echo "* text=auto" > .gitattributes
git add .gitattributes
git commit -m 'adding .gitattributes for unified line-ending'

あなたのバイナリファイルについて心配しないでください - Gitはそれらについて十分に賢くあるべきです。


safecrlf/autocrlf変数についての詳細

57
lukmdo

core.autocrlf設定オプションをtrueに設定してみてください。 core.safecrlfオプションも見てください。

実際には、core.safecrlfがすでにリポジトリに設定されているように思えます。

これがcore.autocrlfの現在の設定に当てはまらない場合、gitはファイルを拒否します

その場合は、テキストエディタが常に行末を使用するように設定されていることを確認してください。テキストファイルにLFとCRLFの行末が混在していると、問題が発生する可能性があります。

最後に、Windowsで単に "あなたが与えたものを使用する"こととLFで終わる行を使用することを推奨することはそれが解決する以上の問題を引き起こすだろうと私は感じます。 Gitは賢明な方法で行末を処理しようとする上記のオプションを持っているので、それらを使うのは意味があります。

10
Greg Hewgill

core.autocrlf=falseを使用すると、自分の Visual Studio 2010 プロジェクトでチェックアウトした直後に、すべてのファイルが更新済みとしてマークされなくなりました。開発チームの他の2人のメンバーもWindowsシステムを使用しているため、混在環境は機能しませんでしたが、リポジトリに付属のデフォルト設定では、クローン作成直後にすべてのファイルが常に更新済みとしてマークされました。

一番下の行は、あなたの環境でどのCRLF設定が機能するのかを見つけることだと思います。特に私たちのLinuxマシン上の他の多くのリポジトリではautocrlf = trueの設定がより良い結果を生み出しています。

20年以上経った今でも、OS間の行末の相違を扱っています…悲しいことです。

9
Lance Cleveland

これらは、WindowsVisual StudioユーザーがMacまたはLinuxユーザー。詳細な説明については、 gitattributesマニュアル を参照してください。

* text = auto

リポジトリの.gitattributesファイルに以下を追加します。

*   text=auto

これにより、LF行の末尾がリポジトリにあるすべてのファイルが正規化されます。

また、オペレーティングシステム(core.eol設定)に応じて、作業ツリー内のファイルは、UnixベースのシステムではLFに、WindowsシステムではCRLFに正規化されます。

これは、 Microsoft .NET リポジトリが使用する構成です。

例:

Hello\r\nWorld

リポジトリでは常に次のように正規化されます。

Hello\nWorld

チェックアウト時に、Windowsの作業ツリーは次のように変換されます。

Hello\r\nWorld

チェックアウト時に、Macの作業ツリーは次のようになります。

Hello\nWorld

注:レポジトリに正規化されていないファイルが既に含まれている場合、git statusは、次にファイルに変更を加えたときにこれらのファイルを完全に変更されたものとして表示します。詳細については、 行末を変更した後のリポジトリの更新 を参照してください。

core.autocrlf = true

text.gitattributesファイルで指定されていない場合、Gitはcore.autocrlf構成変数を使用して、ファイルを変換する必要があるかどうかを判断します。

Windowsユーザーの場合、git config --global core.autocrlf trueは次の理由で優れたオプションです。

  • ファイルはLF行の末尾に正規化されます追加時のみリポジトリに。リポジトリで正規化されていないファイルがある場合、この設定はそれらに影響しません。
  • すべてのテキストファイルは、作業ディレクトリでCRLF行末に変換されます。

このアプローチの問題は次のとおりです。

  • autocrlf = inputを使用するWindowsユーザーの場合、LFの行末が付いたファイルの束が表示されます。コミットは引き続きLF行末で正規化されるため、チームの他のメンバーにとっては危険ではありません。
  • あなたがcore.autocrlf = falseを使用するWindowsユーザーの場合、LFの行末でファイルの束が表示され、CRLFの行末でファイルをリポジトリに導入できます。
  • ほとんどのMacユーザーはautocrlf = inputを使用し、おそらくcore.autocrlf = falseを使用するWindowsユーザーから、CRLFで終わるファイルを取得する場合があります。
7
kiewic

これは単なる回避策の解決策です。

通常は、gitに同梱されているソリューションを使用してください。ほとんどの場合、これらはうまく機能します。 。gitattributesを設定して、WindowsおよびUnixベースのシステムで開発を共有する場合は、LFを強制してください。

私の場合、10人以上のプログラマーがWindowsでプロジェクトを開発していました。このプロジェクトはCRLFでチェックインされていてLFに強制するオプションはありませんでした

LFフォーマットに影響を与えずに、いくつかの設定は私のマシンで内部的に書かれています。そのため、小さなファイルを変更するたびに、一部のファイルがグローバルにLFに変更されました。

私の解決策:

Windows-Machines:すべてをそのままにします。何も気にしないでください。あなたはデフォルトのwindows 'lone wolf'開発者であり、次のように扱わなければならないからです。「広い世界に他のシステムはありませんね」

Unixマシン

  1. 以下の行をconfigの[alias]セクションに追加してください。このコマンドはすべての変更された(すなわち、変更された/新しい)ファイルを一覧表示します。

    lc = "!f() { git status --porcelain \
                 | egrep -r \"^(\?| ).\*\\(.[a-zA-Z])*\" \
                 | cut -c 4- ; }; f "
    
  2. これらすべての変更されたファイルをdos形式に変換します。

    unix2dos $(git lc)
    
  3. オプションで...

    1. この処理を自動化するために、このアクション用にgit フック を作成してください。

    2. Paramsを使用してそれをインクルードし、特定のファイル名だけに一致するようにgrep関数を修正します。例えば:

      ... | egrep -r "^(\?| ).*\.(txt|conf)" | ...
      
    3. 追加のショートカットを使用して、さらに便利にしてください。

      c2dos = "!f() { unix2dos $(git lc) ; }; f "
      

      ...そして変換したものを打ち込んで発射する

      git c2dos
      
4
John Rumpel