Это старая документация по работе с SVN, в данный момент код почти везде переехал в hg, однако, если вы в наши дни работаете с svn некоторые советы и рецепты отсюда вы можете найти полезными. Настоятельно рекомендую прочитать http://svnbook.red-bean.com/nightly/en/index.html целиком, и читать нужные разделы этой книги когда вы хотите сделать что-то из этих советов.
- репо design 700GB, только svn.
- на дев сервере работает 70 человек, у многих чекаут нескольких проектов, в проекте хранитятся и ассеты: картинки, флешки. Размер чекаута имеет значение.
- локальные ветки
- Про локальные ветки: можно сделать что-то в локальной ветки и забыть на ноуте. Или HDD сгорел и всё. Наличие локальных веток располагает к локальным изменениям которых нет на сервере.
- Вопросы с избирательным перекидыванием коммитов принципиально лучше не становятся.
- Работа с ветками принципиально лучше не становится. (на самом деле таки становится)
- Держать git/hg для кода и svn для ассетов, это точно хуже чем svn для всего (ага, в 2018 году на гитхабе используем git, во внутренней разработке hg и svn для ассетов, собери три vcs и получи ачивку!)
- Ветвить разрешено только из одной точки. Обычно это корень репо. Категорически запрещается создавать мержинфо в любых подкаталогах!!! При обнаружении трубить вот все трубы и чинить. (можно если очень осторожно, но вообще лучше считать что нельзя)
есть ^/trunk ^/branches ^/tags
- Дев инсталляция - инсталляция продукта для работы геймдизайнеров, художников и всех желающих для разработки и проверки функциональности.
- QA инсталляция - инсталляция продукта для проверки функциональности стабилизированного состояния, для репетиции выкатки, это симуляция боя.
- Бой - инсталляции продукта с которыми работают пользователи.
- ^
- mergeinfo
- --reintegrate
- Мы девелопим всякие мелкие штуки в ^/trunk
- Иногда мы делаем фичебранчи. Иногда не делаем.
- Мы делаем стейбл теги.
- Мы катим в бой только теги.
- Мы никогда не коммитим в теги. Если надо добавить что-то в стабильный тег, то это новый стабильный тег. (Хотя бывают редкие исключения когда баг вылавливается в бою, там будет коммит с боя в тег потом мердж его в транк и потом из транка в стейблы).
- Мы делаем хотфиксы в транке и мержим их в стейблы, а не наоборот. Объяснение: Фикс в первую очередь не должен потеряться потому сначала транк, а потом мерж в стейбл, иначе пофиксив в стейбле и удостоверившись что на QA и в бою всё работает можно забыть.
- Мы фиксируем externals в стабильных ветках и бранчах
- Стейблы порождаются из транка, а не из других стейблов, ибо наследование стейблов это система с накоплением ошибки. Если мы используем --record-only например или странные мерджи. Новый стейбл не наследует косяков предыдущих.
- Мы хотим как-то помечать что бранчи реинтегрированы в транк //TODO рассмотреть как
- Переходим в корень working copy
- svn up // всегда надо апаться
- svn st // смотрим что у нас, ревьювим, там со статусом ? только то что мы хотим закоммитить, если там есть с таким статусом что-то что мы не хотим коммитить то предварительно добавим это в svn:ignore
- svn add --force . // рекурсивно добавит всё что не добавлено.
- svn st // теперь ни одного файла с ? нету.
Кейс 1. Мы сделали так, что working copy в транке, есть какие-то локальные изменения (это может быть либо написали новое, либо мердж фичебранча.)
- Переходим в корень working copy
- svn up // всегда надо апаться
- svn st // смотрим что у нас, ревьювим перед коммитом
- svn info // всегда проверяем где мы находимся и куда коммитим, например мы в транке
- svn ci -m 'super feature' // коммитим.
- svn up // всегда надо апаться
- Теперь мы идём на дев инсталляцию которая смотрит в транк и проверяем что всё ок.
- svn up // всегда надо апаться
- svn st // проверяем что working copy не содержит изменений
- svn ls ^/branches //смотрим тут какие есть стейбл бранчи и выбираем в какой мы хотим это поместить. Обычно это последний. Или всего много и мы хотим новый
- svn sw ^/branches/stable-3 // переключаемся на стейбл
- svn pg svn:mergeinfo // смотрим какие коммиты из транка были уже смерджены, чтобы понять насколько глубоко надо смотреть историю транка
- svn log -l n ^/trunk // смотрим что тут есть
- svn merge ^/trunk -r n1:n2 // мержим в свою локальную working copy, это операция сторого локальная и если не нравится можно ревертнуть. Могут возникнуть конфликты, но редко.
- тут нужно проверить что всё в принципе работает.
- см Кейс 1.
- svn pg svn:externals . // смотрим что с externals, с какой версией работал транк
- svn cp ^/trunk ^/branches/stable-4 -m 'new branch for this fetures' // новый бранч для фич, это сразу удалённая операция
- svn sw ^/branches/stable-4
- svn ps ... // TODO // фиксируем externals
- см Кейс 1.
- svn up // всегда надо апаться
- Теперь идём на QA инсталляцию и тестируем стейбл там.
- svn ls ^/tags/ // смотрим какой стейбл тег есть последний, например stable-3.0
- svn cp ^/branches/stable-3 ^/tags/stable-3.1
- Теперь идём на QA инсталляцию и тестируем это там.
- Теперь можно свичнуть в бою на этот тег
Кейс 4. Новый бранч. Мы хотим девелопить что-то в новом фиче бранче, или наделали что-то в working copy и хотим отправить в новый бранч.
-
svn up // всегда надо апаться
-
svn st // тут может быть и не пусто, но т.к. мы сделали ап, а cp это удалённая команда, свитч пройдёт гладко без конфликтов и косяков.
-
svn info // всегда проверяем где мы находимся
-
svn cp ^/trunk ^/branches/my-feature-branch -m 'branch for my crazy feature' //создаём бранч для фичи
-
svn sw ^/branches/my-feature-branch
-
девелопим.
-
Периодически синкаем транк к себе, Кейс 5. Дабы разруливать конфликты по мере возникновения, а не пачками потом. Опционально. Злобные буратины могут этого не делать и разруливать потом гору конфликтов.
-
svn up // всегда надо апаться
-
svn st // тут должно быть чисто, если не чисто, идём в Кейс 1 и коммитим
-
svn info // всегда проверяем где мы находимся и куда коммитим, в данном случае мы в фичебранче
-
svn merge ^/trunk // просто синкануть всё что есть в транке. Тут могут возникнуть конфликты, разруливаем на месте.
-
svn st // смотрим что приехало, что все конфликты которые и были разрешены
-
svn ci -m "sync with trunk" // коммитим синк, можно, если не лень писать 'MFC n1:n2'
- svn up // всегда надо апаться
- svn st // тут должно быть чисто, если не чисто, идём в Кейс 1 и коммитим
- svn sw ^/branches/my-feature-branch // свичнемся на бранч, если не были в нём.
- Делаем Кейс 5 для синка в транка. Этим мы сильно уменьшаем вероятность конфликта при merge.
- svn sw ^/trunk // переключаемся на транк
- svn merge ^/branches/my-feature-branch // мержим на свою working copy бранч, конфликтов быть не может т.к. мы только что синхронизировали бранчи. Может быть конфликт если от синка до текущего момента кто-то что-то коммитнул в транк
- svn st //смотрим что всё хорошо
- проверяем что оно в принципе работает
- svn ci -m 'reintegrated feature' // коммитим всё это дело.
- по желанию можно удалить фичебранч // TODO возможно не удаляем а маркируем как-то их
- // TODO: рассмотреть можно ли продолжать работу в бранче
- svn up // всегда надо апаться
- svn st // проверяем что working copy не содержит изменений
- svn info // всегда проверяем где мы находимся, например в транке
- svn log -l 10 // смотрим на лог, например нам не нравится коммт 25, который на самом деле дифф между ревизиями 24:25
- svn megre ^/trunk -r 25:24 // мержим этот же бранч на working copy в обратном порядке, svn понимает это именно так, применение диффа в обратную сторону, что по сути есть откат коммита
- svn st // смотрим на всякий случай
- svn ci -m 'reverted commit 25' //коммитим это
Кейс 8. Почему избирательные мержи коммитов в неправильном порядке могут быть опасны и почему за ними надо внимательно следить.
- потому что при удалении несуществующей строки свн и глазом не моргнёт и пропустит мерж. при накате потом добавленной строки добавит // TODO
Кейс 10. Как пометить коммит что он никогда не должен попасть в конкретный стейбл. --record-only и зачем он нужен. // TODO
- svn co svn://svn.crazypanda.ru/farmstory/client/trunk --depth=empty farmstory-client
- cd farmstory-client
- svn up --set-depth=infinity ai assets3d fla
- открываете repo browser
- выбираете ревизию http://service.crazypanda.ru/v/clip2net/y/A/4yg8lNlaKb.png
- и смотрите там, это без апа на версию, немного быстрее
- http://service.crazypanda.ru/v/clip2net/h/M/kGhFX93HDS.png
- Другой вариант это апнуться на версию до переноса и смотреть там любыми тулами
- И ещё вариант svn diff -r NUMBER ^/path/to/file (именно удалённый путь) или svn log или что там может быть ещё надо
Кейс 15. У нас много изменений над транком, транк давно не апали, ап на локальной копии при водит к конфликтам, не хотим апать а хотим отправить в ветку.
-
svn info //смотрим ревизию
-
svn cp ^/trunk ^/branches/myTrash -r ревизию -m 'new branch for this fetures'
-
svn diff ^/trunk ^/branches/myTrash // тут убеждаемся что транк ушёл от того что мы скопировали
-
svn sw ^/branches/myTrash
-
svn ci -m 'blah blah'
-
мержить назад как обычно. Отдельно пояснить разницу между этим подходом и svn cp . ^/branches/myTrash т.к. в данном случае улетит прям твой бранч локальный без знания о том что он диф над веткой, потом заколебёшься мержить
- // TODO: есть утверждение что --parents не требуется в данном случае
- svn mkdir --parents ^/client/tags -m " Creating tags folder"
-
Проект устроен так: в транке несколько папок, каждая по сути сама по себе проект, например в данном случае проект и тесты. Ветвим только а верхнем уровне.
-
Случайно переключил только проект на новый фичебранч и коммитнул потом скопом одним коммитом в фичебранч код и тесты в транк. Это один коммит. Хотим пофиксить.
-
выглядит так http://service.crazypanda.ru/v/clip2net/N/2/itN5B76XIN.png
-
svn up
-
svn info // убеждаемся что мы в транке, смотри неудобный коммит
-
svn merge ^/client/trunk -r9405:9404 // реверсмёржим неудобный коммит
-
svn ci -m 'removing mistaken commit' // коммитим
-
svn sw ^/client/branches/soft-tutor // переключаемся на проблемную ветку
-
svn merge ^/client/trunk // полюбому синкаем потому что рассинхрон не нужен, видим что код который мы удалили из транка, удалён и в ветке.
-
svn ci -m 'sync with trunk' // коммитим в ветку всё синканутое
-
тут я сознательно развожу мерж коммиты отдельно. Поверьте так проще.
-
svn merge ^/client/trunk -r9404:9405 --ignore-ancestry // вот тут мы мержим заново то что было удалено, без --ignore-ancestry мёрж выходит пустым, потому что в мержинфо указано что эти коммиты уже смержены
-
svn ci -m 'fixing test' // коммитим уже поправленное.
-
Вуаля, факир был трезв и фокус удался. Реинтегрируется нормально и без проблем.
- с консоли видимо никак
- http://stackoverflow.com/questions/2803823/how-can-i-delete-all-unversioned-ignored-files-folders-in-my-working-copy
- right-click on working copy folder, while holding the shift-key down, choose "delete unversioned items"
svn cp --parents https://svn.example.org/svnroot/ph/org/trunk/repo https://svn.example.org/svnroot/ph/org/branches/foo/repo -m "Create a 'foo' branch of /trunk/repo"