Налаштування та використання Meld як диффузора та mergetool git


255

Хоча значна частина інформації в цьому питанні та відповіді доступна на StackOverflow , вона розповсюджується на багато сторінок та серед інших відповідей, які є помилковими чи оманливими. Мені знадобилося певний час, щоб зібрати разом все, що я хотів знати.

Існує багато різних програм, які можна використовувати як ваш git difftool та mergetool, і, звичайно, немає єдиної думки щодо того, який найкращий варіант (думки, вимоги та ОС будуть чітко відрізнятися).

Meld - популярний безкоштовний, відкритий і кросплатформенний вибір (UNIX / Linux, OSX, Windows), як показано у питанні StackOverflow. Який найкращий візуальний інструмент для злиття для Git? , у якій відповідь, що пропонує Meld, має більше 3-х разів голосів, як будь-який інший інструмент.

На мою відповідь нижче відповімо наступні 2 запитання:

  • Як налаштувати та використовувати Meld як диффузол git?
  • Як налаштувати та використовувати Meld як мій gget mergetool?

Примітка. Не потрібно використовувати ту саму програму, що і дифтеол і mergetool, різні програми можна встановити для обох.


Відповіді:


423

Як налаштувати та використовувати Meld як диффузол git?

git difftool відображає diff за допомогою програми diff графічного інтерфейсу (тобто Meld), а не відображення диференційного виходу у вашому терміналі.

Хоча ви можете встановити програму GUI у командному рядку, використовуючи -t <tool> / --tool=<tool>її, має сенс налаштувати її у своєму .gitconfigфайлі. [Примітка. Дивіться розділи про вимкнення цитат та шляхи до Windows внизу.]

# Add the following to your .gitconfig file.
[diff]
    tool = meld
[difftool]
    prompt = false
[difftool "meld"]
    cmd = meld "$LOCAL" "$REMOTE"

[Примітка: ці налаштування не змінять поведінку, git diffяка продовжуватиме працювати як завжди.]

Ви використовуєте git difftoolточно так само, як і ви git diff. напр

git difftool <COMMIT_HASH> file_name
git difftool <BRANCH_NAME> file_name
git difftool <COMMIT_HASH_1> <COMMIT_HASH_2> file_name

Якщо правильно налаштовано, відкриється вікно Meld, на якому відображатиметься diff за допомогою інтерфейсу GUI.

Порядок віконних панелей графічного інтерфейсу Meld можна керувати порядком $LOCALі $REMOTEв cmd, тобто, який файл відображається у лівій та який у правій області. Якщо ви хочете їх навпаки, просто обміняйте їх так:

    cmd = meld "$REMOTE" "$LOCAL"

Нарешті, prompt = falseрядок просто зупиняє git від того, щоб підказати вам, чи хочете ви запустити Meld чи ні, за замовчуванням git видасть підказку.


Як налаштувати та використовувати Meld як мій gget mergetool?

git mergetool дозволяє використовувати програму злиття GUI (тобто Meld) для вирішення конфліктів злиття, що виникли під час злиття.

Як і difftool, ви можете встановити програму GUI в командному рядку за допомогою, -t <tool> / --tool=<tool>але, як і раніше, має сенс налаштувати її у вашому .gitconfigфайлі. [Примітка. Дивіться розділи про вимкнення цитат та шляхи до Windows внизу.]

# Add the following to your .gitconfig file.
[merge]
    tool = meld
[mergetool "meld"]
    # Choose one of these 2 lines (not both!) explained below.
    cmd = meld "$LOCAL" "$MERGED" "$REMOTE" --output "$MERGED"
    cmd = meld "$LOCAL" "$BASE" "$REMOTE" --output "$MERGED"

Ви НЕ використовуєте git mergetoolдля здійснення фактичного злиття. Перед використанням git mergetoolви виконуєте злиття звичайним чином з git. напр

git checkout master
git merge branch_name

Якщо є конфлікт злиття, git відобразить щось подібне:

$ git merge branch_name
Auto-merging file_name
CONFLICT (content): Merge conflict in file_name
Automatic merge failed; fix conflicts and then commit the result.

