SVN: Освободить головные боли в ветвях, как объединить ревизии веб-сайта, когда и когда их очистят, чтобы начать работу? - PullRequest
12 голосов
/ 05 февраля 2010

Мне нужна проверка работоспособности, если мы можем, любые идеи по исправлению / изменению следующего очень приветствуются! В последнее время мы ссорились с нашей SVN и пытаемся исправить это, внедрив систему Trunk / Release.

У нас есть большой веб-сайт, который мы разрабатываем, и мы храним все это в SVN. Вот что мы имели в виду:

  • У нас есть ствол и ветвь релиза
  • Вся работа проверяется в багажнике.
  • Когда функция считается готовой к следующему выпуску, она объединяется в ветку Release.
  • У нас есть только одна ветвь релиза и мы просто помечаем «Последние», когда мы выполняем push to live
  • Мы надеемся, что сможем изменить все файлы с Последнего на Голову, чтобы получить ZIP-файл, который мы можем загрузить (какие-нибудь идеи относительно простого способа сделать это с помощью сценариев?)

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

Мы работаем над множеством различных функций / исправлений / проблем одновременно, и они не все хорошо проверены в полной функциональности (но всегда работают по крайней мере). Тогда иногда вам приходится ждать, пока клиенты подпишутся. В результате вы получаете ревизии, которые «готовы к жизни» и разбросаны с ревизиями, над которыми «все еще работают» в багажнике. Это означает, что завершенные ревизии объединяются не последовательно, а по порядку. Я думал, что SVN может справиться с этим, умная мелочь, но, видимо, нет.

Вот пример:

  • Пит меняет CSS, чтобы новая кнопка выглядела красиво (Версия 1)
  • Дейв добавил немного CSS в конец того же CSS-файла, что и Пит, для новой функции (Редакция 2)
  • Мод Дэйва получает узел, поэтому он объединяет его с Release и фиксирует в сообщении журнала с указанием номера ревизии и идентификатора отслеживания ошибки.
  • Пит добавляет больше кнопок, чтобы закончить этот мод, хотя CSS здесь не меняется (Версия 3)
  • Затем Пит объединяет свои моды (Редакция 1 и 3) с Главой релиза (в которой есть слияние Дейва), но это перезаписывает добавления CSS Дейва, которые теперь полностью исчезают.

Это приводит к тому, что сайт ломается и ветка Release становится практически бесполезной.

Итак, мы попробовали некоторые другие идеи, такие как возврат релиза обратно к «Последнему», а затем просто слияние всех ревизий 1,2 и 3 по порядку. Это работало нормально, пока у нас не было Revision 4, которая не была готова к работе, и Revision 5, которая была. Внезапно мы снова попадаем в узлы с точно такой же проблемой!

Хорошо, возьми три. Вернитесь к Последнему, объединитесь в Версии 5, затем сделайте любое обновление назад к Главе. Дерево конфликтов в изобилии! Так вот нет нет.

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

HELP! Какого черта мы делаем неправильно? Кажется, я не могу найти решения этой проблемы, когда требуются разные, не последовательные версии в выпуске. Если это невозможно, то это нормально, но как, черт возьми, мы должны легко жить. Мы не можем переходить на каждое изменение, сайт занимает 30 минут +, чтобы проверить, что это займет слишком много времени.

Примечание: мы используем TortoiseSVN, поэтому мы можем свести к минимуму примеры командной строки в любых ответах?

Последняя версия TSVN и SVN версии 1.6, поэтому у нас есть прикольное отслеживание слияний и т. Д.

