Gitステータスは行末を無視する/同一のファイル/ WindowsとLinux環境/ Dropbox / mled


112

どうやって作るの?

gitステータス

行末の違いを無視しますか?

背景情報:

私はランダムにWindowsとLinuxを使用してプロジェクトに取り組んでいます。プロジェクトはDropboxにあります。

私はgit diffに行末を無視させる方法について多くを見つけました。meldを使用しているため、git diffは各ファイルのmeldを開きます。そしてmeldは「同一ファイル」と言います。

どうすればこれを回避できますか。Gitは変更されたファイルのmeldのみを開く必要があります。また、ファイルの末尾のみが異なる場合、git statusはファイルが変更されたと報告しないようにする必要があります。

編集:原因:

これは、Windowsでのこの設定が原因で発生しました

core.autocrlf true

Linuxで作業コピーをチェックアウトし、Windowsではcore.autocrlfをfalseに設定しました。

git statusに別の新しい行を無視させる方法を知っておくとなお良いでしょう。


3
異なるプラットフォームでDropboxを使用してファイルを共有している場合、すべてのファイルをバイナリとして扱うようにgitに明示的に指示しない限り、これが発生します。適切な解決策は、gitリポジトリにDropboxを使用しないことです
Petesh

気にしてください:stackoverflow.com/questions/2825428/…-これは多少役立つかもしれません
Petesh

Dropboxでうまく機能する方法を見つけました:core.autocrlfをfalseに設定して
Thorsten Niehues

3
AFAIKがファイルをバイナリとして扱うようにgitに指示することには、ファイルの差分方法を変更するという副作用もあります。適切な解決策は、行末を無視するようにgitに指示することです。一番嫌いなことの2つ:行末の問題と、人々がリポジトリを設定する方法についての不要な
ぎこち

うわー、この問題core.autocrlfがWindowsの根本的な原因であるだけでなく、Linuxの問題も解決するのにしばらく時間がかかりました。問題は、autocrlfWindowsでグローバルであり、リポジトリにその設定がないことです.git/config。ローカルで実行することによりgit config core.autocrlf true、Windowsでクローンを作成したがLinuxでアクセスしたNTFS作業コピーの誤った変更を取り除きました。(現在、シンボリックリンクでの疑似変更のみがあります-NTFSシンボリックリンクはfuseblkマウントで機能しますが、Gitはそれらが変更されたと見なします...)
Tomasz Gandor

回答:


103

次のようにcore.autocrlf値を設定してみてください:

git config --global core.autocrlf true

6
@ThorstenNiehues私はいくつかの作業プロジェクトでその設定を使用します。仕事ではWindowsを、自宅ではMacとLinuxを使用する必要があります。この前に私はあなたと同じ問題を抱えていました、その後、設定はすべて問題ありませんでした。
ササŠijak

1
WindowsでのチェックアウトにはLinuxでのみ\ r \ n行末があるため、これは奇妙です\ n Dropbox(または同様のもの)に両方の作業コピーがありますか?
Thorsten Niehues 2013

1
@ThorstenNiehuesいいえ、gitリポジトリはgithubにあります。ええと、おそらくdropboxがファイルを同期するときに行末がどういうわけかねじ込まれているのでしょうか gitにdropboxを使用するのは奇妙に思えます。bitbucket(無料のプライベートリポジトリがあります)を使用してみてください。1つの小さなリポジトリを作成し、いくつかの小さなテキストファイルを使用して2台のマシンでテストします。
ササŠijak

1
1.作業コピーとローカルリポジトリはDropboxにあります(パブリックリポジトリは必要ありません)。これがおそらく違います
Thorsten Niehues

3
Windowsの場合:core.autocrlf trueCygWinの設定です。core.safecrlf falsegit bashまたはmingwで動作する設定です
DrumM

43

代わりに、次の設定で.gitattributesを使用します。

# Ignore all differences in line endings
*        -crlf

.gitattributesは、グローバル.gitconfigと同じディレクトリにあります。.gitattributesが存在しない場合は、そのディレクトリに追加します。.gitattributesを追加または変更した後、既存のファイルに変更を正常に適用するには、リポジトリをハードリセットする必要があります。


それはあるストリームで私にとってはうまくいきましたが、同じプロジェクトの別のストリームで作成しようとしたときでも、改行の違いを示しています。
フェルナンドム2016

1
@pfernandom、プロジェクトに複数の.gitattributesがある可能性はありますか?最初に最も「ローカルな」バージョンを確認するため、ファイルがあるローカルディレクトリにある場合は、プロジェクト全体のバージョンよりもそのバージョンを使用します。
Trashman、2016

-crlfの前に8つのスペースが必要ですか?
Igonato 2017

重要ではない
トラッシュマン2017

これは、の行末を単に無視するだけではありませんgit status。実際には、ファイルがリポジトリにチェックインされる方法が変更されます。ref:git-scm.com/docs/gitattributes#_code_text_code
Vince

30

OPはマルチOSソリューションの必要性に言及しているため、この回答は適切であると思われます。このGithub ヘルプ記事では、OSを越えて行末を処理するための利用可能なアプローチについて詳しく説明しています。クロスOSラインエンディングを管理するためのグローバルなアプローチとリポジトリごとのアプローチがあります。

グローバルな取り組み

LinuxまたはOS XでGit行末処理を構成します。

git config --global core.autocrlf input

WindowsでGitの行末処理を構成します。

git config --global core.autocrlf true

レポごとのアプローチ:

