280

gitのWindows/Linuxの行末の問題に悩まされてきました。GitHub、MSysGit、およびその他のソースを介して、最善の解決策は、ローカルリポジトリをLinuxスタイルの行末を使用するように設定することですが、に設定core.autocrlfすることtrueです。残念ながら、私はこれを十分に早く実行しなかったので、変更をプルするたびに行末が中断されます。

ここで答えを見つけたと思ったのですが、うまくいきません。私のLinuxコマンドラインの知識はせいぜい限られているので、彼のスクリプトで「xargsfromdos」行が何をしているのかさえわかりません。そのようなファイルやディレクトリが存在しないというメッセージが表示され続けますが、既存のディレクトリを指すようにすると、権限がないというメッセージが表示されます。

私はこれをWindows上のMSysGitとMacOSXターミナル経由で試しました。

4

8 に答える 8

400

これを修正する最も簡単な方法は、すべての行末を修正する 1 つのコミットを作成することです。変更されたファイルがないと仮定すると、次のようにこれを行うことができます。

# From the root of your repository remove everything from the index
git rm --cached -r .

# Change the autocrlf setting of the repository (you may want 
#  to use true on windows):
git config core.autocrlf input

# Re-add all the deleted files to the index
# (You should get lots of messages like:
#   warning: CRLF will be replaced by LF in <file>.)
git diff --cached --name-only -z | xargs -0 git add

# Commit
git commit -m "Fixed crlf issue"

# If you're doing this on a Unix/Mac OSX clone then optionally remove
# the working tree and re-check everything out with the correct line endings.
git ls-files -z | xargs -0 rm
git checkout .
于 2009-10-02T19:03:20.847 に答える
197

gitattributesの git ドキュメントでは、プロジェクト内のすべての行末を「修正」または正規化するための別のアプローチがドキュメント化されています。その要点は次のとおりです。

$ echo "* text=auto" >.gitattributes
$ git add --renormalize .
$ git status        # Show files that will be normalized
$ git commit -m "Introduce end-of-line normalization"

正規化してはならないファイルが git ステータスに表示される場合は、git add -u を実行する前にテキスト属性の設定を解除してください。

manual.pdf -text

逆に、git が検出しないテキスト ファイルでは、正規化を手動で有効にすることができます。

weirdchars.txt text

--renormalizeこれは、 2018 年 1 月にリリースされた git v2.16.0 で追加された新しいフラグを活用します。以前のバージョンの 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"
于 2011-01-13T18:32:28.353 に答える
12

行末を処理するための私の手順は次のとおりです(多くのレポでテストされた戦い):

新しいリポジトリを作成する場合:

  • および.gitattributes他の典型的なファイルと一緒に最初のコミットを 入れます.gitignoreREADME.md

既存のレポを扱う場合:

  • .gitattributesそれに応じて作成/変更
  • git commit -a -m "Modified gitattributes"
  • git rm --cached -r . && git reset --hard && git commit -a -m 'Normalize CRLF' -n"
    • -n( --no-verifypre-commit フックをスキップすることです)
    • エイリアスとして定義するのに十分な頻度で行う必要がありますalias fixCRLF="..."
  • 前のコマンドを繰り返す
    • ええ、それはブードゥー教ですが、通常、コマンドを 2 回実行する必要があります。1 回目はいくつかのファイルを正規化し、2 回目はさらに多くのファイルを正規化します。通常、新しいコミットが作成されなくなるまで繰り返すのがおそらく最善です:)
  • 古いブランチ (正規化の直前) と新しいブランチの間を数回行ったり来たりします。ブランチを切り替えた後、git は再正規化が必要なさらに多くのファイルを見つけることがあります!

通常、Windows ツールは LF と互換性がありますが、Windows 以外のツールは CRLF と互換性がないため、すべて.gitattributesのテキスト ファイルを LF EOL を持つものとして明示的に宣言します(多くの nodejs コマンド ライン ツールでさえ LF を想定しているため、ファイルの EOL を変更できます)。

