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 и вот как это выглядит.

text.txt.working

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 шага.

  1. сливаться
  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.

Другие вопросы по тегам