git repoと作業コピーでLF eolを強制する


170

githubでホストされているgitリポジトリがあります。ファイルの多くは当初Windowsで開発されたもので、行末についてはあまり注意していませんでした。最初のコミットを実行したとき、正しい行末を強制するためのgit設定もありませんでした。結局のところ、githubリポジトリにCRLF行で終わるファイルがいくつかあるということです。

現在、Linuxで部分的に開発を行っているので、行末をクリーンアップしたいと思います。ファイルがgithubのLFで正しく保存され、作業コピーにLFが含まれていることを確認するにはどうすればよいですか?

.gitattributes含むファイルを設定しましたtext eol=LF。あれは正しいですか?それをコミットしてプッシュしrmたら、ローカルリポジトリだけを作成してgithubから再クローンして目的の効果を得ることができますか?




それらのどちらも私が求めているものではありません。私は唯一の開発者であり、自分のすべてのマシンを同じようにセットアップする用意があります。私はいくつかのCRLFファイルが既にコミットされている既存のリポジトリと、異なるマシン上のいくつかのクローンを持っています。どこにでもLFが存在するように、リポジトリと各作業コピーを更新するにはどうすればよいですか?
Chowlett、2012

あなたが見ているこの Githubのガイドを?
アンディ

回答:


237

リポジトリにあるファイルに関する情報(純粋なソースコード、画像、実行可能ファイルなど)がないと、質問に答えるのが少し難しいです:)

これに加えて、WindowsまたはLinuxで作業するかどうかに関係なく、テキストファイルの.gitリポジトリで行末がLFであることを確認したいので、作業ディレクトリの行末としてデフォルトでLFを使用することを検討します。 。確かに申し訳ありませんが...より安全です。

ただし、より良い代替手段があります。LinuxワークディレクトリのLF行末、WindowsワークディレクトリのCRLF行末、およびリポジトリのLF行末のメリットがあります。

あなたが部分的にLinuxとWindowsで作業しているとして、確認してくださいcore.eolに設定されているnativecore.autocrlfに設定されていますtrue

次に、.gitattributesファイルの内容を次のように置き換えます

* text=auto

これにより、コミットおよびチェックアウト時に、Gitが自動行末変換を処理します。バイナリファイルは変更されません。テキストファイルとして検出されたファイルは、行末がオンザフライで変換されます。

ただし、リポジトリのコンテンツがわかっている場合は、Gitに手を貸して、バイナリファイルからテキストファイルを検出する手助けをしてください。

Cベースの画像処理プロジェクトで作業している場合、.gitattributesファイルの内容を次のように置き換えます

* text=auto
*.txt text
*.c text
*.h text
*.jpg binary

これにより、拡張子がc、h、またはtxtのファイルがLFの行末でリポジトリに保存され、ネイティブの行末が作業ディレクトリに含まれるようになります。Jpegファイルは変更されません。他のすべては、上記のように同じオートマジックフィルタリングの恩恵を受けます。

これらすべての内部の詳細をより深く理解するために、ギスババーのティム・クレムによるこの非常に優れた投稿「Mind the your end of your line」に飛び込むことをお勧めします。

実際の例として、ファイルへの変更が示されているこのコミットを確認することもでき.gitattributesます。

次のコメントを考慮して回答を更新してください

私のLinux環境は実際にはWindowsディレクトリを共有するVirtualBoxであるため、実際にはWindowsディレクトリにCRLFを入れたくない

理にかなっています。説明をありがとう。この特定のコンテキストでは、.gitattributesファイルだけでは十分ではありません。

リポジトリに対して次のコマンドを実行します

$ git config core.eol lf
$ git config core.autocrlf input

リポジトリはLinuxとWindows環境の間で共有されるため、これにより両方の環境のローカル構成ファイルが更新されます。core.eolテキストファイルがチェックアウト時にLFで終わることを確認します。core.autocrlf保証されます可能性(例えば、操作を貼り付け/コピー起因する)テキストファイルにCRLFをリポジトリにLFに変換されます。

