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


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

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

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

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

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

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

обновление:

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

12 135

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 и комментарии что стратегии работают также с вишневым сбором:

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

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


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

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

в время, вопрос был задан:

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

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

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

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

например, у меня есть установка 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 является ложным

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

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

DOS скрипт (Примечание:команда 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 предлагает экономить так или иначе.

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

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

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

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

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

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

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. Я потратил пару часов на diffing проекты с различными окончаниями линий.

лучший способ быть:

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