vimdiff как решение конфликтов в VCS на примере GIT

В конспекте намеренно создана ситуация когда возникает конфликт изменений при слиянии в контроле версий GIT и произведено ручное решение конфликта через инструмент vimdiff

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

Создадим чистый git репозиторий без рабочего каталога
mkdir folder1
cd folder1/
git --bare init
Создадим рабочий каталого
cd ../
mkdir folder2
cd folder2/
Склонируем содержимое репозитория folder1
git clone ssh://127.0.0.1:/home/username/Sites/examples/folder1 ./
Создадим файл
touch index.php
Внесем туда данные
<?php

echo 'Hello World From folder2';
Добавим файл под котроль версия, закоммитим и запушим изменения
git add index.php
git commit -m "Init folder2"
git push
Теперь создадим другой рабочий каталог
cd ../
mkdir folder3
cd folder3/
И склонируем данные с репозитория folder1
git clone ssh://127.0.0.1:/home/username/Sites/examples/folder1 ./
index.php появился в рабочем каталоге Теперь давайте снова пойдем в folder2 и сделаем изменения в файл index.php
cd ../folder2/
Внесем изменения
<?php

echo 'Hello World From folder2 change';
Добавим измененный файл под контроль, закоммитим и запушим
git add index.php
git commit -m "folder2 change"
git push
Снова пойдем в folder3
cd ../folder3/
И внесем некоторые изменения в Index.php
<?php

echo 'Hello World From Folder3';
Добавим измененный файл под контроль, закоммитим и запушим
git add index.php
git commit -m "change folder3"
git push
Получаем сообщение:
hint: Updates were rejected because the remote contains work that you do
hint: not have locally. This is usually caused by another repository pushing
hint: to the same ref. You may want to first integrate the remote changes
hint: (e.g., 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
В удаленном репозитории были сделаны изменения в файл, которых нет в локальном рабочем каталоге (folder3) Получаем изменения
git pull
Получаем сообщение
Auto-merging index.php
CONFLICT (content): Merge conflict in index.php
Automatic merge failed; fix conflicts and then commit the result
Возник конфликт изменений и попытка автоматического слияние завершилась провалом. Необходимо решить конфликт вручную. Для решения такого рода задач существует множество различных инструментов, но в этой заметке как и было указано в заголовке будет применен vimdiff Устанавливаем vimdiff как инструмент решения конфликтов по умолчанию:
git config merge.tool vimdiff
git config merge.conflictstyle diff3
git config mergetool.prompt false
Про diff3 и three-way merge можно почитать перейдя по ссылкам в дополнительных материалах Открываем инструмент для решения конфликтов
git mergetool


  • LOCAL - Локальные изменения (folder3) в текущей ветке
  • BASE - Как файл выглядел до того, как были сделаны изменения в folder2 и в folder3
  • REMOTE - Изменения в репозитории (folder1)
  • MERGED (горизонтальное окно снизу) - Результат слияния который попадет в репозиторий (окончательный вариант)
Предположим, что мы хотим оставить изменения сделанные в folder3, т.е. локальные (LOCAL). Перемещаем курсор в окне MERGED на фиолетовую линию и нажимаем "do" Получаем сообщение:
More than two buffers in diff mode, don't know which one to use
Vimdiff работает только с одним буфером, т.е. одним окном, а у нас их 3 (помимо MERGED). Нужно определиться с какого окна мы хотим взять изменения, а остальные заблокировать. При помощи "CTRL+W" перемещаемся по окнам. Для начала поместим курсор в BASE и заблокируем его:
:diffoff
Затем переместим курсор в REMOTE и тоже его заблокируем
:diffoff
Затем пойдем в MERGED и в очередной раз попробуем нажать "do". Если результат свернется в спойлер, его можно развернуть нажав пробел (space)



Чтобы "разблокировать" окно, переместите курсор (CTRL+W) в желаемую панель и введите:
:diffthis
Чтобы завершить слияние введите:
:xa
Не забудьте сделать коммит:
git commit -m "Merged"
И пуш
git push
Изменения были успешно закомитены и залиты в репозиторий folder1
git log --graph


Дополнительные материалы

Информация

Автор конспекта


Дата создания: 01.01.2019
Категория: Веб-разработка