Ответ 1
Я думаю, что нашел решение, которое постоянно фиксирует плохое слияние, и которое не требует, чтобы вы вручную проверяли любые различия. Хитрость заключается в том, чтобы вернуться в историю и генерировать коммиты параллельно с плохим слиянием.
Таким образом, у нас есть репозиторий с отдельными ветвями на поддерживаемую версию одного продукта. Подобно ситуации, возникшей в вопросе, все изменения, сделанные на ветке более ранней версии (т.е. Исправления для этой версии), должны быть в конечном итоге объединены с ветвями более поздних версий.
Итак, если что-то проверено на BRANCH_V8, оно должно быть объединено с BRANCH_V9.
Теперь один из разработчиков делает следующую ошибку: он объединяет все изменения с BRANCH_V9 в BRANCH_V8 (т.е. слияние в неправильном направлении). Кроме того, после этого плохого слияния он выполняет некоторые дополнительные коммиты, прежде чем он замечает свою ошибку.
Итак, ситуация такова, как показано в графическом журнале ниже.
o BRANCH_V8 - 13 - important commit right after the bad merge | o BRANCH_V8 - 12 - wrong merge from BRANCH_V9 |\ | o BRANCH_V8 - 11 - adding comment on BRANCH_V8 (ie. last known good state) | | o | BRANCH_V9 - 10 - last commit on BRANCH_V9 | |
Мы можем исправить эту ошибку следующим образом:
- обновите свой локальный каталог до последнего хорошего состояния BRANCH_V8:
hg update 11
- Создайте новый дочерний элемент этого последнего хорошего состояния:
- изменить файл
$EDITOR some/file.txt
(это необходимо, потому что Mercurial не разрешает пустые коммиты) - зафиксировать эти изменения
hg commit -m "generating commit on BRANCH_V8 to rectify wrong merge from BRANCH_V9"
Ситуация выглядит следующим образом:o BRANCH_V8 - 14 - generating commit on BRANCH_V8 to rectify wrong merge from BRANCH_V9 | | o BRANCH_V8 - 13 - important commit right after the bad merge | | | o BRANCH_V8 - 12 - wrong merge from BRANCH_V9 |/| o | BRANCH_V8 - 11 - adding comment on BRANCH_V8 | | | o BRANCH_V9 - 10 - last commit on BRANCH_V9
- изменить файл
-
Объедините вновь сгенерированный заголовок с ревизией, в которой произошло неудачное слияние, и отбросьте все изменения перед фиксацией. Не просто слияние двух головок, потому что после этого вы потеряете важную фиксацию, которая произошла после слияния!
- merge:
hg merge 12
(игнорировать любые конфликты) - выбросить все изменения:
hg revert -a --no-backup -r 14
- зафиксировать изменения:
hg commit -m "throwing away wrong merge from BRANCH_V9"
Ситуация теперь выглядит так:o BRANCH_V8 - 15 - throwing away wrong merge from BRANCH_V9 |\ | o BRANCH_V8 - 14 - generating commit on BRANCH_V8 to rectify wrong merge from BRANCH_V9 | | +---o BRANCH_V8 - 13 - important commit right after the bad merge | | o | BRANCH_V8 - 12 - wrong merge from BRANCH_V9 |\| | o BRANCH_V8 - 11 - adding comment on BRANCH_V8 | | o | BRANCH_V9 - 10 - last commit on BRANCH_V9 | |
Т.е. на BRANCH_V8 есть две главы: одна, которая содержит исправление плохого слияния, а другая содержит левую над важной фиксацией на BRANCH_V8, которая произошла сразу после слияния.
- merge:
- Объедините две головки на BRANCH_V8:
- merge:
hg merge
- commit:
hg commit -m "merged two heads used to revert from bad merge"
- merge:
Ситуация в конце на BRANCH_V8 теперь исправлена и выглядит следующим образом:
o BRANCH_V8 - 16 - merged two heads used to revert from bad merge |\ | o BRANCH_V8 - 15 - throwing away wrong merge from BRANCH_V9 | |\ | | o BRANCH_V8 - 14 - generating commit on BRANCH_V8 to rectify wrong merge from BRANCH_V9 | | | o | | BRANCH_V8 - 13 - important commit right after the bad merge |/ / o | BRANCH_V8 - 12 - wrong merge from BRANCH_V9 |\| | o BRANCH_V8 - 11 - adding comment on BRANCH_V8 | | o | BRANCH_V9 - 10 - last commit on BRANCH_V9 | |
Теперь ситуация на BRANCH_V8 верна. Остается только одна проблема: следующее слияние с BRANCH_V8 на BRANCH_V9 будет неправильным, так как оно будет сливаться с "fix" для плохого слияния, которое мы не хотим на BRANCH_V9. Трюк здесь состоит в том, чтобы объединиться с BRANCH_V8 в BRANCH_V9 в отдельных изменениях:
- Сначала слияния, от BRANCH_V8 до BRANCH_V9, правильные изменения на BRANCH_V8 из-за неудачного слияния.
- Второе слияние в ошибке слияния и его исправлении и, не требуя ничего проверить, выбросить все изменения.
- В-третьих, объедините оставшиеся изменения с BRANCH_V8.
Подробнее:
- Переключите рабочий каталог в BRANCH_V9:
hg update BRANCH_V9
- Слияние в последнем хорошем состоянии BRANCH_V8 (т.е. фиксация, которую вы создали для исправления плохого слияния). Это слияние является слиянием, как любое регулярное слияние, т.е. конфликты должны быть решены, как обычно, и ничего не нужно выбрасывать.
- merge:
hg merge 14
- commit:
hg commit -m "Merging in last good state of BRANCH_V8"
Ситуация сейчас:@ BRANCH_V9 - 17 - Merging in last good state of BRANCH_V8 |\ | | o BRANCH_V8 - 16 - merged two heads used to revert from bad merge | | |\ | +---o BRANCH_V8 - 15 - throwing away wrong merge from BRANCH_V9 | | | | | o | | BRANCH_V8 - 14 - generating commit on BRANCH_V8 to rectify wrong merge from BRANCH_V9 | | | | | | o | BRANCH_V8 - 13 - important commit right after the bad merge | | |/ +---o BRANCH_V8 - 12 - wrong merge from BRANCH_V9 | |/ | o BRANCH_V8 - 11 - adding comment on BRANCH_V8 | | o | BRANCH_V9 - 10 - last commit on BRANCH_V9 | |
- merge:
- Объединить неудачное слияние на BRANCH_V8 + его исправление и выбросить все изменения:
- merge:
hg merge 15
- вернуть все изменения:
hg revert -a --no-backup -r 17
- передать слияние:
hg commit -m "Merging in bad merge from BRANCH_V8 and its fix and throwing it all away"
Текущая ситуация:@ BRANCH_V9 - 18 - Merging in bad merge from BRANCH_V8 and its fix and throwing it all away |\ | o BRANCH_V9 - 17 - Merging in last good state of BRANCH_V8 | |\ +-----o BRANCH_V8 - 16 - merged two heads used to revert from bad merge | | | | o---+ | BRANCH_V8 - 15 - throwing away wrong merge from BRANCH_V9 | | | | | | o | BRANCH_V8 - 14 - generating commit on BRANCH_V8 to rectify wrong merge from BRANCH_V9 | | | | +-----o BRANCH_V8 - 13 - important commit right after the bad merge | | | o---+ BRANCH_V8 - 12 - wrong merge from BRANCH_V9 |/ / | o BRANCH_V8 - 11 - adding comment on BRANCH_V8 | | o | BRANCH_V9 - 10 - last commit on BRANCH_V9 | |
- merge:
- Объединить изменения слева от BRANCH_V8:
- merge:
hg merge BRANCH_V8
- commit:
hg commit -m "merging changes from BRANCH_V8"
- merge:
В конце ситуация выглядит так:
@ BRANCH_V9 - 19 - merging changes from BRANCH_V8 |\ | o BRANCH_V9 - 18 - Merging in bad merge from BRANCH_V8 and its fix and throwing it all away | |\ | | o BRANCH_V9 - 17 - Merging in last good state of BRANCH_V8 | | |\ o | | | BRANCH_V8 - 16 - merged two heads used to revert from bad merge |\| | | | o---+ BRANCH_V8 - 15 - throwing away wrong merge from BRANCH_V9 | | | | | | | o BRANCH_V8 - 14 - generating commit on BRANCH_V8 to rectify wrong merge from BRANCH_V9 | | | | o | | | BRANCH_V8 - 13 - important commit right after the bad merge |/ / / o---+ BRANCH_V8 - 12 - wrong merge from BRANCH_V9 |/ / | o BRANCH_V8 - 11 - adding comment on BRANCH_V8 | | o | BRANCH_V9 - 10 - last commit on BRANCH_V9 | |
После всех этих шагов, в которых вам не нужно проверять какой-либо diff вручную, BRANCH_V8 и BRANCH_V9 верны, и будущие слияния с BRANCH_V8 на BRANCH_V9 также будут правильными.