Статус Git игнорирует окончания строк / идентичные файлы / окна и среду Linux / dropbox / mled

113

Как мне сделать

git статус

игнорировать различия в конце строки?

Справочная информация:

Я случайно использую Windows и Linux для работы над проектом. Проект находится в Dropbox.

Я много узнал о том, как заставить git diff игнорировать окончания строк. Поскольку я использую meld, git diff открывает meld для каждого файла. И meld говорит "идентичный файл".

Итак, как мне этого избежать. Git должен открывать meld только для измененных файлов. И git status не должен сообщать о файлах как об измененных, если отличается только окончание файла.

РЕДАКТИРОВАТЬ: Причина:

Это произошло из-за этой настройки в Windows

core.autocrlf правда

Итак, я проверил рабочую копию в Linux и установил core.autocrlf false в Windows.

Было бы неплохо узнать, как заставить git status игнорировать разные новые строки.

Торстен Ниеуэс
источник
3
Если вы делитесь файлом с помощью Dropbox на разных платформах, это произойдет, если вы явно не укажете git обрабатывать все файлы как двоичные. Правильное решение - не использовать dropbox для репозиториев git
Питеш
имейте в виду: stackoverflow.com/questions/2825428/… - это может немного помочь
Питеш
Я узнал, как это хорошо работает с Dropbox: установив core.autocrlf false,
Торстен Ниеуэс
3
AFAIK, говорящий git рассматривать файлы как двоичные, также имеет побочный эффект, заключающийся в изменении способа сравнения файлов. Правильное решение - указать git игнорировать окончания строк. 2 из моих наименее любимых вещей: решение проблем с окончанием строки и ненужный язвительный FUD о том, как люди настраивают свои репозитории :)
ChrisM
Вау, мне потребовалось некоторое время, чтобы эта проблема core.autocrlfбыла основной причиной в Windows, но также и лекарством в Linux. Проблема в том, что autocrlfона глобальна в Windows, и в репо нет этой настройки .git/config. Запустив локальный компьютер, git config core.autocrlf trueя избавился от ложных изменений в моей рабочей копии NTFS, клонированной в Windows, но доступной в Linux. (теперь есть только ложные изменения с символическими ссылками - символические ссылки NTFS РАБОТАЮТ на креплениях fuseblk, но Git считает их модифицированными ...)
Томаш Гандор

Ответы:

105

Попробуйте установить значение core.autocrlf следующим образом:

git config --global core.autocrlf true
Саша Шияк
источник
7
@ThorstenNiehues Я использую эту настройку в каком-то рабочем проекте. На работе я должен использовать Windows, дома я использую Mac и Linux. До этого у меня была такая же проблема, как и у вас, после этой настройки все было нормально.
Saša Šijak
1
Это странно, потому что проверка в Windows имеет \ r \ n окончания строк только в Linux \ n Есть ли у вас обе рабочие копии в Dropbox (или аналогичном)?
Thorsten Niehues
1
@ThorstenNiehues Нет, репозиторий git находится на github. Хм, а может дропбокс как-то лажает с окончаниями строк при синхронизации файлов? Кажется странным использовать dropbox для git. Попробуйте использовать bitbucket (у него есть бесплатные частные репозитории), просто сделайте одно небольшое репо и протестируйте на своих двух машинах с небольшими текстовыми файлами.
Saša Šijak
1
1. Рабочая копия и локальное репо находятся в Dropbox (мне не нужен публичный репозиторий), в этом, вероятно, разница,
Торстен Ниеуэс
3
В Windows: core.autocrlf trueэто рабочий параметр CygWin. core.safecrlf falseэто рабочая настройка в git bash или mingw
DrumM
43

Вместо этого используйте .gitattributes со следующей настройкой:

# Ignore all differences in line endings
*        -crlf

.gitattributes будут находиться в том же каталоге, что и ваш глобальный .gitconfig. Если .gitattributes не существует, добавьте его в этот каталог. После добавления / изменения .gitattributes вам нужно будет выполнить полный сброс репозитория, чтобы успешно применить изменения к существующим файлам.

Мусорщик
источник
У меня это сработало в одном потоке, но когда я попытался создать его в другом потоке для того же проекта, он по-прежнему показывает различия новой строки.
pfernandom
1
@pfernandom, возможно, у вас есть несколько атрибутов .gitattributes в вашем проекте? Сначала он будет смотреть на самую «локальную» версию, поэтому, если у вас есть одна в локальном каталоге, где находятся файлы, он будет использовать ее поверх всего вашего проекта.
Trashman
Перед -crlf должно быть 8 пробелов?
Igonato
Не имеет значения
мусорщик
Это больше, чем просто игнорирование окончаний строк для git status. Фактически это меняет способ регистрации файлов в репозитории. ref: git-scm.com/docs/gitattributes#_code_text_code
Винс,
31

Этот ответ кажется актуальным, поскольку OP ссылается на необходимость решения для нескольких ОС. В этой статье справки Github подробно описаны доступные подходы к обработке окончаний строк в разных ОС. Существуют глобальные подходы и подходы для отдельных репо к управлению окончаниями строк между операционными системами.

Глобальный подход

Настройте обработку окончаний строк Git в Linux или OS X:

git config --global core.autocrlf input

Настройте обработку окончаний строк Git в Windows:

git config --global core.autocrlf true

Подход на основе репо:

В корне репозитория создайте .gitattributesфайл и определите параметры окончания строки для файлов проекта, по одной строке за раз в следующем формате: path_regex line-ending-settingsгде line-ending-settingsодно из следующих значений:

  • текст
  • двоичный (файлы, для которых Git не должен изменять окончания строк - это может привести к тому, что некоторые типы изображений, такие как PNG, не будут отображаться в браузере)

Это textзначение можно настроить дополнительно, чтобы указать Git, как обрабатывать окончания строк для совпадающих файлов:

  • text - Изменяет окончание строки на окончание строки ОС.
  • 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

Совершенно безопасно увидеть здесь множество сообщений, которые читают [s] «предупреждение: CRLF будет заменен на LF в файле».

Перепишите файл .gitattributes.

git add .gitattributes

Зафиксируйте изменения в своем репозитории.

git commit -m "Normalize all the line endings"

user4603841
источник
18

Проблема, связанная с командами git в операционной системе Windows:

$ git add --all

предупреждение: LF будет заменен на CRLF в ...

У файла будут исходные окончания строки в вашем рабочем каталоге.

Разрешение :

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

Никаких предупреждающих сообщений не появляется.

Winstonhong
источник
вы должны делать это во всех операционных системах, которые вы используете, то есть в Windows и Linux. Помните, что каждая ОС имеет свой собственный глобальный файл .git / config, поэтому вам нужно сделать эти настройки одинаковыми. Вот почему у @Thorsten возникли проблемы. Но я установил флаг в значение true вместо false.
Emmanuel Mahuni
Это решение работает также в Linux (ответ @ SašaŠijak у меня не работает)
juliocesar
4

Я создал скрипт, чтобы игнорировать различия в окончании строк:

Он отобразит файлы, которые не добавлены в список фиксации и были изменены (после игнорирования различий в окончании строк). Вы можете добавить аргумент «добавить», чтобы добавить эти файлы в коммит.

#!/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: Синтаксическая ошибка: незавершенная строка в кавычках
evandro777
1
Исправление проблемы скрипта: Проблема: когда файл имеет место в каталоге filename ou, 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 06
@ evandro777: Спасибо! Я обновил и ответ, и код git.
Лепе
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 diff -b" для каждого файла, чтобы проверить наличие изменений изменения пробелов Excel
Иван