の内容.gitattributes

私の.gitattributes通常は次のようになります。

*.html eol=lf
*.js   eol=lf
*.json eol=lf
*.less eol=lf
*.md   eol=lf
*.svg  eol=lf
*.xml  eol=lf

現在のリポジトリで git によって追跡されている個別の拡張機能を確認するには、こちらを参照してください。

正規化後の問題

ただし、これが完了したら、もう 1 つの一般的な注意事項があります。

がすでにmaster最新で正規化されているとします。その後、 をチェックアウトしoutdated-branchます。多くの場合、そのブランチをチェックアウトした直後に、git は多くのファイルを変更済みとしてマークします。

解決策は、偽の commit( git add -A . && git commit -m 'fake commit') を実行してからgit rebase master. リベース後、偽のコミットはなくなるはずです。

于 2015-12-04T13:39:23.897 に答える
4

を使用して、履歴全体のすべての行末を修正する方法を次に示しますgit filter-branch。文字は+^Mを使用して入力する必要があります。これはバイナリファイルを自動的にスキップするため、以前はファイルを変換していました。CTRL-VCTRL-Mdos2unix

$ git filter-branch --tree-filter 'grep -IUrl "^M" | xargs -I {} dos2unix "{}"'
于 2015-04-02T20:26:18.427 に答える
4
git status --short|grep "^ *M"|awk '{print $2}'|xargs fromdos

説明:

  • git status --short

    これにより、git が認識している行と認識していない行が表示されます。git の制御下にないファイルは、行の先頭に「?」でマークされます。変更されたファイルには、M のマークが付けられます。

  • grep "^ *M"

    これにより、変更されたファイルのみが除外されます。

  • awk '{print $2}'

    これは、マーカーなしでファイル名のみを表示します。

  • xargs fromdos

    これは、前のコマンドからファイル名を取得し、ユーティリティ「fromdos」を介してそれらを実行して、行末を変換します。

于 2012-03-09T12:36:39.113 に答える
3

「| xargs fromdos」は、標準入力 (ファイルfindが検出) から読み取り、それを command の引数として使用してfromdos、行末を変換します。(これらの環境では fromdos は標準ですか? 私は dos2unix に慣れています)。xargs の使用を避けることができることに注意してください (特に、引数リストが xargs に対して長すぎる十分な数のファイルがある場合に役立ちます)。

find <path, tests...> -exec fromdos '{}' \;

また

find <path, tests...> | while read file; do fromdos $file; done

エラーメッセージについてはよくわかりません。この方法のテストに成功しました。それぞれどのようなプログラムを作成していますか? アクセス許可を持っていないファイル/ディレクトリはどれですか? ただし、これはあなたのそれが何であるかを推測するための刺し傷です:

スクリプトの「ファイルが見つかりません」エラーを発生させる簡単な方法の 1 つは、相対パスを使用することです。絶対パスを使用してください。同様に、スクリプトを実行可能 (chmod +x) にしていないと、パーミッション エラーが発生する可能性があります。

コメントを追加してください。問題解決のお手伝いをします!

于 2009-10-02T17:50:31.383 に答える
1

わかりました... cygwinではfromdosを簡単に利用できません.変更されたファイルへのパスにスペースがあると、そのawkサブステブが顔に爆発します(これは私たちが持っていたものです)。

git status --short | grep "^ *M" | sed 's/^ *M//' | xargs -n 1 dos2unix

このソリューションの大部分について@lloydに称賛を

于 2012-04-30T11:44:55.770 に答える
-3

他の回答が役に立たない場合は、次の手順に従ってください。

  1. Windows を使用している場合は、次のようにしますgit config --global core.autocrlf true。Unix を使用している場合は、git config core.autocrlf input
  2. 走るgit rm --cached -r .
  3. ファイルを削除する.gitattributes
  4. 走るgit add -A
  5. 走るgit reset --hard

次に、ローカルは今すぐきれいになるはずです。

于 2014-05-06T20:01:58.153 に答える