Как мне не удалось гладко перенести выборочные изменения с Git
Возникла задача временной правки некоторых переменных скрипта для внесения ключевых изменений в работу отдельных функций, а затем отката к старым значениям переменных (с сохранением нового функционала). Расскажу, какие инструменты предлагает Git для решения проблемы и почему они не работают как ожидалось.
Итак, я попробовал два решения:
- Первое - сохранить правки значений переменных в стек, модифицировать код функций и закоммитить изменения, а затем отменить действия из стека.
- Второе - сохранить в отдельной ветке в виде двух коммитов правку переменных и правку функций и перенести только второй коммит в основную ветку.
Изменения стека
Рассмотрим проект с файлом, который изначально имел следующий вид:
Закоммитим его состояние, создадим для удобства новую ветку, а затем изменим последнюю строку и сбросим изменения в стек:
Затем восстановим изменения:
Новая версия файла такая:
Затем сымитируем изменения функционала (которые нам реально нужно будет сохранить) - добавим строку и сделаем коммит:
Модифицированная версия файла:
Теперь отменим изменения из стека командой:
git stash show -p stash@{1} | git apply -R:
Получили ошибку, так как версия файла после применения изменений из стека поменялась (я же надеялся на гладкое изменение строки со значением df2):
Если модифицировать команду, нацеливая на поиск общего предка (у версии перед исправлением и новой), Git потребует разрешить конфликт:
git stash show -p stash@{1} | git apply -R3
То есть сама система не может догадаться, что нужно оставить, а что удалить. Изменения, внесенные через стек и коммит объединены.
Перенос изменений выбранного коммита
Создадим отдельную ветку, закоммитим изменения переменной df2, затем добавим строку с df3 и закоммитим опять:
Теперь переключимся на ветку master:
И с помощью команды
git cherry-pick хеш_коммита
попробуем перенести "вторые" изменения:
Получим схожее с первым "неполное" решение:
Опять же из-за несовпадение версий файлов второго коммита (зависит от первого) и того, который перед первым, система не может самостоятельно принять решение.