オプションで、次のようなものを含むファイルを作成することにより、Git テキストファイルとは何かを区別できるようにすることができ.gitattributesます。

# Autodetect text files
* text=auto

# ...Unless the name matches the following
# overriding patterns

# Definitively text files 
*.txt text
*.c text
*.h text

# Ensure those won't be messed up with
*.jpg binary
*.data binary

.gitattributesファイルを作成する場合は、コミットします。

最後に、「コミットするものgit status何もない(作業ディレクトリがクリーン)」と記載されていることを確認してから、次の操作を実行します。

$ git checkout-index --force --all

これにより、設定の変更と.gitattributesファイルを考慮に入れて、作業ディレクトリにファイルが再作成され、テキストファイルで見落とされている可能性のあるCRLFが置き換えられます。

これが完了すると、作業ディレクトリ内のすべてのテキストファイルはLFで終了しgit status、workdirはクリーンであると見なされます。


34
私のLinux環境は実際にはWindowsディレクトリを共有するVirtualBoxなので、実際にはWindowsディレクトリにCRLFを入れたくありません。Notepad ++などはWindowsではLFのみを処理できますが、viCRLFには不満があります。私はちょうどので、それはそれを変更したいんcore.autocrlfですfalse(またはinput)?
Chowlett

5
すばらしい答えです。この設定を使用する他の人への簡単なメモ: "* text = auto"という行は.gitattributesファイルの最初の行にして、後続の行でその設定を上書きできるようにする必要があります。
アリパトリック

9
@CMCDragonkaiシェルによっては、git checkout-index --force --allより適切に動作する場合があります。2番目のポイントは、元の質問に関するトピックから少し外れているように見えます。専用の質問をしてみませんか?
nulltoken 2013年

8
LinuxとWindowsの間で作業コピーを共有するケースを.gitattributesが処理できない理由がわかりません。我々は設定できませんtexteol=lfを経由してあなたの答えで説明したのと同じ結果を達成するためにcore.eolしてcore.autocrlf
DanielSank 2014

10
git checkout-index --force --all私には何もしません。機能しているのは、この問題に対処するためのGitHub命令のコマンドリストです
Roman Starkov 16

127

git 2.10(2016年9月3日リリース)以降では、各テキストファイルを個別に列挙する必要はありません。Git 2.10は、text = autoとeol = lfの動作を修正しましたソース

.gitattributes gitリポジトリのルートにあるファイル:

* text=auto eol=lf

追加してコミットします。

その後、次の手順を実行すると、すべてのファイルが正規化されます。

git rm --cached -r .  # Remove every file from git's index.
git reset --hard      # Rewrite git's index to pick up all the new line endings.

出典:kenorbによって回答


7
Git 2.10は2016
。– 2017年

私はこれを実行し、すべての非テキストファイル
Anthony

特定のファイルにバイナリモードを明示的に設定できます。-一部のファイルで自動検出が(まだ?!)壊れているのはなぜですか
koppor

これは受け入れられる答えになるはずです。
CletusW

25

すべてのテキストファイルの改行を強制的にLFに.gitattributesするには、次の行を使用してリポジトリの最上位にファイルを作成します(必要に応じて変更します)。

# Ensure all C and PHP files use LF.
*.c         eol=lf
*.php       eol=lf

これにより、Gitがテキストファイルであると見なすすべてのファイルがLF、リポジトリ内で正規化された()行末を持っていることが保証されます(通常core.eol、デフォルトでは、どちらがデフォルトの設定になっていますか)。

新しい属性設定に基づいて、CRLFを含むテキストファイルはすべてGitで正規化する必要があります。これが自動的に行われない場合は、行末を変更した後で手動でリポジトリを更新できるので、次の手順で作業ディレクトリを再スキャンしてコミットできます(作業ディレクトリをクリーンにしてください)。

