Решайте конфликты между различными ветвями без фиксации
Я получил две ветви (мастер и функция), которые разошлись.
master - C1 - C3
\
feature C2 - C4 - C5
C2 и C4 - просто грязные коммиты с временным кодом, которые я не хочу включать в окончательное слияние / перебазирование двух ветвей.
Я обычно выполняю:
git checkout master
git cherry-pick C5 (last commit from the feature branch)
Но на этот раз у меня конфликтует C3, и я не могу выбрать коммит.
Я попробовал перенести C3 в ветку функций, чтобы не было конфликтов при сборке вишни.
git checkout feature
git rebase master
Теперь я получил это
master - C1 - C3
\
feature C2 - C4 - C5
Кажется, хорошо, но если я попытаюсь снова выбрать вишню на главном компьютере, у меня все еще будут конфликты (на некотором пустом месте, которое я удалил из некоторых файлов)
Git говорит мне разрешить конфликты, добавить файлы и зафиксировать. Я могу разрешать конфликты вручную, но не хочу совершать их просто как разрешение конфликтов.
Я хочу избежать коммитов в моей истории о чем-то, что не связано напрямую с реализациями. Я бы даже не знал, что написать как коммит-сообщение.
- Почему я все еще получаю конфликты после ребазинга?
- И как я могу получить C5 для слияния / выбора вишни без дополнительных коммитов?
Я обычно предпочитаю вишню, потому что я могу избежать "бесполезного" коммита слияния и просто коммитить изменения кода. Затем после этого я удаляю ветку, через некоторое время я уверен, что она мне больше не нужна
[[ РЕДАКТИРОВАТЬ ]]
Странное поведение заключается в том, что C5 и C3 конфликтуют с файлами, которые не были изменены в C3.
Infact, все обнаруженные конфликты просто пусты в главной ветви
<<<<<<< HEAD
=======
[ added code ..................... ]
[ .......... from ................ ]
[ ............... 'feature' branch ]
>>>>>>> 581g52d... "Commit message from 'feature' C5 "
Что мне нужно "решить", так это просто удалить конфликтующие теги из конфликтующих файлов.
- Я не понимаю причины конфликтов
- Я хотел бы решить это вручную, а затем объединить / cherry-pick без необходимости создавать новые коммиты
- потому что фиксация просто разрешит некоторые конфликты с веткой, которая в будущем будет удалена
- при удалении ветки этот коммит не будет иметь смысла / позиции в истории репозитория
[[РЕД. 2 ]]
Более того, если я попытаюсь сделать git cherry-pick master / C3, я получу:
в коммит не было внесено никаких изменений (используйте "git add" и / или "git commit -a") Предыдущий вишневый пик теперь пуст, возможно, из-за разрешения конфликта.
Я не понимаю, почему у меня есть конфликты в противоположном направлении (от объекта к мастеру)
[[РЕДАКТИРОВАТЬ 3 - Повтор с самого начала! ]]
Вот что я тоже попробовал.
Сделал две копии главной ветви с C3 в качестве последнего коммита с именами: master_copy и repeat_feature
git checkout master
/git branch master_copy
/git branch repeat_feature
- Каждый коммит, выбранный вишней, из ветви функций, до C5, в repeat_feature
git checkout repeat_feature
/git cherry-pick C2^..C5
(из фича)
- (У меня нет конфликтов)
- Пытался выбрать вишню С5 в master_copy, из repeat_feature
- помните, что repeat_feature было начато с C3 (поэтому, если был какой-то конфликт, их следует поднимать при выборе вишни с C2 до C5)
git checkout master_copy
/git cherry-pick repeat_feature_C5
У меня до сих пор такие же конфликты!
Даже если я начинал с того же коммита C3 (когда клонировал ветку в ветвь repeat_feature) и пытался выбрать вишню для того же коммита C3 (в master_copy)!
Я совершенно не понимаю, что происходит и почему я получаю эти пустые конфликты, которые мешают мне перенести мою функцию в основную ветку.
Предложение эксперта необходимо здесь.
2 ответа
Я закончил менять подход:
- Я сделал копию _feature_branch_ (
git checkout feature_branch
/git checkout -b copy_feature_branch
); - Я "сжал" все коммиты ветви в один
- первое: я возвращаюсь к родительскому коммиту ветки:
git reset <branch_parent_commit>
- первое: я возвращаюсь к родительскому коммиту ветки:
- второе: я заново добавляю все изменения с
git add .
, а затем совершить сgit commit
- второе: я заново добавляю все изменения с
- наконец, я выбрал этот коммит в ветку master, применив все свои изменения из feature_branch всего за один коммит (как я хотел сделать с C5, неправильно интерпретируя git cherry-pick).
git checkout master
/git cherry-pick <last-commit-of-copy_feature_branch>
)
- наконец, я выбрал этот коммит в ветку master, применив все свои изменения из feature_branch всего за один коммит (как я хотел сделать с C5, неправильно интерпретируя git cherry-pick).
Таким образом, я не получаю никаких конфликтов (как я ожидаю) и получаю только один коммит, который вводит все изменения (или в любом случае "пакет" изменений) из feature_branch. Я сделал копию своей функциональной ветви, чтобы на некоторое время иметь полную последовательность WIP- коммитов, которая может быть полезна некоторое время (для тестирования, применения исправлений, просмотра истории изменений для конкретной функции). Вместо удаления ветки я обычно переименовываю ее git branch -m <current_name> FINISHED_<current_name>
и держите это, пока я не уверен, что хочу удалить это.
Это не замечательный рабочий процесс, но на самом деле он работает для меня, ожидая, чтобы найти лучший способ удовлетворить мои потребности.
К сожалению, я до сих пор не могу объяснить конкретную логику, вызывающую конфликты при выборе вишни только одного последнего коммита (частичное изменение функции). Я знаю, что я делал неправильно, но не знаю, как возник этот конфликт с этими конкретными частями файла.
Я хочу избежать коммитов в моей истории о чем-то, что не связано напрямую с реализациями.
Поскольку я прочитал множество ответов на эту тему на SO
Я мог бы сказать, что большинство людей советуют не использовать ненужные git cherry-pick
,
Да, cherry-pick
не для слияния чего-то, что было разработано через кучу коммитов. Это для применения небольших изменений от одной ветви к другой для кодовых строк, которые обе ветви не изменили в своих других коммитах.
Основной возможностью является слияние feature
C5
государство для master
избегая грязного C2
а также C4
это использовать сквош.
1. Использование merge
:
git checkout master
git merge --squash feature
2. Использование rebase
:
Это можно сделать с помощью интерактивной перебазировки:
git checkout feature
git rebase -i master
Затем вы должны изменить pick
в squash
для всех коммитов, кроме одного.
Кроме того, все ваши временные сообщения о коммитах начинаются с squash!
или же fixup!
слово. Тогда вы сможете использовать autosquash
(все временные коммиты появятся с этим ключевым словом в списке при перебазировании)
git checkout feature
HASH=`git merge-base --fork-point master`
git rebase -i $HASH --autosquash