РЕДАКТИРОВАТЬ: Отличный пост в блоге, посвященный циклу разработки / выпуска (хотя и с использованием GIT, но все еще актуальным), думал, что все захотят прочитать его, если найдут этот вопрос интересным. (http://nvie.com/git-model)

РЕДАКТИРОВАТЬ 2: Я написал сообщение в блоге о том, как показать, над какой веткой вы работаете на своем веб-сайте, о чем другие спрашивали меня (http://www.offroadcode.com/2010/5/14/which-svn-branch-are-you-working-on.aspx). Надеюсь, это поможет. Тем временем мы смотрим на Kiln и надеясь переключиться в следующем месяце (глоток!)

Ответы [ 5 ]

13 голосов
/ 08 февраля 2010

Какого черта мы делаем неправильно?

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

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

См:

5 голосов
/ 09 февраля 2010

Давайте попробуем сценарий, который вы описали, и посмотрим, что на самом деле происходит (я использую командную строку по понятным причинам, но в TortoiseSVN она работает так же):

# let's create a simple repository for testing and add some baseline data:
$ svnadmin create test

$ svn import baseline file:///path/to/repo/test/trunk -m "Import baseline"
Adding         baseline/other.txt
Adding         baseline/css.txt

Committed revision 1.

# now create a branch:
$ svn copy file:///path/to/repo/test/trunk file:///path/to/repo/test/branches/r1 -m "branched" --parents

Committed revision 2.

# Pete changes some CSS to make a new button look pretty (Revision 3)
$ svn co file:///path/to/repo/test/trunk Pete-trunk
A    Pete-trunk/other.txt
A    Pete-trunk/css.txt
Checked out revision 2.
$ svn diff Pete-trunk/
Index: Pete-trunk/css.txt
===================================================================
--- Pete-trunk/css.txt  (revision 2)
+++ Pete-trunk/css.txt  (working copy)
@@ -1,3 +1,3 @@
 This is a test
-more lines
+more lines Pete's change
 even more
$ svn commit Pete-trunk/ -m "Pete's first change"
Sending        Pete-trunk/css.txt
Transmitting file data .
Committed revision 3.

# meanwhile, Dave add some CSS to the bottom of the same CSS file as Pete's for a new feature (Revision 4)
$ svn co file:///path/to/repo/test/trunk Dave-trunk
A    Dave-trunk/other.txt
A    Dave-trunk/css.txt
Checked out revision 3.
$ svn diff Dave-trunk/Index: Dave-trunk/css.txt
===================================================================
--- Dave-trunk/css.txt  (revision 3)
+++ Dave-trunk/css.txt  (working copy)
@@ -1,3 +1,4 @@
 This is a test
 more lines Pete's change
 even more
+Dave's change
$ svn commit Dave-trunk/ -m "Dave's change"Sending        Dave-trunk/css.txt
Transmitting file data .
Committed revision 4.

# Dave's mod gets the nod so he merges it into Release and commits it (Revision 5)...
$ svn co file:///path/to/repo/test/branches/r1 Dave-branch
A    Dave-branch/other.txt
A    Dave-branch/css.txt
Checked out revision 4.
$ svn merge -c4 file:///path/to/repo/test/trunk Dave-branch
--- Merging r4 into 'Dave-branch':
U    Dave-branch/css.txt
$ svn diff Dave-branch/

Property changes on: Dave-branch
___________________________________________________________________
Added: svn:mergeinfo
   Merged /trunk:r4

Index: Dave-branch/css.txt
===================================================================
--- Dave-branch/css.txt (revision 4)
+++ Dave-branch/css.txt (working copy)
@@ -1,3 +1,4 @@
 This is a test
 more lines
 even more
+Dave's change
$ svn commit Dave-branch/ -m "Merged Dave's change to release"
Sending        Dave-branch
Sending        Dave-branch/css.txt
Transmitting file data .
Committed revision 5.

# Pete adds more buttons to finish this mod, no CSS changes here though (Revision 6)
$ svn diff Pete-trunk/Index: Pete-trunk/other.txt
===================================================================
--- Pete-trunk/other.txt    (revision 2)
+++ Pete-trunk/other.txt    (working copy)
@@ -1 +1,2 @@
-another file
\ No newline at end of file
+another file
+Unrelated change
\ No newline at end of file
$ svn commit Pete-trunk/ -m "Pete's second change"Sending        Pete-trunk/other.txt
Transmitting file data .
Committed revision 6.

# Pete then merges his mods (Revision 3 and 6) into the Head of Release (which has Daves merge in it)
$ svn co file:///path/to/repo/test/branches/r1 Pete-branch
A    Pete-branch/other.txt
A    Pete-branch/css.txt
 U   Pete-branch
Checked out revision 6.
$ svn merge -c3,6 file:///path/to/repo/test/trunk Pete-branch
--- Merging r3 into 'Pete-branch':
U    Pete-branch/css.txt
--- Merging r6 into 'Pete-branch':
U    Pete-branch/other.txt
$ svn diff Pete-branch/
Property changes on: Pete-branch
___________________________________________________________________
Modified: svn:mergeinfo
   Merged /trunk:r3,6

Index: Pete-branch/other.txt
===================================================================
--- Pete-branch/other.txt   (revision 6)
+++ Pete-branch/other.txt   (working copy)
@@ -1 +1,2 @@
-another file
\ No newline at end of file
+another file
+Unrelated change
\ No newline at end of file
Index: Pete-branch/css.txt
===================================================================
--- Pete-branch/css.txt (revision 6)
+++ Pete-branch/css.txt (working copy)
@@ -1,4 +1,4 @@
 This is a test
-more lines
+more lines Pete's change
 even more
 Dave's change
$ svn commit Pete-branch/ -m "Merged Pete's changes"Sending        Pete-branch
Sending        Pete-branch/css.txt
Sending        Pete-branch/other.txt
Transmitting file data ..
Committed revision 7.

# Now the test: is Dave's change still there? Yes!
$ svn cat file:///path/to/repo/test/branches/r1/css.txt
This is a test
more lines Pete's change
even more
Dave's change

Проблема не произошла, понимаете? И это все равно было бы верно, если бы мы сделали шаги в другом порядке - попробуйте!

Так что может пойти не так? Скорее всего, неправильное разрешение конфликтов слияния:

Например, возможно, Пит проверил свою рабочую копию ветви, прежде чем Дейв объединил свои изменения. Он все еще может слить свои изменения в порядке, но когда он попытается зафиксировать, svn пожалуется, что его рабочая копия устарела. Он должен обновить свою рабочую копию. Это добавит изменения Дэйва в его рабочую копию; поскольку изменение Дэйва влияет на тот же файл, который изменил и Питер, SVN попытается объединить изменения в файле. Если изменения далеко друг от друга, это будет выполнено автоматически.

Но если изменения находятся на одной линии или очень близко друг к другу, SVN не сможет объединить их и пометить их как конфликтующие. Теперь Пит должен разрешить конфликт. Один из вариантов - просто использовать его версию, отбрасывая изменения Дэйва. Если он сделает это, изменения Дэйва будут потеряны . Вместо этого он должен отредактировать файл (с помощью TortoiseMerge или, возможно, вручную), чтобы он содержал оба изменения.

2 голосов
/ 05 февраля 2010

Обычно люди развиваются в транке, как и вы, и в какой-то момент решают выпустить таким образом ветвление с именем "release_something". Это не постоянный процесс слияния вещей в релизе, насколько это возможно, а скорее процесс тегов и заморозки :-). Тогда работа, выполняемая над веткой релиза, будет состоять в основном из исправлений ошибок, которые также будут объединены как можно скорее в стволе: с этим типом процесса это будет намного проще.

Из того, что вы говорите, что хотите достичь, кажется, что вы правы: лучшее решение было бы иметь одну ветвь для каждой функции, а затем объединить их одну за другой в стволе и выборочно в ветке выпуска. Subversion, похоже, не лучший инструмент для такого развития. Если вы использовали DVCS, такой как hg или git, у вас мог бы быть один репозиторий для каждого разработчика, попросив их как можно скорее объединить / протолкнуть их наборы изменений в транк, чтобы протестировать максимум функций, объединенных вместе, и найти потенциальные проблемы. , Но у вас также будет еще один репозиторий, называемый «релиз», поддерживаемый только одним человеком, который будет выборочно извлекать такую ​​или такую ​​функцию / патч из ваших репозиториев разработчиков. Например, в hg, который я знаю лучше, когда вы извлекаете изменения, которые еще не были объединены (например, из dev-репо в релиз-репозиторий), создаются несколько «голов», то есть какие-то анонимные ветви, и вы может решить изменение за изменением, функция за функцией, если вы хотите объединить эти "головы" в основную ветвь не.

Я полагаю, что из-за этой гибкости и того, что инструменты DVCS способны обрабатывать ветви и слияния намного лучше, чем централизованные инструменты, это намного лучше соответствовало бы вашим потребностям.

Надеюсь, это поможет.

Приветствия
Christophe.

= Они всегда говорят, что время меняет вещи, но у вас действительно есть =
= изменить их самостоятельно. - Энди Уорхол =

0 голосов
/ 15 февраля 2010

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

root
 - tags
    - project-name-1.0.1
    - project-name-1.0.2
    - ...
 - branches
    - reviewed
    - stable
 - trunk

Все коммиты выполняются в trunk, так же, как вы делаете сейчас. Это полезно, потому что вы улавливаете все конфликты во время начальной регистрации кода.

Однако вместо объединения изменений в стабильную ветвь вы объединяете изменения для версий утвержденных / проверенных исправлений ошибок или функций в нечто вроде branches/reviewed. Хорошей практикой может быть указание номера билета и оригинальной версии в svn:log. Затем, когда вы будете готовы обновить сервер утвержденными изменениями, вы можете выполнить автоматическое объединение со стабильной веткой, поскольку любые странные конфликты будут обнаружены ранее в процессе.

Со вторым шагом вы можете столкнуться с некоторыми конфликтами, так как вы применяете изменения не по порядку. Subversion должен быть в состоянии справиться с этим, но если вы столкнетесь с какими-либо проблемами, стратегия для их обхода будет такой:

Найдите ревизию в стволе, которая имеет только утвержденные изменения, затем

  1. выборочно объединить последующие утвержденные наборы изменений в порядке или
  2. Объединить все ревизии с r{all-approved} до CURRENT, затем выполнить обратное объединение каждого последующего неутвержденного набора изменений

И то, и другое будет болезненно, но опять же, это не должно случаться очень часто.

И последнее: большинство наших разработчиков используют TortoiseSVN, как и вы, но вы можете сэкономить много времени, выполняя подобные операции слияния с помощью сценариев bash или даже сценариев perl / php. Возможно, вы захотите настроить Unix Box или виртуальную машину для этой единственной цели.

0 голосов
/ 09 февраля 2010

Лучшая установка, которую я видел:

  • Багажник всегда строится и тестируется, и вы можете «вживую» с ним в любое время.
  • Вы создаете теги из магистрали, когда готовы к выпуску и экспорту из тега.
  • теги (v.1.0.233, v.1.1.013 и т. Д.)
  • Ветви - это то, где делается вся разработка. Ошибки и особенности. И сливаются в багажник после тестирования. Возможно в ветке "Тестирование".

    root
     - trunk
     - branches
       - bug 1
       - bug 2
       - feature 1
     - tags
       - v.1.0.233
       - v.1.1.013
    
...