$ echo "* text=auto" >> .gitattributes
$ rm .git/index     # Remove the index to force Git to
$ git reset         # re-scan the working directory
$ git status        # Show files that will be normalized
$ git add -u
$ git add .gitattributes
$ git commit -m "Introduce end-of-line normalization"

またはGitHubドキュメントに従って:

git add . -u
git commit -m "Saving files before refreshing line endings"
git rm --cached -r . # Remove every file from Git's index.
git reset --hard # Rewrite the Git index to pick up all the new line endings.
git add . # Add all your changed files back, and prepare them for a commit.
git commit -m "Normalize all the line endings" # Commit the changes to your repository.

参照:@Charles Bailey post

さらに、テキストとして扱われないようにファイルを除外したい場合は、それらのテキスト属性を設定解除します。例えば、

manual.pdf      -text

または、明示的にバイナリとしてマークします。

# Denote all files that are truly binary and should not be modified.
*.png binary
*.jpg binary

より高度なgit正規化ファイルを確認するには.gitattributesDrupalコアで確認してください。

# Drupal git normalization
# @see https://www.kernel.org/pub/software/scm/git/docs/gitattributes.html
# @see https://www.drupal.org/node/1542048

# Normally these settings would be done with macro attributes for improved
# readability and easier maintenance. However macros can only be defined at the
# repository root directory. Drupal avoids making any assumptions about where it
# is installed.

# Define text file attributes.
# - Treat them as text.
# - Ensure no CRLF line-endings, neither on checkout nor on checkin.
# - Detect whitespace errors.
#   - Exposed by default in `git diff --color` on the CLI.
#   - Validate with `git diff --check`.
#   - Deny applying with `git apply --whitespace=error-all`.
#   - Fix automatically with `git apply --whitespace=fix`.

*.config  text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2
*.css     text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2
*.dist    text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2
*.engine  text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 diff=php
*.html    text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 diff=html
*.inc     text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 diff=php
*.install text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 diff=php
*.js      text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2
*.json    text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2
*.lock    text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2
*.map     text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2
*.md      text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2
*.module  text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 diff=php
*.php     text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 diff=php
*.po      text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2
*.profile text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 diff=php
*.script  text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2
*.sh      text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 diff=php
*.sql     text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2
*.svg     text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2
*.theme   text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 diff=php
*.twig    text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2
*.txt     text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2
*.xml     text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2
*.yml     text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2

# Define binary file attributes.
# - Do not treat them as text.
# - Include binary diff in patches instead of "binary files differ."
*.eot     -text diff
*.exe     -text diff
*.gif     -text diff
*.gz      -text diff
*.ico     -text diff
*.jpeg    -text diff
*.jpg     -text diff
*.otf     -text diff
*.phar    -text diff
*.png     -text diff
*.svgz    -text diff
*.ttf     -text diff
*.woff    -text diff
*.woff2   -text diff

以下も参照してください。


2
1. text=auto誤解を招く。text=autoeol一緒に使用することはできません。設定eolすると、テキストファイルの自動検出が無効になります。このため、これらのファイルタイプをすべて指定する必要があります。autoが有効になっている場合、そのすべては必要ありません。2. textとは必要ありませんeol=lfeol=lf効果的に設定しますtext
Ben

2
2番目の@Benの発言、この構成は現在間違っており、すべてのバイナリファイルを明示的にマークしないと危険です。
マイケルR

1
* text=auto eol=lf最初のtext=autoはによってオーバーライドされることを読みましたeol=lf。この機能はどこで見つけましたか?ここに私のソースです:stackoverflow.com/questions/29435156/...
CMCDragonkai

除去し* text=auto eol=lf、それがされたので、実施例から除去同様のDrupalから。コメントも削除することを検討してください。
ケノーブ2016

4
@Benが言ったことはもはや真実ではなく、それは常にバグであり、意図された動作ではなかったことに注意することが重要です。
Semmel
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.