Возможно ли, чтобы git-merge игнорировал различия с окончанием строки?

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

возможно, я задаю неправильный вопрос ... но:

я попробовал uisng config.crlf input но все стало немного грязным и неконтролируемым, особенно когда я применил его после того.

во-первых, применение этой конфигурации после факта, похоже, не влияет на файлы, которые были зафиксированы в репозитории перед применением этой опции. Другое дело, что вдруг все совершается сейчас результатом является множество раздражающих предупреждающих сообщений о преобразовании CRLF в LF.

честно говоря, мне все равно, какой конец строки используется, я лично предпочитаю стиль Unix n, но все. Все, что меня волнует, это git merge чтобы быть немного умнее и игнорировать различия в окончаниях строк.

иногда у меня есть два одинаковых файла, но git будет отмечать их как находящиеся в конфликте (и конфликт-это весь file) просто потому, что они используют другой символ окончания строки.

обновление:

узнал, что git diff принимает --ignore-space-at-eol вариант, можно было бы позволить git merge использовать эту опцию?

12 ответов


обновление 2013 года:

более поздние версии git разрешают использование слияния со стратегией recursive стратегии опции (-X):

git merge -s recursive -Xignore-space-at-eol

но с помощью "-Xignore-space-change" возможность

  • Fab-V упоминает ниже:
    git merge master -s recursive -X renormalize
    
    

Якуб.g и комментарии что стратегии работают также с cherry-picking:

git cherry-pick abcd123456 --strategy=recursive --strategy-option=renormalize 

это работает намного лучше, чем ignore-all-space.


оригинальный ответ (май 2009)

патч для игнорирования стиля eol был предложен в июнь 2007 года, но это касается только git diff --ignore-space-at-eol, а не git merge.

в время, вопрос был askeed:

должны --ignore-space-at-eol такой вариант git-merge ?
Слияния, где эта функциональность имеет значение.
Какова семантика автоматического разрешения слияния с этими параметрами в действительности - они используются только для обнаружения переименования или мы, например, не конфликтуем с изменениями только пробелов ? А если нет, то какую версию мы принимаем автоматически ?

Хулио с Хамано был не совсем восторженные:

это, конечно, заманчиво, но я подозреваю, что это следует оставить на более поздние раунды.
Я подозреваю, что это введет концепцию двух разных видов различий, один из которых будет механически обработан (т. е. использовать в слиянии с "git-merge-recursive" и применять с "git-am"), И еще один, чтобы его осмотрели люди, чтобы понять.
Часто может быть полезно munge вход для последнего случая, даже если выход из сравнения munged вход файлы не могут быть легко использованы для механического применения.

общая идея, когда дело доходит до git merge, полагаться на сторонний инструмент слияния.

например, у меня есть setup DiffMerge чтобы быть инструментом для слияния Git, установите правил которые позволяют этому инструменту слияния игнорировать eol для определенного типа файлов.


настройка В Windows с помощью MSysGit1.6.3, либо для DOS или Git bash сеанс, с DiffMerge или KDiff3:

  • установите каталог в свой путь (здесь:c:\HOMEWARE\cmd).
  • добавить в этот каталог скрипт merge.sh (обертка для вашего любимого инструмента слияния)

merge.sh:

#!/bin/sh

# Passing the following parameters to mergetool:
#  local base remote merge_result

alocal=
base=
remote=
result=

if [ -f $base ]
then
    #"C:/Program Files/SourceGear/DiffMerge/DiffMerge.exe" "$alocal" "$base" "$remote" -m --result="$result" --title1="Mine" --title2="Merging to: $result" --title3="Theirs"

    # for merge respecting eol, KDiff3 is better than DiffMerge (which will always convert LF into CRLF)
    # KDiff3 will display eol choices (if Windows: CRLF, if Unix LF)
    "C:/Program Files/KDiff3/kdiff3.exe" -m "$base" "$alocal" "$remote" -o "$result"
