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

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

Возможно я задаю не тот вопрос... но:

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

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

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

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

Обновить:

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

12 ответов

Решение

Обновление 2013:

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

git merge -s рекурсивный -Xignore-space-at-eol

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

  • Fab V. упоминает ниже:
    git merge master -s рекурсивный -X перенормировать
    
    

jakub.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?
Слияния, где эта функциональность имеет значение.
Какова семантика автоматического разрешения слияния с этими действующими параметрами - используются ли они только для обнаружения переименования, или мы, например, не помечаем конфликтами только изменения пробелов? И если мы не делаем, какую версию мы принимаем автоматически?

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

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

Общая идея, когда дело доходит до 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=$1
base=$2
remote=$3
result=$4

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 config команды:

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 (примечание: команда dos2unix происходит отсюда и используется для имитации стиля Unix eol. Эта команда была скопирована в каталог, упомянутый в начале этого ответа.):

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):

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

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

Я искал тот же ответ, и я узнал это

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

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

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

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

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

git config merge.renormalize true

После прочтения /questions/36786287/vozmozhno-li-dlya-git-merge-ignorirovat-razlichiya-v-kontse-stroki/36786306#36786306 и /questions/36786287/vozmozhno-li-dlya-git-merge-ignorirovat-razlichiya-v-kontse-stroki/36786309#36786309

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

git merge master -s recursive -X renormalize

Как и в этом ответе: /questions/10544358/git-merge-i-ispravlenie-smeshannyih-probelov-i-vkladok-s-dvumya-vetvyami/10544375#10544375

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

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

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

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

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

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

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

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

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

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

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

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

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

>sfk remcr . .py

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

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

Я наконец решил свою версию этой проблемы. Я пытался получить обновления из вышестоящего репозитория, но у моего текущего были проблемы, связанные с 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 каталог) в другой каталог, создайте в нем хранилище, затем добавьте файлы и зафиксируйте их (должно быть в главной ветке в новом хранилище).
  2. скопировать файлы из второго проекта в ту же папку, но другую ветку, например dev (git checkout -b dev), зафиксируйте файлы в этой ветке и запустите (если первый проект находится в master): git diff master..dev --names-only видеть только имена измененных файлов
Другие вопросы по тегам