У цей момент file_nameбуде міститись частково об'єднаний файл із конфліктною інформацією про злиття (це файл із усіма записами >>>>>>>та <<<<<<<записами в ньому).

Mergetool тепер може використовуватися для вирішення конфліктів злиття. Ви починаєте це дуже легко:

git mergetool

Якщо правильно налаштовано, відкриється вікно Meld із відображенням 3-х файлів. Кожен файл міститиметься в окремій області інтерфейсу GUI.

У наведеному .gitconfigвище прикладі в якості [mergetool "meld"] cmdрядка пропонуються 2 рядки . Насправді існують всілякі способи для досвідчених користувачів налаштувати cmdлінію, але це виходить за рамки цієї відповіді.

У цій відповіді є два альтернативних cmdрядки, які між ними будуть задовольняти більшість користувачів, і стане гарною відправною точкою для досвідчених користувачів, які бажають перенести інструмент на наступний рівень складності.

По-перше, ось що означають параметри:

  • $LOCAL - це файл у поточній гілці (наприклад, master).
  • $REMOTE це файл у гілці, що об'єднується (наприклад, ім'я гілки).
  • $MERGED це частково об'єднаний файл із конфліктною інформацією про об'єднання.
  • $BASEє спільним предком фіксації, $LOCALі $REMOTEце означає файл, як це було, коли гілка, що містить, $REMOTEбула створена спочатку.

Я пропоную вам скористатися будь-яким:

[mergetool "meld"]
    cmd = meld "$LOCAL" "$MERGED" "$REMOTE" --output "$MERGED"

або:

[mergetool "meld"]
    cmd = meld "$LOCAL" "$BASE" "$REMOTE" --output "$MERGED"
    # See 'Note On Output File' which explains --output "$MERGED".

Вибір - використовувати $MERGEDчи $BASEміж ними $LOCALта між ними $REMOTE.

У будь-якому випадку Meld буде відображати 3 панелі з $LOCALі $REMOTEв лівій і правій панелях, або на $MERGEDабо $BASEсередній панелі.

У випадках BOTH середня панель - це файл, який слід відредагувати, щоб вирішити конфлікти злиття. Різниця полягає лише в тому, в якій початковій позиції редагування ви б хотіли віддати перевагу; $MERGEDдля файлу, який містить частково об'єднаний файл із конфліктною інформацією про злиття або $BASEдля предка спільного виконання комісій $LOCALта $REMOTE. [Оскільки обидва cmdрядки можуть бути корисними, я зберігаю їх обидва у своєму .gitconfigфайлі. Більшу частину часу я використовую $MERGEDрядок, і $BASEрядок коментується, але коментування може бути замінено, якщо я хочу використовувати $BASEрядок замість цього.]

Note On Output File: Не хвилюйтеся , що --output "$MERGED"використовується в cmdнезалежно від того , $MERGEDчи $BASEвикористовувався раніше в cmdлінії. Цей --outputпараметр просто повідомляє Meld, яке ім'я файлу git хоче зберегти файл вирішення конфлікту. Meld збереже ваші зміни конфлікту у цьому файлі незалежно від того, використовуєте ви $MERGEDабо $BASEяк початкову точку редагування.

Після редагування середньої панелі для вирішення конфліктів злиття просто збережіть файл та закрийте вікно Meld. Git виконає оновлення автоматично, і файл у поточній гілці (наприклад, master) тепер міститиме все, що ви закінчили на середній панелі.

git зробить резервну копію частково об'єднаного файла з конфліктною інформацією в ньому, додавши .origдо оригінального імені файлу. напр file_name.orig. Перевіривши, що ви задоволені злиттям та виконавши будь-які тести, які ви можете зробити, .origфайл можна видалити.

На даний момент ви можете взяти на себе зобов’язання здійснити зміни.

Якщо під час редагування конфліктів злиття в Meld ви хочете відмовитися від використання Meld, а потім закрийте Meld, не зберігаючи файл роздільної здатності на середній панелі. git відповість на повідомлення, file_name seems unchangedа потім запитає Was the merge successful? [y/n], якщо ви відповісте, nтоді вирішення конфлікту злиття буде скасовано, а файл залишиться незмінним. Зауважте, що якщо ви зберегли файл у Meld в будь-який момент, то ви не отримаєте попередження та підказку від git. [Звичайно, ви можете просто видалити файл і замінити його на .origфайл резервного копіювання, який створено для вас.]