else
    #there is not always a common ancestor: DiffMerge needing 3 files, BASE will be the result
    #"C:/Program Files/SourceGear/DiffMerge/DiffMerge.exe" "$alocal" "$result" "$remote" -m --result="$result" --title1="Mine" --title2="Merging to: $result" --title3="Theirs"

    # KDiff3 however does know how to merge based on 2 files (not just 3)
    "C:/Program Files/KDiff3/kdiff3.exe" -m "$base" "$remote" -o "$result"
fi
  • объявите обертку слияния для Git

команды конфигурации Git:

git config --global merge.tool diffmerge
git config --global mergetool.diffmerge.cmd "merge.sh \"$PWD/$LOCAL\" \"$PWD/$BASE\" \"$PWD/$REMOTE\" \"$PWD/$MERGED\"
git config --global mergetool.diffmerge.trustExitCode false
git config --global mergetool.diffmerge.keepBackup false
  • проверьте, что autoCRLF является false

в git config в системе уровень:

git config ---system core.autoCRLF=false
  • проверьте, что, когда две строки идентичны (но их символы eol), DiffMerge или KDiff3 будут игнорировать эти строки во время слияния.

DOS script (Примечание:команда dos2unix отсюда, и используется для имитации стиля EOL Unix. Эта команда была скопирована в каталог, упомянутый в начале этого ответа.):

C:\HOMEWARE\git\test>mkdir test_merge C:\HOMEWARE\git\test>cd test_merge C:\HOMEWARE\git\test\test_merge>git init C:\HOMEWARE\git\test\test_merge>echo a1 > a.txt & echo a2 >> a.txt C:\HOMEWARE\git\test\test_merge>git add a.txt C:\HOMEWARE\git\test\test_merge>git commit -m "a.txt, windows eol style" C:\HOMEWARE\git\test\test_merge>git checkout -b windows Switched to a new branch 'windows' C:\HOMEWARE\git\test\test_merge>echo a3 >> a.txt & echo a4 >> a.txt C:\HOMEWARE\git\test\test_merge>git add a.txt C:\HOMEWARE\git\test\test_merge>git commit -m "add two lines, windows eol style" C:\HOMEWARE\git\test\test_merge>git checkout master C:\HOMEWARE\git\test\test_merge>git checkout -b unix Switched to a new branch 'unix' C:\HOMEWARE\git\test\test_merge>echo au3 >> a.txt & echo au4 >> a.txt && echo au5 >> a.txt C:\HOMEWARE\git\test\test_merge>dos2unix a.txt Dos2Unix: Processing file a.txt ... C:\HOMEWARE\git\test\test_merge>git add a.txt C:\HOMEWARE\git\test\test_merge>git commit -m "add 3 lines, all file unix eol style" [unix c433a63] add 3 lines, all file unix eol style C:\HOMEWARE\git\test\test_merge>git merge windows Auto-merging a.txt CONFLICT (content): Merge conflict in a.txt Automatic merge failed; fix conflicts and then commit the result. C:\HOMEWARE\git\test\test_merge>git ls-files -u 100644 39b4c894078a02afb9b1dfeda6f1127c138e38df 1 a.txt 100644 28b3d018872c08b0696764118b76dd3d0b448fca 2 a.txt 100644 3994da66530b4df80189bb198dcfac9b8f2a7b33 3 a.txt C:\HOMEWARE\git\test\test_merge>git mergetool Merging the files: a.txt Normal merge conflict for 'a.txt': {local}: modified {remote}: modified Hit return to start merge resolution tool (diffmerge):

в этот момент (нажав " return"), Откроется DiffMerge или KDiff3, и вы сами увидите, какие строки фактически объединены, а какие игнорируются.

предупреждение: файл результатов всегда будет находиться в режиме Windows eol (CRLF) с DiffMerge...
KDiff3 предлагает экономить так или иначе.


Я ищу тот же ответ, и я узнал этой

объединение ветвей с различными атрибутами проверки / проверки

Если вы добавили атрибуты в файл, которые вызывают канонические формат репозитория для изменения этого файла, например добавление очистить / смазать фильтр или текстовые/eol / ident атрибуты, слияние чего-либо где атрибут не на месте обычно вызывает слияние рознь.

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

