Subversion: как объединить только определенные ревизии в транк, когда в ветке делается несколько последовательных изменений?
Я использовал TortoiseSVN, svn и subclipse, и я думаю, что понимаю основы, но есть одна вещь, которая меня давно беспокоит: слияние приводит к появлению нежелательного кода. Вот шаги.
trunk/test.txt@r2
, Тестовый файл был создан с 'A' и возвращением:
A
[EOF]
branches/TRY-XX-Foo/test.txt@r3
, Разветвленный trunk
в TRY-XX-Foo
:
A
[EOF]
branches/TRY-XX-Foo/test.txt@r4
, Внесла нежелательные изменения в TRY-XX-Foo
и совершил это:
A
B (unwanted change)
[EOF]
branches/TRY-XX-Foo/test.txt@r5
, Сделано важное исправление ошибки в TRY-XX-Foo
и совершил это:
A
B (unwanted change)
C (important bug fix)
[EOF]
Теперь я хотел бы объединить только важные исправления ошибок с магистралью. Итак, я запускаю слияние для ревизии 4:5
, То, что я заканчиваю в моем рабочем каталоге, является конфликтом.
trunk/test.txt
:
A
<<<<<<< .working
=======
B (unwanted change)
C (important bug fix)
>>>>>>> .merge-right.r5
[EOF]
Вопреки моей воле, Subversion теперь включила "нежелательные изменения" в код транка, и мне нужно отсеять их вручную. Есть ли способ объединить только указанные ревизии, когда в ветке делается несколько последовательных изменений?
Часть проблемы заключается в том, что B (без изменений) включено в.merge-right, и я не могу определить разницу между ревизией. Я обычно использую TortoiseMerge и вот как это выглядит.
8 ответов
Проблема в том, что оба SVN
A
<<<<<<< .working
=======
B (unwanted change)
C (important bug fix)
>>>>>>> .merge-right.r341
и TortoiseSVN рассматривает ситуацию как двустороннее слияние. Я слышал о термине трехстороннее слияние, поэтому я дал Beyond Compare шанс. С быстрой настройкой TortoiseSVN, Edit Conflict теперь выводит следующий экран. Это не идеально, поскольку все еще требует вмешательства человека, но, по крайней мере, я могу сказать, какие изменения происходят откуда.
Слияние только ревизий 4,7 и 11-15 с svnmerge:
svnmerge.py merge -r4,7,11-15
И с обычным SVN:
svn merge -c4,7 -r10:15 http://.../branches/TRY-XX-Foo
Я полагаю, что вы правильно включаете ревизии, но алгоритм слияния не может найти место для вставки требуемого изменения и, таким образом, также включает в себя строку над ним. Вот те же шаги, но с другим набором изменений, и я считаю, что это работает так, как вы ожидали изначально:
$ svnadmin создать репо Файл $ svn mkdir -m ''://`pwd`/repo/trunk Совершенная редакция 1. Файл $ svn mkdir -m ''://`pwd`/repo/branch Совершенная редакция 2. $ svn co file://`pwd`/repo/trunk co.trunk Проверено ревизия 2. $ cat > co.trunk/test.txt << EOF > А > B > C > EOF $ svn add co.trunk/test.txt Co.trunk / test.txt $ svn commit -m '' co.trunk Добавление co.trunk / test.txt Передача файловых данных. Совершенная редакция 3. $ svn copy -m '' file://`pwd`/repo/trunk file://`pwd`/repo/branch / testbr Совершенная редакция 4. $ svn co file://`pwd`/repo/branch / testbr co.testbr Co.testbr / test.txt Проверил ревизию 4. $ cat > co.testbr/test.txt << EOF > А > A1 нежелательный > B > C > EOF $ svn commit -m '' co.testbr Отправка co.testbr / test.txt Передача файловых данных. Совершенная редакция 5. $ cat > co.testbr/test.txt << EOF > А > A1 нежелательный > B > В1 хотел > C > EOF $ svn commit -m '' co.testbr Отправка co.testbr / test.txt Передача файловых данных. Совершенная редакция 6. $ svn merge -r 5:6 file://`pwd`/repo/branch /testbr co.trunk --- слияние r6 в 'co.trunk': U co.trunk/test.txt $ cat co.trunk/test.txt В В1 хотел С
В TortoiseSVN вы должны указывать только те ревизии, которые хотите объединить. В отличие от клиента командной строки, где вы должны указать, например, -r4:5, чтобы объединить изменения между r4 и r5, вам нужно только указать "5" в качестве номера редакции для объединения в диалоге объединения TortoiseSVN. Если вы не уверены, всегда используйте диалоговое окно журнала в диалоговом окне слияния и выберите ревизии, которые вы хотите объединить, в этом диалоговом окне журнала (затем нажмите кнопку ОК, и выбранные ревизии автоматически установятся в диалоговом окне слияния).
Что касается разрешения вашего конфликта в TortoiseMerge: согласно скриншоту в вашем вопросе, TortoiseMerge показывает две конфликтующие строки (те, что показаны как "????" в нижнем представлении). Что вы хотите, чтобы включить изменение "C", но не "B"?
- щелкните левой кнопкой мыши на первом "???" линия, чтобы выбрать его, затем щелкните правой кнопкой мыши, выберите "использовать блок из" шахты "" из контекстного меню
- щелкните левой кнопкой мыши на втором "???" выберите его, затем щелкните правой кнопкой мыши, выберите "использовать блок из" своих "" в контекстном меню.
- Нажмите кнопку сохранения (или Файл-> Сохранить)
- При желании нажмите на кнопку "Пометить как решенную"
Чтобы уточнить слияние, нужно сказать, что на самом деле есть 2 шага.
- сливаться
- совершить
Таким образом, это означает, что после того, как ваше слияние будет завершено, вы можете выполнить ручное сравнение с головой и другой веткой, чтобы убедиться, что слияние было правильным. И если с этим что-то не так, как в вашем случае, вы можете вручную исправить это перед фиксацией.
/ Johan
Как отмечают другие пользователи (я не буду брать на себя ответственность за то, что заметил это, потому что я этого не сделал), это может быть тривиальная природа этого слияния (то есть отсутствие контекста вокруг изменений), которая сбивает с толку инструменты.
Я делаю много слияний, и, как вы обнаружили, инструмент слияния, предоставленный Tortoise, ужасен. Трехсторонний инструмент слияния абсолютно необходим, если вы делаете это очень часто. Beyond Compare - мой личный фаворит, но есть и другие, которые бесплатны (Meld, KDiff3) и те, которые не являются бесплатными (Araxis).
Вы заметите, что Beyond Compare в конце концов поступил правильно, даже если он заставит вас вручную проверить его правильность!
Другая вещь, которую вы могли бы сделать, это вручную отменить неудачный коммит в ветви, что затем позволит вам слить ветку обратно в ствол, как вы это обычно делаете.
TortoiseSVN
Используя TortoiseSVN, вы открываете представление журнала для файла, выбираете версию, которая нарушает работу, и выбираете "Вернуть изменения из этой ревизии" в меню правой кнопки мыши. Зафиксируйте изменения, внесенные в вашу рабочую копию, и вы сможете легко объединить ветку.
Командная строка
Чтобы сделать это с клиентом командной строки, вы выполняете обратное слияние (это взято из Pragmatic Source Control с использованием книги Subversion), где вы объединяете изменения между ошибочной версией и предыдущей версией в рабочую копию файла. Затем, как указано выше, вы фиксируете изменения и затем можете переходить как обычно. В вашем примере вы бы сделали что-то вроде:
svn merge -r 4:3 test.txt
Если вы не хотите нежелательного изменения, не объединяйте редакцию 4:5, а просто редакцию 5. Это означает, что вы объединяете изменение, зафиксированное в редакции 5.