Якщо у вас більше 1 файлу з конфліктами злиття, то git відкриє нове вікно Meld для кожного, по черзі, поки вони не будуть виконані. Усі вони не будуть відкриті одночасно, але коли ви закінчите редагувати конфлікти в одному і закриєте Meld, git відкриє наступний і так далі, поки всі конфлікти злиття не будуть вирішені.

Було б розумним створити фіктивний проект для перевірки використання, git mergetoolперш ніж використовувати його в реальному проекті. Не забудьте використати ім’я файлу, що містить пробіл у вашому тесті, якщо ваша ОС вимагає від вас уникнути лапок у cmdрядку, див. Нижче


Уникнення символів цитати

У деяких операційних системах може знадобитися відмовитись від лапок cmd. Менш досвідчені користувачі повинні пам’ятати, що командні рядки конфігурації повинні бути протестовані з іменами файлів, які містять пробіли, а якщо cmdрядки не працюють з іменами файлів, які містять пробіли, то спробуйте уникнути лапок. напр

cmd = meld \"$LOCAL\" \"$REMOTE\"

У деяких випадках може знадобитися складніша втеча цитати. Перше з посилань на шлях до Windows нижче містить приклад потрійного виходу кожної цитати. Це нудно, але іноді необхідно. напр

cmd = meld \\\"$LOCAL\\\" \\\"$REMOTE\\\"

Доріжки для Windows

Користувачі Windows, ймовірно, потребуватимуть додаткової конфігурації, доданої до cmdрядків Meld . Можливо, їм потрібно буде використовувати повний шлях до meldc, який призначений для виклику в Windows з командного рядка, або вони можуть потребувати або хочуть використовувати обгортку. Вони повинні читати сторінки StackOverflow, що посилаються нижче, про те, як встановити правильну cmdлінію Meld для Windows. Оскільки я користувач Linux, я не в змозі перевірити різні cmdрядки Windows і не маю додаткової інформації з цього приводу, окрім як рекомендувати використовувати мої приклади з додаванням повного шляху до Meld або meldcабо додавання папки програми Meld у свою path.

Ігнорування пробілу пробілу з Meld

Meld має ряд переваг, які можна налаштувати в GUI.

На Text Filtersвкладці налаштувань є кілька корисних фільтрів, щоб ігнорувати речі, такі як коментарі, виконуючи різницю. Хоча є фільтри, які потрібно ігнорувати, All whitespaceі Leading whitespaceнемає Trailing whitespaceфільтра ігнорування (це було запропоновано як доповнення до списку розсилки Meld, але воно не доступне в моїй версії).

Ігнорування пробілів пробілів часто є дуже корисним, особливо при співпраці, і його можна легко вручну додати простим регулярним виразом на вкладці Meld preferences Text Filters.

# Use either of these regexes depending on how comprehensive you want it to be.
[ \t]*$
[ \t\r\f\v]*$

Я сподіваюся, що це допомагає всім.


2
Спасибі, що так набагато простіше використовувати [mergetool "meld"] cmd = meld "$LOCAL" "$MERGED" "$REMOTE" --output "$MERGED"в ~/.gitconfig, то просто вирішити конфлікти , виділені червоним кольором в середній каструлі і зберегти! Це має бути налаштування за замовчуванням.
KrisWebDev

1
$LOCAL $MERGED $REMOTEце налаштування, яке я використовую більшу частину часу, коли є лише кілька конфліктів для вирішення, це чудово, і це також мій дефолт. $LOCAL $BASE $REMOTEнасправді стає власним, коли потрібно зробити багато, і ви точно знаєте, які розділи коду надходять із якого файлу; пращур спільного вчинення може бути чудовим початковим пунктом, коли іноді висвітлення конфлікту насправді стає на шляху, а більш чиста основа - благо.
матст