до тех пор, пока "smudge→clean" приводит к тому же результату, что и " clean" даже на файлах, которые уже смазанный, эта стратегия будет автоматически разрешить все фильтра конфликтов. Фильтры, которые делают не действовать таким образом может вызвать дополнительные конфликты слияния, которые должны быть разрешено вручную.

поэтому запуск этой команды в любом репозитории сделает трюк:

git config merge.renormalize true

после чтения https://stackoverflow.com/a/12194759/1441706 и https://stackoverflow.com/a/14195253/1441706

для меня эта команда сработала отлично:

git merge master -s recursive -X renormalize

как в этом ответе:https://stackoverflow.com/a/5262473/943928

вы можете попробовать:git merge -s recursive -Xignore-space-at-eol


Я оставил все по умолчанию (т. е. autocrlf=true), нажмите все файлы (найти . - exec touch {} \;), пусть git видит их как "измененные" и фиксирует их обратно, и покончить с этим. В противном случае вас всегда будут беспокоить раздражающие сообщения или удивительные различия, или вам придется отключить все функции пробелов git.

вы потеряете информацию о вине, но лучше сделать это раньше, чем позже:)


" git merge-Xrenormalize " работает как шарм.


не похоже, что это можно сделать напрямую, но этот пост предлагает работу.

http://osdir.com/ml/git/2009-02/msg02532.html


http://stahlforce.com/dev/index.php?tool=remcrlf

Я пробовал, но если после последней строки в вашем коде у вас еще не было CRLF, он добавляет сам по себе LF, и файл выглядит измененным в git. Кроме этого, это работает.


мне кажется, что лучший способ-нормализовать окончания строк на обеих ветвях (и фиксации) перед их объединением.

я погуглил "конвертировать crlf в lf" и нашел это в качестве первых результатов:
http://stahlforce.com/dev/index.php?tool=remcrlf

Я загрузил его и использовал, кажется, хороший инструмент.

>sfk remcr . .py

обязательно укажите каталог и тип файла (например .py) в противном случае он может попытаться возиться с содержимым из


AFAICT, (я не пробовал) вы могли бы использовать git diff чтобы сравнить ветвь, которую вы хотите объединить с общим предком, затем примените результаты с git apply. Обе команды имеют --ignore-whitespace опции для игнорирования ошибок окончания строки и пробелов.

к сожалению, если патч не применяется, чисто, вся операция отменяется. Вы не можете исправить конфликты слияния. Есть --reject возможность оставить неуловимые куски в .rej файлы, которые помогают, но не то же самое, что иметь конфликты слияния в один файл.


после прочтения разрешить конфликты слияния: принудительно перезаписать все файлы

Я, наконец, решил свою версию этой проблемы. Я пытался вытащить обновления из восходящего РЕПО, Но у моего текущего были проблемы с CRLF и не удалось объединить в результате. Следует отметить, что у меня не было никаких местных изменений, о которых я должен был беспокоиться. Следующие шаги решили мою проблему:

согласно инструкциям github по синхронизации вилок (https://help.github.com/articles/syncing-a-fork/):

  1. git fetch upstream

  2. git reset --hard upstream/master
    Мое ограниченное понимание git говорит мне, что это делает то, что я хочу ... перебазирования вилкой (без незафиксированных изменений), чтобы получить все изменения, внесенные в исходный код. Согласно странице источника, этот шаг обычно не требуется, но проблема CRLF сделала это необходимым.

  3. git merge upstream/master

  4. git push

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

лучшим способом было:

  1. копировать только файлы проекта (как правило, без .git directory) в другой каталог создайте в нем репозиторий, затем добавьте файлы и зафиксируйте их (должны быть на главной ветке в новом репозитории).
  2. копировать файлы из второго проекта в ту же папку, но другая ветвь, например dev (git checkout -b dev), фиксировать файлы в этой ветке и запускать (если первый проект находится в master): git diff master..dev --names-only видеть только имена измененных файлов