Як вирішити конфлікти злиття в Git?
git
установки. Мені вдалося потрапити на початкову сторінку SE для мене сьогодні, 2017, з 1,3 мільйонами переглядів та тисячами голосів обома способами. Захоплююче.
Як вирішити конфлікти злиття в Git?
git
установки. Мені вдалося потрапити на початкову сторінку SE для мене сьогодні, 2017, з 1,3 мільйонами переглядів та тисячами голосів обома способами. Захоплююче.
Відповіді:
Спробуйте: git mergetool
Він відкриває графічний інтерфейс, який простежує вас через кожен конфлікт, і ви можете вибрати спосіб злиття. Іноді для цього потрібно трохи редагувати руки, але зазвичай цього достатньо саме по собі. Це набагато краще, ніж звичайно все робити вручну.
Відповідно до коментаря @JoshGlover:
Команда
не обов'язково відкривати графічний інтерфейс, якщо ви не встановите його. Біг
git mergetool
для мене призвів доvimdiff
використання. Ви можете встановити один з наступних інструментів , щоб використовувати його замість:meld
,opendiff
,kdiff3
,tkdiff
,xxdiff
,tortoisemerge
,gvimdiff
,diffuse
,ecmerge
,p4merge
,araxis
,vimdiff
,emerge
.
Нижче наведена прикладна процедура, яка використовується vimdiff
для вирішення конфліктів злиття. На основі цього посилання
Крок 1 : Виконайте наступні команди у своєму терміналі
git config merge.tool vimdiff
git config merge.conflictstyle diff3
git config mergetool.prompt false
Це встановить vimdiff як інструмент злиття за замовчуванням.
Крок 2 : Виконайте наступну команду в терміналі
git mergetool
Крок 3 : Ви побачите відображення vimdiff у наступному форматі
╔═══════╦══════╦════════╗
║ ║ ║ ║
║ LOCAL ║ BASE ║ REMOTE ║
║ ║ ║ ║
╠═══════╩══════╩════════╣
║ ║
║ MERGED ║
║ ║
╚═══════════════════════╝
Ці 4 погляди є
LOCAL - це файл з поточної гілки
БАЗА - звичайний пращур, як файл виглядав до обох змін
ВИДАЛЕНО - файл, який ви об’єднуєте у свою філію
MERGED - результат злиття, це те, що зберігається в репо
Ви можете переміщатися серед цих поглядів за допомогою ctrl+ w. Ви можете безпосередньо дістатися до MERGED подання за допомогою ctrl+, wа потім j.
Більше інформації про навігацію vimdiff тут і тут
Крок 4 . Ви можете редагувати MERGED-перегляд наступним чином
Якщо ви хочете отримати зміни від REMOTE
:diffg RE
Якщо ви хочете отримати зміни від BASE
:diffg BA
Якщо ви хочете отримати зміни від LOCAL
:diffg LO
Крок 5 . Збережіть, вийдіть, покладіть та очистіть
:wqa
зберегти та вийти з vi
git commit -m "message"
git clean
Видаліть зайві файли (напр. * .Orig), створені інструментом diff.
git mergetool -y
для збереження декількох натискань клавіш, якщо об’єднаєте багато файлів одночасно.
git mergetool
для мене призвів до vimdiff
використання. Ви можете встановити один з наступних інструментів , щоб використовувати його замість: meld opendiff kdiff3 tkdiff xxdiff tortoisemerge gvimdiff diffuse ecmerge p4merge araxis vimdiff emerge
.
git mergetool -t bc3
).
Ось вірогідний випадок використання зверху:
Ви збираєтеся внести деякі зміни, але, на жаль, ви не в курсі:
git fetch origin
git pull origin master
From ssh://gitosis@example.com:22/projectname
* branch master -> FETCH_HEAD
Updating a030c3a..ee25213
error: Entry 'filename.c' not uptodate. Cannot merge.
Тож ви отримуєте інформацію про час та повторіть спробу, але у вас виник конфлікт:
git add filename.c
git commit -m "made some wild and crazy changes"
git pull origin master
From ssh://gitosis@example.com:22/projectname
* branch master -> FETCH_HEAD
Auto-merging filename.c
CONFLICT (content): Merge conflict in filename.c
Automatic merge failed; fix conflicts and then commit the result.
Тож ви вирішили поглянути на зміни:
git mergetool
О мій, о мій, вгору змінив деякі речі, але просто використовувати мої зміни ... ні ... їх зміни ...
git checkout --ours filename.c
git checkout --theirs filename.c
git add filename.c
git commit -m "using theirs"
І тоді ми спробуємо остаточний час
git pull origin master
From ssh://gitosis@example.com:22/projectname
* branch master -> FETCH_HEAD
Already up-to-date.
Та-да!
git merge --help
this question
Я знаходжу інструменти злиття рідко допомагають мені зрозуміти конфлікт чи вирішення. Зазвичай я успішніше дивлюся на маркери конфліктів у текстовому редакторі і використовую журнал git як доповнення.
Ось кілька порад:
Найкраще, що я знайшов - це використовувати стиль конфлікту "diff3" злиття:
git config merge.conflictstyle diff3
Це створює маркери конфлікту на зразок цього:
<<<<<<<
Changes made on the branch that is being merged into. In most cases,
this is the branch that I have currently checked out (i.e. HEAD).
|||||||
The common ancestor version.
=======
Changes made on the branch that is being merged in. This is often a
feature/topic branch.
>>>>>>>
Середній розділ - це, як виглядав загальний предок. Це корисно, оскільки ви можете порівняти його з верхніми та нижчими версіями, щоб краще зрозуміти, що було змінено на кожній гілці, що дає вам краще уявлення про те, якою була мета кожної зміни.
Якщо конфлікт становить лише кілька рядків, це, як правило, робить конфлікт дуже очевидним. (Знання, як виправити конфлікт, дуже різна; вам потрібно знати про те, над чим працюють інші люди. Якщо ви розгублені, то, ймовірно, краще просто зателефонувати цій людині у вашу кімнату, щоб вони побачили, що ви шукаєте у.)
Якщо конфлікт довший, то я виріжу і вставлю кожен з трьох розділів у три окремі файли, такі як "моя", "загальна" та "їхня".
Тоді я можу запустити наступні команди, щоб побачити дві різкі частини, які спричинили конфлікт:
diff common mine
diff common theirs
Це не те саме, що використовувати інструмент злиття, оскільки інструмент злиття буде включати в себе і всі неконфліктні розрізнення. Я вважаю, що це відволікає.
Хтось уже згадував про це, але розуміння наміру, що стоїть за кожною різною частиною, як правило, дуже корисно для розуміння, звідки виник конфлікт і як його впоратися.
git log --merge -p <name of file>
Тут відображаються всі коміти, які торкнулися цього файлу між загальним предком і двома головами, які ви зливаєте. (Отже, він не включає комітети, які вже існують в обох гілках перед об'єднанням.) Це допомагає вам ігнорувати різні переклади, які явно не є фактором у вашому поточному конфлікті.
Перевірте свої зміни за допомогою автоматизованих інструментів.
Якщо у вас є автоматизовані тести, запустіть їх. Якщо у вас є обличчя , запустіть це. Якщо це збірний проект, то складіть його перед тим, як здійснити виконання, і т. Д. У всіх випадках вам потрібно зробити трохи тестування, щоб переконатися, що ваші зміни нічого не порушили. (Хек, навіть злиття без конфліктів може порушити робочий код.)
Планувати заздалегідь; спілкуватися з колегами.
Планування заздалегідь та усвідомлення того, над чим працюють інші, можуть допомогти запобігти конфліктам злиття та / або допомогти вирішити їх раніше - хоча деталі ще свіжі.
Наприклад, якщо ви знаєте, що ви та інша людина працюєте над різними рефакторингами, які будуть впливати на один і той же набір файлів, вам слід поговорити один з одним заздалегідь і краще зрозуміти, які типи змін кожного з вас виготовлення. Ви можете заощадити чималий час і зусилля, якщо проводити заплановані зміни послідовно, а не паралельно.
Що стосується великих рефактори, які вирізають велику частину коду, слід наполегливо розглянути можливість послідовної роботи: усі припиняють роботу над цією областю коду, тоді як одна людина виконує повний рефакторинг.
Якщо ви не можете працювати серійно (можливо, через тиск у часі), то спілкування про очікувані конфлікти злиття принаймні допомагає вирішити проблеми швидше, поки деталі ще свіжі. Наприклад, якщо працівник колективу робить порушуючий ряд зобов’язань протягом одного тижня, ви можете вирішити об'єднання / повторне базування цього відділення співробітників один або два рази на день протягом цього тижня. Таким чином, якщо ви знайдете конфлікти злиття / відновлення, ви можете вирішити їх швидше, ніж якщо зачекати кілька тижнів, щоб злити все разом в один великий грудочок.
Якщо ви не впевнені в злитті, не змушуйте його.
Об'єднання може відчувати непосильне значення, особливо коли є багато конфліктуючих файлів і маркери конфліктів охоплюють сотні рядків. Часто при оцінці програмних проектів ми не передбачаємо достатньо часу для накладних елементів, таких як обробка грубого злиття, тому відчувається, що справжнє перетягування витрачає кілька годин на розсічення кожного конфлікту.
Зрештою, планування заздалегідь та усвідомлення того, над чим працюють інші, є найкращими інструментами для передбачення конфліктів злиття та підготуйтеся до їх правильного вирішення за менший час.
p4merge
, який можна встановити та використовувати окремо від інших інструментів Perforce (які я не використовував, але чув скарги на це).
git config merge.conflictstyle diff3
- Дякую вам сер. Це дивовижно і звільнило мене від спроб знайти (і заплатити $$) за хороший інтерфейс графічного інтерфейсу в 3 способи. IMO це краще, тому що він показує загального предка, а також локальний / віддалений, і показує останні рядки журналу фіксування, які (AFAIK) не робить GUI. Коміти, безумовно, допоможуть вам визначити, який код належить до тієї галузі.
Визначте, які файли конфліктують (Git повинен вам це сказати).
Відкрийте кожен файл і вивчіть відмінності; Гіт розмежовує їх. Сподіваємось, буде очевидно, яку версію кожного блоку зберігати. Можливо, вам доведеться обговорити це з іншими розробниками, які ввели код.
Після вирішення конфлікту у файлі git add the_file
.
Після того як ви вирішите всі конфлікти, виконайте git rebase --continue
або будь-яку команду, яку сказав Git, коли ви виконали.
git add
ставить файли в індекс; він нічого не додає до сховища. git commit
додає речі до сховища. Це використання має сенс для злиття - злиття автоматично стадіює всі зміни, які можна об'єднати автоматично; Ваша відповідальність - об'єднати решту змін і додати їх до індексу, коли Ви закінчите.
Перегляньте відповіді на запитання про переповнення стека. Скасування злиття в Git , особливо відповідь Чарльза Бейлі, яка показує, як переглянути різні версії файлу з проблемами, наприклад,
# Common base version of the file.
git show :1:some_file.cpp
# 'Ours' version of the file.
git show :2:some_file.cpp
# 'Theirs' version of the file.
git show :3:some_file.cpp
Конфлікти злиття трапляються, коли в файл одночасно вносяться зміни. Ось як це вирішити.
git
CLIОсь прості кроки, що потрібно робити, коли потрапляєш у конфліктний стан:
git status
(під Unmerged paths
розділом).Вирішіть конфлікти окремо для кожного файлу одним із наступних підходів:
Використовуйте GUI для вирішення конфліктів: git mergetool
(найпростіший спосіб).
Для того, щоб прийняти віддалений / інші версії, використання: git checkout --theirs path/file
. Це відхилить усі локальні зміни, які ви зробили для цього файлу.
Щоб прийняти локальну / нашу версію, використовуйте: git checkout --ours path/file
Однак ви повинні бути обережними, оскільки віддалені зміни, які конфлікти були зроблені з якоїсь причини.
Відредагуйте конфліктні файли вручну та знайдіть код коду між <<<<<
/ >>>>>
та виберіть версію зверху чи знизу =====
. Див.: Як представлені конфлікти .
Конфлікти шляху та імен можна вирішити за допомогою git add
/ git rm
.
Нарешті, перевірте файли готові для фіксації з допомогою: git status
.
Якщо у вас є якісь - або файли в Unmerged paths
, і ти розв'язати конфлікт вручну, то нехай Git знаю , що ви вирішили його: git add path/file
.
Якщо всі конфлікти були вирішені успішно, введіть зміни за допомогою: git commit -a
та натисніть на віддалений як завжди.
Дивіться також: Вирішення конфлікту злиття з командного рядка в GitHub
Для практичного підручника перевірте: Сценарій 5 - Виправлення конфліктів злиття від Katacoda .
Я успішно використовував DiffMerge, який дозволяє візуально порівнювати та об’єднувати файли в Windows, macOS та Linux / Unix.
Він графічно може відображати зміни між 3 файлами, і це дозволяє автоматичне об'єднання (коли це безпечно) та повний контроль над редагуванням отриманого файлу.
Джерело зображення: DiffMerge (скріншот Linux)
Просто завантажте його та запустіть у репо як:
git mergetool -t diffmerge .
На macOS ви можете встановити через:
brew install caskroom/cask/brew-cask
brew cask install diffmerge
І, ймовірно, (якщо це не передбачено) вам потрібні такі додаткові прості обгортки, які розміщені у вашій PATH (наприклад /usr/bin
):
#!/bin/sh
DIFFMERGE_PATH=/Applications/DiffMerge.app
DIFFMERGE_EXE=${DIFFMERGE_PATH}/Contents/MacOS/DiffMerge
exec ${DIFFMERGE_EXE} --nosplash "$@"
Тоді ви можете використовувати наступні комбінації клавіш:
Крім того, ви можете використовувати opendiff (частина інструментів Xcode), яка дозволяє об'єднати два файли або каталоги разом, щоб створити третій файл або каталог.
Якщо ви робите часті невеликі комітети, то почніть з перегляду коментарів із виконання git log --merge
. Тоді git diff
покажуть вам конфлікти.
У конфліктах, які містять більше кількох рядків, простіше зрозуміти, що відбувається у зовнішньому інструменті графічного інтерфейсу. Мені подобається opendiff - Git також підтримує vimdiff, gvimdiff, kdiff3, tkdiff, meld, xxdiff, вийде з коробки і ви можете встановити інші: git config merge.tool "your.tool"
встановіть вибраний інструмент, а потім git mergetool
після невдалого злиття покаже вам відмінності в контексті.
Кожен раз, коли ви редагуєте файл, щоб вирішити конфлікт, git add filename
оновити індекс, і ваш розмінник більше не відображатиме його. Коли всі конфлікти будуть вирішені, а їхні файли git add
-ed, git commit
завершиться злиттям.
Перегляньте, як представлені конфлікти або документацію в Git, git merge
щоб зрозуміти, що таке маркери конфліктів злиття.
Також у розділі " Як вирішити конфлікти " пояснюється спосіб вирішення конфліктів:
Побачивши конфлікт, ви можете зробити дві речі:
Вирішіть не зливатися. Єдині необхідні очищення - це скинути індексний файл до
HEAD
зобов’язання обернути реверс 2. та очистити зміни робочого дерева, внесені на 2. та 3.;git merge --abort
можна використовувати для цього.Вирішіть конфлікти. Git позначить конфлікти в робочому дереві. Відредагуйте файли у формі та додайте
git add
їх до індексу. Використовуйтеgit commit
для підписання угоди.Ви можете працювати через конфлікт з низкою інструментів:
Використовуйте mergetool.
git mergetool
запустити графічний mergetool, який пропрацює вас через злиття.Подивіться на відмінності.
git diff
покаже тристоронній розбіг, виділивши зміни як версій, такHEAD
іMERGE_HEAD
версій.Подивіться на відмінності кожної галузі.
git log --merge -p <path>
покаже розходження дляHEAD
версії, а потім дляMERGE_HEAD
версії.Подивіться на оригінали.
git show :1:filename
показує загального предка,git show :2:filename
показуєHEAD
версію таgit show :3:filename
показуєMERGE_HEAD
версію.
Ви також можете прочитати про злиття конфліктних маркерів та способи їх вирішення в розділі книги Pro Git Основні конфлікти злиття .
Я або хочу, щоб моя або їх версія була повністю, або хочу переглянути окремі зміни та прийняти рішення щодо кожної з них.
Повністю прийміть мою чи їхню версію :
Прийміть мою версію (локальну, нашу):
git checkout --ours -- <filename>
git add <filename> # Marks conflict as resolved
git commit -m "merged bla bla" # An "empty" commit
Прийміть їх версію (віддалену, їхню):
git checkout --theirs -- <filename>
git add <filename>
git commit -m "merged bla bla"
Якщо ви хочете виконати всі запущені файли конфлікту :
git merge --strategy-option ours
або
git merge --strategy-option theirs
Перегляньте всі зміни та прийміть їх окремо
git mergetool
git add <filename>
git commit -m "merged bla bla"
За замовчуванням mergetool
працює в командному рядку . Як використовувати mergetool командного рядка, має бути окремим питанням.
Для цього також можна встановити візуальний інструмент , наприклад, meld
і запустити
git mergetool -t meld
Він відкриє локальну (нашу), "базову" або "злиту" версію (поточний результат об'єднання) та віддалену версію (їх). Збережіть об’єднану версію, коли закінчите, запустіть git mergetool -t meld
ще раз, поки не з’явиться "Жодних файлів не потрібно об'єднувати", а потім перейдіть до кроків 3. та 4.
Для користувачів Emacs, які хочуть вирішити конфлікти злиття напівручно:
git diff --name-status --diff-filter=U
показує всі файли, які потребують вирішення конфлікту.
Відкрийте кожен із цих файлів по одному або всі відразу:
emacs $(git diff --name-only --diff-filter=U)
Відвідавши буфер, який вимагає редагування в Emacs, введіть
ALT+x vc-resolve-conflicts
Це відкриє три буфери (мій, їхній та вихідний буфер). Перейдіть, натискаючи 'n' (наступний регіон), 'p' (область попереднього перегляду). Натисніть 'a' та 'b', щоб скопіювати шахту або їх область у вихідний буфер відповідно. І / або редагувати вихідний буфер безпосередньо.
По закінченні: Натисніть «q». Emacs запитує вас, чи бажаєте ви зберегти цей буфер: так. Закінчивши буфер, позначте його як вирішене запуском із терміналу:
git add FILENAME
Після закінчення всіх типів буферів
git commit
закінчити злиття.
Говорячи про тягнення / отримання / злиття у вищезазначених відповідях, я хотів би поділитися цікавим та продуктивним трюком,
git pull --rebase
Ця вище команда - найкорисніша команда в моєму житті git, яка зекономила багато часу.
Перед тим, як натиснути щойно здійснену зміну на віддалений сервер, спробуйте git pull --rebase
скоріше git pull
і вручну, merge
і вона автоматично синхронізує останні зміни на віддаленому сервері (із вилученням і злиттям) і поставить останню локальну фіксацію вгорі в журналі git. Не потрібно турбуватися про ручне потягування / злиття.
У разі конфлікту просто використовуйте
git mergetool
git add conflict_file
git rebase --continue
Деталі можна знайти на веб- сайті: http://gitolite.com/git-pull--rebase
Просто, якщо ви добре знаєте, що зміни в одному з сховищ не є важливими, і хочете вирішити всі зміни на користь іншого, скористайтеся:
git checkout . --ours
щоб вирішити зміни на користь вашого сховища , або
git checkout . --theirs
вирішити зміни на користь іншого чи основного сховища .
Або ж вам доведеться використовувати інструмент злиття графічного інтерфейсу, щоб переглядати файли один за одним, скажімо, інструмент злиття є p4merge
, або написати будь-яке ім’я, яке ви вже встановили
git mergetool -t p4merge
а після закінчення файлу вам доведеться зберегти і закрити, тому наступний відкриється.
Виконайте наступні кроки, щоб виправити конфлікти злиття в Git:
Перевірте статус Git: статус git
Отримайте патчсет: git fetch ( оформити правильний патч від вашої Git комісії)
Оформити локальну гілку (temp1 у моєму прикладі тут): git checkout -b temp1
Витягніть останній вміст з master: git pull - master master origin
Запустіть mergetool і перевірте конфлікти та виправте їх ... і перевірте зміни у віддаленій гілці за допомогою вашої поточної гілки: git mergetool
Перевірте статус ще раз: статус git
Видаліть непотрібні файли, створені локально за допомогою mergetool, зазвичай mergetool створює додатковий файл із розширенням * .orig. Видаліть цей файл, оскільки це лише дублікат та виправлення змін на локальному рівні та додайте правильну версію файлів. git add #your_changed_correct_files
Перевірте статус ще раз: статус git
Введіть зміни в той самий id комісії (це дозволяє уникнути нового окремого набору патчів): git commit --amend
Натисніть на головну гілку: git push (до вашого сховища Git)
Є 3 кроки:
Знайдіть, які файли викликають конфлікти за командою
git status
Перевірте файли, в яких ви знайдете конфлікти, позначені як
<<<<<<<<head
blablabla
Змініть його так, як вам потрібно, а потім виконайте команди
git add solved_conflicts_files
git commit -m 'merge msg'
Ви можете виправити конфлікти злиття різними способами, як інші детально описані.
Я думаю, що справжнім ключем є те, як змінюються зміни з локальними та віддаленими сховищами. Ключовим моментом є розуміння відстеження гілок. Я виявив, що я вважаю гілку відстеження як "пропущений фрагмент в середині" між мною моїм локальним, фактичним каталогом файлів і віддаленим, визначеним як джерело.
Я особисто ввійшов у звичку 2 речі, щоб допомогти цього уникнути.
Замість:
git add .
git commit -m"some msg"
У якого є два недоліки -
а) Додаються всі нові / змінені файли, які можуть включати небажані зміни.
б) Ви не спершу переглядаєте список файлів.
Тому замість цього я роблю:
git add file,file2,file3...
git commit # Then type the files in the editor and save-quit.
Таким чином ви більш обмірковуєте, які файли додаються, і ви також можете переглянути список і подумати трохи більше, використовуючи редактор для повідомлення. Я вважаю, що це також покращує мої повідомлення про фіксацію, коли я використовую повноекранний редактор, а не -m
варіант.
[Оновлення - як минув час, я перейшов більше на:
git status # Make sure I know whats going on
git add .
git commit # Then use the editor
]
Також (і більше стосується вашої ситуації), я намагаюся уникати:
git pull
або
git pull origin master.
тому що притягування передбачає злиття, і якщо у вас є місцеві зміни, які ви не хотіли об'єднати, ви можете легко закінчити об'єднаний код та / або конфлікти злиття для коду, який не повинен був бути об'єднаний.
Натомість я намагаюся це зробити
git checkout master
git fetch
git rebase --hard origin/master # or whatever branch I want.
Ви також можете скористатися цією корисною:
git гілка, вилка, витяг, злиття, відновлення та клонування, які відмінності?
git checkout master
та git fetch
і git rebase --hard origin/master
git add .
, чи збережемо наші локальні модифікації, щоб ми могли продовжувати роботу git checkout master
? чи це два різні сценарії?
$ git rebase --hard origin/master b5a30cc159ba8dd error: unknown option
hard 'використання: git rebase [-i] [параметри] [--exec <cmd>] [--onto <newbase>] [<upstream>] [<branch>] або: git rebase [-i] [ параметри] [--exec <cmd>] [--onto <newbase>] --root [<Branch>] або: git rebase - продовжити | --аборт | --скіп | --edit-todo `
Відповідь CoolAJ86 підсумовує майже все. Якщо у вас є зміни в обох гілках в одному і тому ж фрагменті коду, вам доведеться виконати об'єднання вручну. Відкрийте файл в конфлікті в будь-якому текстовому редакторі, і ви повинні побачити наступну структуру.
(Code not in Conflict)
>>>>>>>>>>>
(first alternative for conflict starts here)
Multiple code lines here
===========
(second alternative for conflict starts here)
Multiple code lines here too
<<<<<<<<<<<
(Code not in conflict here)
Виберіть одну з альтернатив або комбінацію обох способів, яким ви хочете, щоб був новий код, видаляючи однакові знаки та кутові дужки.
git commit -a -m "commit message"
git push origin master
git log --merge -p [[--] path]
Мабуть, не завжди працює для мене, і зазвичай в кінцевому підсумку відображається кожен комітет, який відрізнявся між двома гілками, це відбувається навіть при використанні --
для відділення шляху від команди.
Що я роблю для вирішення цього питання - це відкрити два командні рядки та за один пробіг
git log ..$MERGED_IN_BRANCH --pretty=full -p [path]
а в іншому
git log $MERGED_IN_BRANCH.. --pretty=full -p [path]
Замінившись $MERGED_IN_BRANCH
із гілкою, я злився і [path]
з файлом, який конфліктує. Ця команда буде реєструвати всі коміти у формі виправлення між ( ..
) двома комітами. Якщо ви залишите одну сторону порожньою, як у командах над git, автоматично використовуватиметься HEAD
(гілка, в яку ви зливаєтеся в цьому випадку).
Це дозволить вам побачити, які коміти входили у файл у двох гілках після їх розбіжності. Зазвичай це значно полегшує вирішення конфліктів.
patience
Я здивований, що ніхто не говорив про вирішення конфлікту за patience
допомогою рекурсивної стратегії злиття. Для великого конфлікту злиття, використовуючи patience
хороші результати для мене. Ідея полягає в тому, що вона намагатиметься відповідати блокам, а не окремим рядкам.
Якщо змінити відступ програми, наприклад, стратегія злиття Git за замовчуванням іноді відповідає одній дужці, {
яка належить до різних функцій. Цього уникнути patience
:
git merge -s recursive -X patience other-branch
З документації:
With this option, merge-recursive spends a little extra time to avoid
mismerges that sometimes occur due to unimportant matching lines
(e.g., braces from distinct functions). Use this when the branches to
be merged have diverged wildly.
Якщо у вас конфлікт злиття і хочете побачити, що мали на увазі інші, змінюючи свою гілку, іноді простіше порівняти їх гілку безпосередньо із загальним предком (замість нашої гілки). Для цього ви можете використовувати merge-base
:
git diff $(git merge-base <our-branch> <their-branch>) <their-branch>
Зазвичай ви хочете бачити лише зміни для певного файлу:
git diff $(git merge-base <our-branch> <their-branch>) <their-branch> <file>
З 12 грудня 2016 року ви можете об’єднати гілки та вирішити конфлікти на github.com
Таким чином, якщо ви не хочете використовувати командний рядок або будь-які сторонні інструменти, які тут пропонуються зі старих відповідей , перейдіть з нативним інструментом GitHub.
У цьому дописі в блозі докладно роз'яснено, але основи полягають у тому, що при "об'єднанні" двох гілок через інтерфейс користувача ви побачите параметр "вирішити конфлікти", який переведе вас до редактора, що дозволяє вирішувати ці конфлікти злиття.
Якщо ви хочете об'єднатись з гілки (тесту) в master, виконайте наступні дії:
Крок 1 : Перейдіть до гілки
git checkout test
Крок 2 :
git pull --rebase origin master
Крок 3 : Якщо є деякі конфлікти, перейдіть до цих файлів, щоб змінити їх.
Крок 4 : Додайте ці зміни
git add #your_changes_files
Крок 5 :
git rebase --continue
Крок 6 : Якщо конфлікт все ще існує, поверніться до кроку 3 знову. Якщо конфлікту немає, зробіть наступне:
git push origin +test
Крок 7 : І тоді між тестом і майстром немає конфлікту. Ви можете використовувати об'єднання безпосередньо.
Я завжди дотримуюся наведених нижче кроків, щоб уникнути конфліктів.
Тепер ви можете зробити те саме і підтримувати стільки місцевих гілок, які ви хочете, і працювати одночасно, я просто роблю виїзд у ваш відділення, коли це буде потрібно.
Конфлікти злиття можуть виникати в різних ситуаціях:
Для вирішення конфліктів вам потрібно встановити інструмент злиття, сумісний з Git. Я особисто використовую KDiff3, і мені це було приємно і зручно. Ви можете завантажити його версію для Windows тут:
https://sourceforge.net/projects/kdiff3/files/
BTW, якщо ви встановлюєте Git Extensions, у його майстра налаштування є можливість встановити Kdiff3.
Потім встановіть конфігурації git, щоб використовувати Kdiff як свій mergetool:
$ git config --global --add merge.tool kdiff3
$ git config --global --add mergetool.kdiff3.path "C:/Program Files/KDiff3/kdiff3.exe"
$ git config --global --add mergetool.kdiff3.trustExitCode false
$ git config --global --add diff.guitool kdiff3
$ git config --global --add difftool.kdiff3.path "C:/Program Files/KDiff3/kdiff3.exe"
$ git config --global --add difftool.kdiff3.trustExitCode false
(Не забудьте замінити шлях фактичним шляхом до файлу Kdiff exe.)
Потім кожного разу, коли ви стикаєтеся з конфліктом злиття, вам просто потрібно виконати цю команду:
$git mergetool
Потім він відкриває Kdiff3 і спочатку намагається вирішити конфлікти злиття автоматично. Більшість конфліктів буде вирішено спонтанно, а решту потрібно виправити вручну.
Ось як виглядає Kdiff3:
Потім, як тільки ви закінчите, збережіть файл, і він перейде до наступного файлу з конфліктом, і ви знову зробите те саме, поки всі конфлікти не будуть вирішені.
Щоб перевірити, чи все об’єднано успішно, просто запустіть команду mergetool ще раз, ви повинні отримати такий результат:
$git mergetool
No files need merging
Ця відповідь полягає в тому, щоб додати альтернативу тим користувачам VIM, як я, який вважає за краще робити все в редакторі.
Tpope придумав цей чудовий плагін для VIM під назвою втікач . Після встановлення ви можете запустити :Gstatus
для перевірки файлів, які конфліктують та:Gdiff
відкрити Git трьома способами злиття.
Потрапивши в 3-х напрямкове злиття, втікач дозволить вам змінити будь-яку з гілок, які ви об’єднуєте, таким чином:
:diffget //2
, отримати зміни з оригінальної ( HEAD ) гілки::diffget //3
, отримайте зміни від галузі, що об'єднується: Після того як ви закінчите об'єднання файлу, введіть :Gwrite
об'єднаний буфер. Vimcasts випустив чудове відео, де детально пояснюються ці кроки.
git fetch
git checkout вашого філіалу
git rebase master
На цьому кроці ви спробуєте виправити конфлікт, використовуючи перевагу IDE
Ви можете перейти за цим посиланням, щоб перевірити, як вирішити конфлікт у файлі
https://help.github.com/articles/resolving-a-merge-conflict-using-the-command-line/
git add
git rebase - продовжити
git commit - змінити
походження git push HEAD: refs / drafts / master (push як чернетки)
Тепер все добре, і ви знайдете свою прихильність в Геррі
Сподіваюся, що це допоможе кожному, хто стосується цього питання.
Спробуйте скористатися кодом Visual Studio для редагування, якщо ви ще цього не зробили. Що ви робите, це те, що ви спробуєте об'єднатись (і розташуватися в конфліктах злиття) .VS код автоматично виявить конфлікти злиття.
Це може допомогти вам дуже добре, показавши, які зміни були внесені до оригіналу, і якщо ви приймаєте incoming
або
current change
(мається на увазі оригінал перед об'єднанням) '?.
Це допомогло для мене, і це може працювати і для вас!
PS: Він буде працювати лише в тому випадку, якщо ви налаштували git зі своїм кодом та кодом Visual Studio.
Більш безпечним способом вирішення конфліктів є використання git-mediate (поширені рішення, запропоновані тут, є досить схильними до помилок).
Перегляньте цю публікацію для швидкого ознайомлення з тим, як її використовувати.
Для тих, хто використовує Visual Studio (2015 в моєму випадку)
Закрийте проект у VS. Особливо у великих проектах VS, як правило, відлякує при об'єднанні за допомогою інтерфейсу.
Зробіть об'єднання в командному рядку.
git checkout target_branch
git merge source_branch
Потім відкрийте проект у VS та перейдіть до Team Explorer -> Відділення. Тепер з'явилося повідомлення, яке говорить про те, що об’єднання очікує на розгляд, а файли, що суперечать один одному, перераховуються під цим повідомленням.
Клацніть файл, що суперечить, і у вас буде можливість об'єднати, порівняти, взяти джерело, взяти за мету. Інструмент злиття в VS дуже простий у використанні.
Якщо ви використовуєте intelliJ як IDE, спробуйте об'єднати батьківство з вашою філією
git checkout <localbranch>
git merge origin/<remotebranch>
Він покаже всі подібні конфлікти
A_MBPro: перевірити початок злиття anu $ git / Автоматичне об'єднання src / test / java / com /.../ TestClass.java CONFLICT (content): конфлікт злиття в src / test / java / com /.../ TestClass.java
Тепер зауважте, що файл TestClass.java відображається червоним кольором в intelliJ Також буде показаний статус git
Unmerged paths:
(use "git add <file>..." to mark resolution)
both modified: src/test/java/com/.../TestClass.java
Відкрийте файл в IntelliJ, він буде мати розділи з
<<<<<<< HEAD
public void testMethod() {
}
=======
public void testMethod() { ...
}
>>>>>>> origin/<remotebranch>
де HEAD - це зміна вашої локальної гілки та походження / - це зміни від віддаленої гілки. Тут зберігайте потрібні вам речі та видаліть потрібні вам речі. Після цього слід виконати звичайні дії. Це є
git add TestClass.java
git commit -m "commit message"
git push