Subversion: как объединить только определенные ревизии в транк, когда в ветке делается несколько последовательных изменений? - PullRequest
15 голосов
/ 29 ноября 2008

Я использую 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 ]

37 голосов
/ 29 ноября 2008

Слияние только ревизий 4,7 и 11-15 с svnmerge :

svnmerge.py merge -r4,7,11-15

И с обычным SVN:

svn merge -c4,7 -r10:15 http://.../branches/TRY-XX-Foo
5 голосов
/ 14 декабря 2008

Проблема в том, что оба svn

A
<<<<<<< .working
=======
B (unwanted change)
C (important bug fix)
>>>>>>> .merge-right.r341

и TortoiseSVN рассматривает ситуацию как двустороннее слияние. Я слышал о термине «трехстороннее слияние», поэтому я дал Beyond Compare шанс. С быстрой настройкой TortoiseSVN, Edit Conflict теперь выводит следующий экран. Это не идеально, так как все еще требует вмешательства человека, но, по крайней мере, я могу сказать, какие изменения происходят откуда.

См. Скриншот .

2 голосов
/ 30 января 2009

В TortoiseSVN вы должны указывать только те ревизии, которые хотите объединить. В отличие от клиента командной строки, где вы должны указать, например, -r4: 5, чтобы объединить изменения между r4 и r5, вам нужно только указать «5» в качестве номера редакции для объединения в диалоге слияния TortoiseSVN. Если вы не уверены, всегда используйте диалоговое окно журнала в диалоговом окне слияния и выберите ревизии, которые вы хотите объединить, в этом диалоговом окне журнала (затем нажмите кнопку ОК, и выбранные ревизии будут автоматически установлены в диалоговом окне слияния).

Что касается разрешения вашего конфликта в TortoiseMerge: Согласно скриншоту в вашем вопросе, TortoiseMerge показывает две конфликтующие строки (те, что показаны как «????» на виде снизу). Что вы хотите, чтобы включить изменение «C», но не «B»?

  • щелкните левой кнопкой мыши на первом «???» выберите его, затем щелкните правой кнопкой мыши, выберите «использовать блок из« шахты »» из контекстного меню
  • щелкните левой кнопкой мыши на втором '???' выберите его, затем щелкните правой кнопкой мыши, выберите «использовать блок из« своих »» в контекстном меню
  • Нажмите кнопку сохранения (или Файл-> Сохранить)
  • При желании нажмите кнопку "Пометить как разрешенное"
2 голосов
/ 29 января 2009

Хорошо, чтобы прояснить одну вещь о слиянии, это то, что оно на самом деле имеет 2 шага.

  1. Слияние
  2. Commit

Таким образом, это означает, что после того, как ваше слияние завершено, вы можете выполнить ручной diff для головы и другой ветви, чтобы убедиться, что слияние было правильным. И если что-то было не так, как в вашем случае, Вы можете вручную исправить это перед фиксацией.

/ Йохан

2 голосов
/ 28 января 2009

Я полагаю, что вы правильно включили ревизии, но алгоритм слияния не может найти место для вставки требуемого изменения и, следовательно, включая строку над ним Вот те же шаги, но с другим набором изменений, и я считаю, что это работает так, как вы ожидали изначально:

$ svnadmin create repo
$ svn mkdir -m '' file://`pwd`/repo/trunk

Committed revision 1.
$ svn mkdir -m '' file://`pwd`/repo/branches

Committed revision 2.
$ svn co file://`pwd`/repo/trunk co.trunk
Checked out revision 2.
$ cat > co.trunk/test.txt << EOF
> A
> B
> C
> EOF
$ svn add co.trunk/test.txt
A         co.trunk/test.txt
$ svn commit -m '' co.trunk
Adding         co.trunk/test.txt
Transmitting file data .
Committed revision 3.
$ svn copy -m '' file://`pwd`/repo/trunk file://`pwd`/repo/branches/testbr

Committed revision 4.
$ svn co file://`pwd`/repo/branches/testbr co.testbr
A    co.testbr/test.txt
Checked out revision 4.
$ cat > co.testbr/test.txt << EOF
> A
> A1 unwanted
> B
> C
> EOF
$ svn commit -m '' co.testbr
Sending        co.testbr/test.txt
Transmitting file data .
Committed revision 5.
$ cat > co.testbr/test.txt << EOF
> A
> A1 unwanted
> B
> B1 wanted
> C
> EOF
$ svn commit -m '' co.testbr
Sending        co.testbr/test.txt
Transmitting file data .
Committed revision 6.
$ svn merge -r 5:6 file://`pwd`/repo/branches/testbr co.trunk
--- Merging r6 into 'co.trunk':
U    co.trunk/test.txt
$ cat co.trunk/test.txt
A
B
B1 wanted
C
1 голос
/ 28 января 2009

Как отмечают другие пользователи (я не буду признателен за то, что заметил это, потому что я этого не сделал), это может быть тривиальная природа этого слияния (то есть отсутствие контекста вокруг изменений), которая сбивает с толку инструменты.

Я много делаю слияния, и, как вы обнаружили, инструмент слияния, предоставленный Tortoise, ужасен. Трехсторонний инструмент слияния абсолютно необходим, если вы делаете это очень часто. Beyond Compare - мой личный фаворит, но есть и другие, которые бесплатны (Meld, KDiff3) и те, которые не являются бесплатными (Araxis).

Вы заметите, что Beyond Compare в конце концов поступил правильно, даже если он заставляет вас вручную проверить его правильность!

1 голос
/ 28 января 2009

Еще одна вещь, которую вы могли бы сделать, это вручную отменить неудачный коммит на ветке, который затем позволит вам слить ветку обратно в ствол, как вы это обычно делаете.

TortoiseSVN

Используя TortoiseSVN, вы открываете представление журнала для файла, выбираете версию, которая нарушает работу, и выбираете «Вернуть изменения из этой ревизии» в меню правой кнопки мыши. Зафиксируйте изменения, внесенные в вашу рабочую копию, и вы сможете легко объединить ветку.

Командная строка

Чтобы сделать это с клиентом командной строки, вы выполняете обратное слияние (это взято из Pragmatic Source Control с использованием книги Subversion), где вы объединяете изменения между ошибочной версией и предыдущей версией в рабочую копию файла , Затем, как указано выше, вы фиксируете изменения и затем можете переходить как обычно. В вашем примере вы бы сделали что-то вроде:

svn merge -r 4:3 test.txt
0 голосов
/ 29 ноября 2008

Если вы не хотите нежелательного изменения, не объединяйте редакцию 4: 5, а просто редакцию 5. Это означает, что вы объединяете изменение, зафиксированное в редакции 5.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...