リポジトリのルートで、.gitattributesファイルを作成し、プロジェクトファイルの行末設定を次の形式で一度に1行ずつ定義します。path_regex line-ending-settingsここline-ending-settingsで、は次のいずれかです。

  • テキスト
  • バイナリー(Gitが行末を変更してはならないファイル)

text値が一致するファイルのための行末を処理する方法にGitの指示にさらに構成することができます。

  • text -行末をOSネイティブの行末に変更します。
  • text eol=crlf-行末CRLFをチェックアウト時にに変換します。
  • text eol=lf-行末LFをチェックアウト時にに変換します。
  • text=auto -行ハンドルをGitの裁量に任せる適切なデフォルト。

サンプルの.gitattributesファイルの内容は次のとおりです。

# Set the default behavior for all files.
* text=auto

# Normalized and converts to 
# native line endings on checkout.
*.c text
*.h text

# Convert to CRLF line endings on checkout.
*.sln text eol=crlf

# Convert to LF line endings on checkout.
*.sh text eol=lf

# Binary files.
*.png binary
*.jpg binary

ここで行末の設定を変更した後、リポジトリを更新する方法の詳細。Tldr:

Gitを使用してファイルをバックアップし、リポジトリ内のすべてのファイル(.gitディレクトリを除く)を削除してから、ファイルを一度に復元します。現在のファイルをGitに保存して、作業内容が失われないようにします。

git add . -u

git commit -m "Saving files before refreshing line endings"

インデックスを削除し、Gitに作業ディレクトリの再スキャンを強制します。

rm .git/index

Gitインデックスを書き換えて、すべての新しい行末を取得します。

git reset

再書き込みされ、正規化されたファイルを表示します。

場合によっては、これで十分です。他のユーザーは、次の追加手順を完了する必要がある場合があります。

git status

変更したファイルをすべて追加し、コミットの準備をします。これは、変更されたファイルがある場合は、それを検査するチャンスです。

git add -u

「警告:ファイル内のCRLFはLFに置き換えられます。」というメッセージがここに表示されても、完全に安全です。

.gitattributesファイルを書き換えます。

git add .gitattributes

変更をリポジトリにコミットします。

git commit -m "Normalize all the line endings"


18

Windowsオペレーティングシステムでのgitコマンドに関連する問題

$ git add --all

警告:LFは...でCRLFに置き換えられます

ファイルの元の行末は作業ディレクトリになります。

解決策

$ git config --global core.autocrlf false     
$ git add --all 

警告メッセージは表示されません。


これは、使用しているすべてのOS、つまりWindowsとLinuxで行う必要があります。各OSには独自のグローバル.git / configファイルがあるため、これらの設定を同様にする必要があります。これが@Thorstenに問題があった理由です。しかし、フラグをfalseではなくtrueに設定しました。
Emmanuel Mahuni

このソリューションはLinuxでも機能します(@SašaŠijakの答えは私には機能しませんでした)
juliocesar

4

行末の違いを無視するスクリプトを作成しました。

コミットリストに追加されておらず、変更されたファイルを表示します(行末の違いを無視した後)。引数「add」を追加して、これらのファイルをコミットに追加できます。

#!/usr/bin/perl

# Usage: ./gitdiff.pl [add]
#    add : add modified files to git

use warnings;
use strict;

my ($auto_add) = @ARGV;
if(!defined $auto_add) {
    $auto_add = "";
}

my @mods = `git status --porcelain 2>/dev/null | grep '^ M ' | cut -c4-`;
chomp(@mods);
for my $mod (@mods) {
    my $diff = `git diff -b $mod 2>/dev/null`;
    if($diff) {
        print $mod."\n";
        if($auto_add eq "add") {
            `git add $mod 2>/dev/null`;
        }
    }
}

ソースコード:https : //github.com/lepe/scripts/blob/master/gitdiff.pl

アップデート

  • evandro777による修正:ファイルのファイル名またはディレクトリにスペースがある場合

ありがとう!それが本当の違いを得ることができる唯一の方法です。印刷された3行で問題が発生し、次のエラーが表示されます
。sh

1
スクリプトの問題の修正:問題:ファイルのファイル名またはディレクトリにスペースがある場合、gitは ""を使用するため、スクリプトが壊れます。修正はこの行を変更することです:my @mods = git status --porcelain 2>/dev/null | grep '^ M ' | awk '{ print \$2 }'; これに:my @mods = git status --porcelain 2>/dev/null | grep '^ M ' | cut -c4-;
evandro777 2017

@ evandro777:ありがとう!答えとgitコードの両方を更新しました。
lepe 2017

3

私はWindowsとLinuxの両方を使用していますが、このソリューションcore.autocrlf trueは役に立ちませんでした。その後も何も変わりませんでしたgit checkout <filename>

だから私は代わりに回避策を使いますgit status-gitstatus.sh

#!/bin/bash

git status | grep modified | cut -d' ' -f 4 | while read x; do
 x1="$(git show HEAD:$x | md5sum | cut -d' ' -f 1 )"
 x2="$(cat $x | md5sum | cut -d' ' -f 1 )"

 if [ "$x1" != "$x2" ]; then
    echo "$x NOT IDENTICAL"
 fi
done

md5sumリポジトリでファイルとその兄弟を比較するだけです。

出力例:

$ ./gitstatus.sh
application/script.php NOT IDENTICAL
application/storage/logs/laravel.log NOT IDENTICAL

2
おそらくあなたは、変更空白の変更をエクセルをチェックするために、ファイルごとに「gitの差分-b」を使用することができます
イワン
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.