GitのWindows/Linuxの行末の問題に悩まされています。 GitHub、MSysGit、およびその他のソースを介して、Linuxスタイルの行末を使用するようにローカルリポジトリを設定し、core.autocrlf
をtrue
に設定することが最善の解決策であると思われます。残念ながら、私はこれを十分に早く行わなかったため、変更をプルするたびに行末が中断されます。
私は答えを見つけたと思った ここ しかし、私はそれを私のために働かせることができない。私のLinuxコマンドラインの知識はせいぜい限られているので、「xargs fromdos」行が彼のスクリプトで何をするのかさえわかりません。そのようなファイルやディレクトリが存在しないというメッセージが表示され続け、既存のディレクトリを指すように管理しようとすると、アクセス許可がないことがわかります。
これをWindows上のMSysGitで、Mac OS Xターミナル経由で試しました。
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
これは、2018年1月にリリースされたgit v2.16.0で追加された新しい--renormalize
フラグを活用します。古いバージョンの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"
これを修正する最も簡単な方法は、すべての行末を修正する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 .
行末を処理するための私の手順は次のとおりです(多くのリポジトリでバトルがテストされています)。
新しいレポジトリを作成する場合:
.gitattributes
および.gitignore
として、最初のコミットにREADME.md
を他の典型的なファイルとともに配置します既存のレポを扱う場合:
.gitattributes
を適宜作成/変更しますgit commit -a -m "Modified gitattributes"
git rm --cached -r . && git reset --hard && git commit -a -m 'Normalize CRLF' -n"
-n
(--no-verify
は事前コミットフックをスキップします)alias fixCRLF="..."
として定義するのに十分な頻度で行う必要があります.gitattributes
では、すべてのテキストファイルを明示的にLF EOLとして宣言します。これは一般に、WindowsツールはLFと互換性があるためですCRLFと互換性がありません(多くの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は多くのファイルを変更済みとしてマークします。
解決策は、偽のコミット(git add -A . && git commit -m 'fake commit'
)を実行してからgit rebase master
を実行することです。リベース後、偽のコミットはなくなります。
git filter-branch
を使用して、履歴全体のすべての行末を修正する方法を次に示します。 ^M
文字は、CTRL-V
+ CTRL-M
を使用して入力する必要があります。バイナリファイルを自動的にスキップするため、dos2unix
を使用してファイルを変換しました。
$ git filter-branch --tree-filter 'grep -IUrl "^M" | xargs -I {} dos2unix "{}"'
git status --short|grep "^ *M"|awk '{print $2}'|xargs fromdos
説明:
git status --short
これにより、gitが認識している各行が表示されます。 gitの制御下にないファイルは、行の先頭に「?」でマークされます。変更されたファイルにはMのマークが付けられます。
grep "^ *M"
これにより、変更されたファイルのみが除外されます。
awk '{print $2}'
これは、マーカーなしでファイル名のみを表示します。
xargs fromdos
これは、前のコマンドからファイル名を取得し、ユーティリティ「fromdos」を介して実行して、行末を変換します。
"| xargs fromdos"は、標準入力(ファイルfind
が検出)から読み取り、コマンドfromdos
の引数として使用します。これは、行末を変換します。 (これらの環境ではfromdosが標準ですか?dos2unixに慣れています)。 xargsの使用を避けることができることに注意してください(引数リストがxargsには長すぎるほど十分なファイルがある場合に特に便利です)。
find <path, tests...> -exec fromdos '{}' \;
または
find <path, tests...> | while read file; do fromdos $file; done
エラーメッセージについて完全に確信はありません。このメソッドのテストに成功しました。各プログラムはどのプログラムを作成していますか?どのファイル/ディレクトリにアクセス許可がありませんか?ただし、これが何であるかを推測するのは簡単です。
スクリプトの「ファイルが見つかりません」エラーを取得する簡単な方法の1つは、相対パスを使用することです-絶対パスを使用します。同様に、スクリプトを実行可能にしないと(chmod + x)アクセス許可エラーが発生する可能性があります。
コメントを追加してください
わかりました... cygwinではfromdosを簡単に使用できません。変更されたファイルへのパスにスペースがあると、awk substebが顔に吹き飛ばされます(私たちは持っていました)。
git status --short | grep "^ *M" | sed 's/^ *M//' | xargs -n 1 dos2unix
このソリューションの大部分を@lloydに称賛