Кінець рядка ігнорує статус Git / однакові файли / середовище Windows та Linux / dropbox / mled


112

Як зробити

git статус

ігнорувати відмінності, що закінчуються рядком?

Довідкова інформація:

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

Я дізнався багато про те, як зробити git diff ігнорувати закінчення рядків. Оскільки я використовую meld git diff, відкривається meld для кожного файлу. І meld говорить "однаковий файл".

Тож як я цього уникаю. Git повинен відкривати meld лише для змінених файлів. І статус git не повинен повідомляти про файли як про змінені, якщо лише закінчення файлу відрізняється.

EDIT: Причина:

Це сталося через це налаштування в Windows

core.autocrlf вірно

Тому я перевірив робочу копію в Linux і встановив core.autocrlf false в Windows.

Було б ще приємно знати, як змусити статус git ігнорувати різні нові рядки.


3
Якщо ви ділитесь файлом за допомогою папки "папка" на різних платформах, це станеться, якщо ви прямо не скажете git трактувати всі файли як бінарні. Правильне рішення - не використовувати
дроп-бокс

зауважте: stackoverflow.com/questions/2825428/… - це може дещо допомогти
Petesh

Я дізнався, як це добре працює з Dropbox: встановивши core.autocrlf false
Thorsten Niehues

3
AFAIK, який говорить git, щоб розглядати файли як бінарні, також має побічний ефект від зміни способу, який він відрізняє від файлу. Правильне рішення - сказати git ігнорувати закінчення рядків. 2 моїх найменш улюблених речей: вирішення проблем із закінченням рядків та непотрібної
дивакуватості FUD

Нічого собі, мені знадобилося певний час, що для цієї проблеми core.autocrlfє першопричиною Windows, а також ліком у Linux. Проблема полягає в тому, що він autocrlfє глобальним у Windows, і репо не має цього налаштування .git/config. Запустивши локальну службу, git config core.autocrlf trueя позбувся хибних змін у своїй робочій копії NTFS, клонованій у Windows, але отримав доступ до Linux. ( В даний час є тільки паразитні зміни з симлінк - символьні посилання NTFS зробити роботу на fuseblk монтує, але Git бачить їх як модифіковані ...)
Томаш Gandor

Відповіді:


103

Спробуйте встановити значення core.autocrlf так:

git config --global core.autocrlf true

6
@ThorstenNiehues Я використовую цей параметр у деяких робочих проектах. На роботі я повинен використовувати Windows, вдома я використовую Mac та Linux. До цього у мене була така ж проблема, як у вас, після цього налаштування все було нормально.
Saša Šijak

1
Це дивно, тому що в касі Windows є \ r \ n закінчення рядка лише для Linux \ n Чи є у вас як робочі копії в Dropbox (або подібних)?
Торстен Niehues

1
@ThorstenNiehues Ні, сховище git знаходиться в github. Гм, може, Dropbox якось обертається кінцями рядків, коли він синхронізує файли? Дуже дивно використовувати Dropbox для git. Спробуйте використовувати bitbucket (у ньому є безкоштовні приватні сховища), просто зробіть одне невелике репо-тестування і протестуйте на своїх 2-х машинах кілька невеликих текстових файлів.
Saša Šijak

1
1. Робоча копія та локальне репо є в Dropbox (я не потребую публічного сховища), ймовірно, різниця
Thorsten Niehues

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 вам доведеться зробити жорсткий скидання сховища, щоб успішно застосувати зміни до існуючих файлів.


Він працював для мене в одному потоці, але коли я спробував створити його в іншому потоці для того ж проекту, він все ще показує відмінності від Newline.
pfernandom

1
@pfernandom, чи можливо у вас є кілька .gitattributes у вашому проекті? Він спочатку розгляне найбільш "локальну" версію, тому, якщо у вас є в локальному каталозі, де є файли, він буде використовувати цей варіант у вашому проекті.
Trashman

Чи потрібно мати 8 пробілів перед -crlf?
Ігонато

Не має значення
Trashman

Це більше, ніж просто ігнорувати закінчення рядків git status. Це фактично змінює спосіб перевірки файлів у сховищі. ref: git-scm.com/docs/gitattributes#_code_text_code
Vince

31

Ця відповідь здається актуальною, оскільки в ОП посилається на потребу в мульти ОС. У цій довідковій статті 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 - Розумний за замовчуванням, який залишає обробку рядків, на розсуд Гіта.

Ось вміст зразка .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"


18

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

$ git add --all

попередження: LF буде замінено CRLF у ...

Файл матиме оригінальні закінчення рядків у вашому робочому каталозі.

Роздільна здатність :

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

Ніяких попереджувальних повідомлень не з’являється.


ви повинні робити це у всіх ОС, які ви використовуєте, тобто: у Windows та Linux. Вимкніть кожну ОС, має свій глобальний .git / config файл, тому вам потрібно зробити ці налаштування простими. Ось чому у @Thorsten у вас виникли проблеми. Але я встановив прапор істинним, а не хибним.
Еммануель Махуні

Це рішення працює також у 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: Синтаксична помилка:
Невизначений

1
Виправлення проблеми із сценарієм: Проблема: Коли файл має простір у каталозі файлу ou, у git буде використано "", тому сценарій розривається. Виправлення полягає в тому, щоб змінити цей рядок: my @mods = git status --porcelain 2>/dev/null | grep '^ M ' | awk '{ print \$2 }'; до цього: мій @mods = git status --porcelain 2>/dev/null | grep '^ M ' | cut -c4-;
evandro777

@ evandro777: Дякую! Я оновив і відповідь, і код git.
lepe

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" для кожного файлу, щоб перевірити, чи не змінюються зміни в пробілі
Іван
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.