4
Примітка: Якщо ви перебуваєте на OSX та встановили meld через homebrew, для вихідного параметра знадобиться =такий:cmd = meld "$LOCAL" "$MERGED" "$REMOTE" --output="$MERGED"
Alteisen

2
Користувачі Mac, які встановили .dmg і виявили, що "meld" не стоїть на їх шляху, не забудьте дотримуватися альтернативного набору інструкцій тут: yousseb.github.io/meld
KC Baltz

3
Це набагато краще, ніж пояснення в Git Configuration - git mergetool . Дуже дякую, особливо за пояснення різниці між $ MERGED та $ BASE. Врятувало мене від божевілля!
ChrisG

81

Хоча інша відповідь правильна, ось найшвидший спосіб просто йти вперед і налаштувати Meld як інструмент візуального розгляду. Просто скопіюйте та вставте це:

git config --global diff.tool meld
git config --global difftool.prompt false

Тепер запустіть git difftoolв каталозі, і Meld буде запущений для кожного іншого файлу.

Побічна примітка: Meld на диво повільний при порівнянні файлів CSV, і жоден інструмент Linux diff, який я знайшов, швидший, ніж цей інструмент Windows під назвою Порівняти! (востаннє оновлено у 2010 році).


13
Напевно, ви хочете і git config --global difftool.meld.cmd 'meld "$LOCAL" "$REMOTE"'рядок там. Це "за замовчуванням", але як тільки ви налаштуєте a mergetool, difftoolто почне використовувати конфігурацію mergetool як за замовчуванням, якщо diff config не знайдено. Оскільки злиття зазвичай налаштовано для передачі трьох файлів для тристороннього злиття, це означає, що у вашому meld розрізному вікні раптом будуть три області, що не має сенсу.
BeeOnRope

Чому б не перевірити конфігурацію, після встановлення з $ git config -l
agfe2

56

Для Windows . Виконайте ці команди в Git Bash:

git config --global diff.tool meld
git config --global difftool.meld.path "C:\Program Files (x86)\Meld\Meld.exe"
git config --global difftool.prompt false

git config --global merge.tool meld
git config --global mergetool.meld.path "C:\Program Files (x86)\Meld\Meld.exe"
git config --global mergetool.prompt false

(Оновіть шлях до файлу Meld.exe, якщо ваш інший.)

Для Linux . Виконайте ці команди в Git Bash:

git config --global diff.tool meld
git config --global difftool.meld.path "/usr/bin/meld"
git config --global difftool.prompt false

git config --global merge.tool meld
git config --global mergetool.meld.path "/usr/bin/meld"
git config --global mergetool.prompt false

Ви можете перевірити шлях Meld за допомогою цієї команди:

which meld

1
Я отримав помилку, коли запускаю git difftool "Розділення інструмента diff не доступне як" D: \ software \ melddiff \ Meld.exe ""
Аллен Ворк,

@AllenVork: Ви підтвердили, що Meld.exe знаходиться у вказаній вами папці? Чи можете ви запустити його поза Git успішно? Що повертає Git при запуску git config --global --get-regex diff*?
MarredCheese

Я це вирішив. Я змінюю його на "D: /software/melddiff/Meld.exe", і він працює. Формат .gitconfig - це ubuntu, а не windows.
Аллен Ворк

Не повинно бути: git config --global difftool.meld.path "C:\Program Files (x86)\Meld\Meld.exe"?
Джонатан Розенн

@AllenVork, ти використовуєш git для cygwin?
Адріан

25

Я вважаю за краще налаштувати meld як окрему команду, як-от так:

git config --global alias.meld '!git difftool -t meld --dir-diff'

Це робить його схожим зі скриптом git-meld.pl тут: https://github.com/wmanley/git-meld

Потім можна просто бігти

git meld

Я щойно працював із Cygwin, і тепер він зламався. Це і виправило це. Дякую! (Хоча я видалив цю --dir-diffчастину як особисту перевагу.)
PfunnyGuy

3

Для Windows 10 мені довелося помістити це у свій .gitconfig:

[merge]
  tool = meld
[mergetool "meld"]
  cmd = 'C:/Program Files (x86)/Meld/Meld.exe' $LOCAL $BASE $REMOTE --output=$MERGED
[mergetool]
  prompt = false

Все інше ви повинні знати , що написано в цьому супер відповідь на mattst далі вище.

PS: Чомусь це працювало лише з Meld 3.18.x, Meld 3.20.x дає мені помилку.


1

Це відповідь, орієнтований головним чином на розробників, що використовують Windows, оскільки синтаксис шляху інструменту diff відрізняється від інших платформ.

Я використовую Kdiff3 як git mergetool, але щоб налаштувати git difftool як Meld, я спершу встановив останню версію Meld з Meldmerge.org, а потім додав наступне до мого глобального .gitconfig, використовуючи:

git config --global -e

Зверніть увагу, якщо ви хочете, щоб Sublime Text 3 замість Vim за замовчуванням був основним ditor, ви можете додати це у файл .gitconfig:

[core]
editor = 'c:/Program Files/Sublime Text 3/sublime_text.exe'

Потім ви додаєте готель Meld як дифтол

[diff]
tool = meld
guitool = meld 

[difftool "meld"]
cmd = \"C:/Program Files (x86)/Meld/Meld.exe\" \"$LOCAL\" \"$REMOTE\" --label \"DIFF 
(ORIGINAL MY)\"
prompt = false
path = C:\\Program Files (x86)\\Meld\\Meld.exe

Зверніть увагу на провідну косу рису в cmd вище, для Windows це необхідно.

Можна також встановити псевдонім, щоб показати поточний git diff за допомогою опції --dir-diff . Тут буде перераховано змінені файли всередині Meld, що зручно, коли ви змінили декілька файлів (насправді дуже поширений сценарій).

Псевдонім виглядає таким чином у файлі .gitconfig, під розділом [псевдонім] :

showchanges = difftool --dir-diff

Щоб показати зміни, які я внесла до коду, я просто введіть таку команду:

git showchanges

На наступному зображенні показано, як ця опція - dir-diff може відображати список змінених файлів (приклад): Поле відображає список файлів зі змінами між $ LOCAL і $ REMOTE

Тоді можна натиснути на кожен файл і показати зміни всередині Meld.


0

Визначити різницю в голові від різних розділів у $ MERGED може бути складним і застосувати це. У моїх налаштуваннях meld допомагає, показуючи вам ці відмінності візуально, використовуючи:

[merge]
    tool = mymeld
    conflictstyle = diff3

[mergetool "mymeld"]
    cmd = meld --diff $BASE $REMOTE --diff $REMOTE $LOCAL --diff $LOCAL $MERGED

Це виглядає дивно, але пропонує дуже зручний робочий процес, використовуючи три вкладки:

  1. у вкладці 1 ви бачите (зліва направо) зміни, які слід внести у вкладку 2 для вирішення конфлікту злиття.

  2. у правій частині вкладки 2 ви застосовуєте "зміни, які слід внести", і копіюєте весь вміст файлу до буфера обміну (використовуючи ctrl-a та ctrl-c).

  3. у вкладці 3 замініть праву частину вмістом буфера обміну. Якщо все правильно, тепер ви побачите - зліва направо - таку ж зміну, що показана на вкладці 1 (але з різними контекстами). Збережіть зміни, внесені на цій вкладці.

Примітки:

  • не редагуйте нічого у вкладці 1
  • не зберігайте нічого у вкладці 2, оскільки це призведе до дратівливих спливаючих вікон у вкладці 3

Це краще, ніж тристороння злиття (локальне / базове / віддалене) в одній вкладці?
Андре Верланг

@ AndréWerlang Перевага тристороннього злиття в одній вкладці полягає в тому, що вам потрібно вирішувати лише суперечливі зміни (інші зміни об'єднуються автоматично). Але я віддаю перевагу "мій" підхід у тих випадках, коли в 3-х напрямному злитті важко зрозуміти, що змінилося, і як злитися таким чином, щоб зберегти всі зміни. Якщо в якийсь момент тривимірне злиття більше не бентежить мене, я можу перейти до нього.
mnieber

Як зазначив користувач mattst, ви можете використовувати $BASEзамість того, $MERGEDщоб розпочати операцію злиття
Андре Верланг
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.