Перейти к содержимому

Git svn что это

  • автор:

Системы контроля версий: Git, SVN, Mercurial для менеджеров

Задача проектного менеджера и коммерческой разработки как таковой — ставить конкретные цели и отслеживать этапы выполнения работ.

Для этого в производственный процесс принято внедрять ежедневные митинги, таск трекеры и системы контроля версий (СКВ или VCS — Version Control System), которые мы рассматриваем как инструменты для управления проектами.

Выбор СКВ лежит на плечах технического директора, тимлидов или воли случая (“так исторически сложилось”). Вопросы о преимуществах или недостатках конкретных систем вызывают священные войны в среде разработчиков, однако, наc они итересуют только в контексте организации работы над проектом.

Популярные решения

По опыту 9 из 10 команд разработки используют Git, хотя рейтинг Tagline говорит о меньшей его популярности.

Рейтинг систем контроля версий Git, SVN, Mercurial

После Git с большим отрывом идет SVN (Subversion) и Mercurial.

Синтаксис Git сложнее в изучении, однако, по отзывам программистов он функциональнее. Очков гиту добавили и популярные ресурсы для хранения репозиториев на всевозможных языках: GitHub и BitBucket.

Долю на рынке, сопоставимую с массой электрона, занимают осталные системы : CVS (Concurrent Versions System), Team Foundation Server, Bazaar, Darcs итд.

Все системы контроля версий по сути решают 4 задачи

Доступ к коду. Исходники кода хранятся в удаленном репозитории (хранилище данных), куда обращаются разработчики, чтобы забрать актуальную версию файлов или внести изменения. Так выстраивается командная разработка.

Логирование изменений в коде. Отслеживание коммитов (внесений изменений в код), помогает найти кто, что и когда менял, решить конфликты при модифицировании одних и тех же файлов, откатиться на любое предыдущее состояние.

Ветвление разработки. Программисты параллельно ведут разработку нового функционала в отдельных ветках, не затрагивая работоспособности старого.

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

Организация процесса разработки

Вам, как менеджеру проекта, стоит обратить внимание:

  1. Принят ли у разработчиков единый шаблон оформления комментариев к коммитам (commit message), из которых понятно, что делает коммит и зачем.
  1. Настроена ли привязка коммитов к конкретным задачам из таск трекера (traceability) для трассировки бизнес требований.
    В Mercurial это работает из коробки, а вот, например, в Git это обычно решают с помощью хука, который не дает ничего закоммитить без метки таска, а-ля “PROJECT-JIRA_ISSUE_NUMBER”
  1. Делают ли разработчики ежедневный пуш (выгрузку коммитов) в центральный репозиторий или работают локально не отдавая написанный за день код вовне.

Последний вопрос не актуален, если разработчики используют на проекте SVN, так как это централизованная СКВ и весь код хранится на сервере.

Распределенные и централизованные подходы к хранению кода

Git и Mercurial — распределенные системы, SVN — централизованная.

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

При этом Git, в отличие от Mercurial, работает не только с локальными коммитами, но и с локальными ветками, которые можно вовсе не заливать в удаленный репозиторий.

SVN предполагает, что полная версия кода со всеми ветками хранится в удаленном репозитории, а у разработчика локально находится только тот файл, который он сейчас модифицирует.

C этой точки зрения, SVN лучше вписывается в модель коммерческой разработки, где мы ежедневно контролируем объем и качество выполненной работы.

При использовании Git или Mercurial проектному менеджеру необходимо установить правило ежедневных коммитов для разработчиков, это особенно критично для удаленных команд или аутсорсеров.

Как менеджеру освоить базовые функции Git

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

Короткий видеокурс Geekbrains для старта за 2 часа.
Официальная документация для дотошных.

Программное окружение:

На Mac Git по умолчанию вшит в штатную консоль. На Windows первым делом скачайте и установите сам Git.

С гитом работают через консоль или графический интерфейс (GUI).

Графический интерфейс SourceTree для работы менеджера с Git

Для задач IT-менеджера рациональнее использовать графический клиент. Лично я использую SourceTree, хотя не всем нравится продукция Atlassian.

Выберите клиент по вкусу вот тут.

Вперед к первому $ git clone!

A3.10 Приложение C: Команды Git — Внешние системы

В Git есть несколько стандартных команд для работы с другими системами контроля версий.

git svn

Команда git svn используется для работы с сервером Subversion. Это означает, что вы можете использовать Git в качестве SVN клиента, забирать изменения и отправлять свои собственные на сервер Subversion.

Мы разобрались с этой командой в разделе Git и Subversion главы 9.

git fast-import

Для других систем контроля версий, либо для импорта произвольно форматированных данных, вы можете использовать git fast-import , которая умеет преобразовывать данные в формат, понятный Git.

Мы детально рассмотрели эту команду в разделе Импорт произвольного репозитория главы 9.

В чем различия между Git и SVN?

Вопрос, собственно выбора. Чем Git лучше или хуже SVN? Почему чаще от разработчиков я слышу именно про Git и его удобства, чем про SVN, хотя как по мне, все что слышал можно делать и в SVN. Причём для обоих вариантов есть удобный Tortoise, что сводит общение с репозиториями практически на один уровень. Может просто что-то плохо рекламируют, а разницы вообще нет?

Отслеживать
user177221
задан 17 сен 2013 в 15:11
pincher1519 pincher1519
2,548 4 4 золотых знака 35 35 серебряных знаков 56 56 бронзовых знаков

Если вы работали с тем или другим, то вы знаете, чем одно лучше другого. svn — наследие прошлого, уродливое и неповоротливое. Если вы планируете работать в одной ветке, что в корне неправильно, то для вас разницы действительно нет.

17 сен 2013 в 15:20
@pirj Расскажите, пожалуйста, если у вас найдется минутка, почему вы пришли к такому выводу.
17 сен 2013 в 15:26

>Если вы работали с тем или другим, то вы знаете, чем одно лучше другого @pirj мне кажется, что ТС задал этот вопрос именно потому, что он не работал с тем и другим. И да, вы забыли аргументировать ваше бесспорно взешенное мнение

17 сен 2013 в 15:52

да ладно, вы сейчас человека на svn уговорите, аргументы в инете и их много. я бы ещё понял если бы выбор между git и mercurial был. а svn это кошмар. не знаю как там разработчикам, я его админил.

17 сен 2013 в 16:05
Еще есть такая штука как Mercurial — тоже довольно таки удобная
17 сен 2013 в 23:04

5 ответов 5

Сортировка: Сброс на вариант по умолчанию

  1. GIT распределяется, а SVN — нет. Другими словами, если есть несколько разработчиков работающих с репозиторием у каждого на локальной машине будет ПОЛНАЯ копия этого репозитория. Разумеется есть и где-то и центральная машина, с которой можно клонировать репозиторий. Это напоминает SVN. Основной плюс в том, что если вдруг у вас нет доступа к интернету, сохраняется возможность работать с репозиторием. Потом только один раз сделать синхронизацию и все остальные разработчики получат поолную историю.
  2. GIT сохраняет метаданные изменений, а SVN целые файлы. Это экономит место и время.
  3. Система создания branches, versions и прочее в GIT и SVN отличаются значительно. В GIT проще переключатся с ветки на ветку, делать merge между ними. В общем GIT я нахожу немного проще и удобнее, но бывают конечно иногда сложности. Но где их не бывает?

Разумеется есть гораздо больше отличий, но я перечислил те, которые чаще всего встречаются при работе с репозиториями и на МОЙ взгляд наиболее важные.

Отслеживать
ответ дан 17 сен 2013 в 15:49
3,521 12 12 серебряных знаков 20 20 бронзовых знаков

— У вас часто не бывает доступа к интернету, когда вы работаете? — Это, естественно, неправда. И Subversion, и Git хранят дельты изменений. См., например, git-scm.com/book/ch9-4.html и stackoverflow.com/questions/127692/…

17 сен 2013 в 15:56

ну пусть не часто нет интернета, но не будете же Вы отрицать, что наличие полной копии репозитория на локальном компьютере это не отличие? Я просто привел пример, когда это может быть полезно. На счет файлов — спасибо, просветился.

17 сен 2013 в 15:59

Для меня тот факт, что с git можно работать локально — большой плюс. К примеру, можно поработать в самолете. Или к примеру, начал делать свой маленький проектик — тут же добавил в git. Если что то не так — удалил. Еще большой плюс локальности — для больших команд. Пришел новый разработчик — давать ему доступ на коммиты сразу — глупо (если это только не Кармак или ван Россум). А так — коммитить он может себе, может запушить это кому-то из разработчиков ( да, я знаю, в свн есть диффы. )

18 сен 2013 в 11:36

Новички они такие. Чуть не досмотрел — а он уже пол репозитория переработал. > однако хранить гигабайты кода на локальной машине — зачем? а никто не заставляет гигабайты хранить. можно удалять у себя ненужные ветки, делать git gc. Но в случае, если внешний репозитарий испортился, его можно восстановить из локальных копий. Только не говорите о бэкапах — иногда средства бекапа бывают такое выдают.

.1 Git и другие системы контроля версий — Git и Subversion

В настоящее время большинство проектов с открытым исходным кодом, а также большое число корпоративных проектов, используют Subversion для управления своим исходным кодом. Это самая популярная на текущий момент система контроля версий с открытым исходным кодом, история её использования насчитывает около 10 лет. Кроме того, она очень похожа на CVS, систему, которая была самой популярной до Subversion.

Одна из замечательных особенностей Git’а — возможность двустороннего обмена с Subversion через интерфейс, называемый git svn . Этот инструмент позволяет использовать Git в качестве корректного клиента при работе с сервером Subversion. Так что вы можете пользоваться всеми локальными возможностями Git’а, а затем сохранять изменения на сервере Subversion так, как если бы использовали Subversion локально. То есть вы можете делать локальное ветвление и слияние, использовать индекс, перемещение и отбор патчей для переноса из одной ветви в другую (cherry-picking) и т.д., в то время как ваши коллеги будут продолжать использовать в разработке подход времён каменного века. Это хороший способ протащить Git в рабочее окружение своей компании и помочь коллегам разработчикам стать более эффективными, в то время как вы будете лоббировать переход полностью на Git. Интерфейс обмена с Subversion — это ворота в мир распределённых систем контроля версий.

git svn

Базовой командой в Git’е для всех команд, работающих с мостом к Subversion, является git svn . Ей предваряется любая команда. Она принимает довольно порядочное число команд, поэтому мы изучим из них те, которые наиболее часто используются, рассмотрев несколько небольших вариантов работы.

Важно отметить, что при использовании git svn вы взаимодействуете с Subversion — системой, которая намного менее «продвинута», чем Git. Хоть вы и умеете с лёгкостью делать локальное ветвление и слияние, как правило, лучше всего держать свою историю в как можно более линейном виде, используя перемещения (rebase) и избегая таких вещей, как одновременный обмен с удалённым Git-репозиторием.

Не переписывайте свою историю, попробуйте отправить изменения ещё раз, а также не отправляйте изменения в параллельный Git-репозиторий, используемый для совместной работы, одновременно с другими разработчиками, использующими Git. Subversion может иметь только одну единственную линейную историю изменений, сбить с толку которую очень и очень просто. Если вы работаете в команде, в которой некоторые разработчики используют Git, а другие Subversion, убедитесь, что для совместной работы все используют только SVN-сервер — это сильно упростит вам жизнь.

Настройка

Для того чтобы попробовать этот функционал в действии, вам понадобится доступ с правами на запись к обычному SVN-репозиторию. Если вы хотите повторить рассматриваемые примеры, вам нужно сделать доступную на запись копию моего тестового репозитория. Это можно сделать без труда с помощью утилиты svnsync , входящей в состав последних версий Subversion (по крайней мере после версии 1.4). Для этих примеров я создал новый Subversion-репозиторий на Google Code, который был частичной копией проекта protobuf (утилита кодирования структурированных данных для их передачи по сети).

Чтобы мы могли продолжить, прежде всего создайте новый локальный репозиторий Subversion:

$ mkdir /tmp/test-svn $ svnadmin create /tmp/test-svn 

Затем разрешите всем пользователям изменять revprops — самым простым способом сделать это будет добавление сценария pre-revprop-change , который просто всегда завершается с кодом 0:

$ cat /tmp/test-svn/hooks/pre-revprop-change #!/bin/sh exit 0; $ chmod +x /tmp/test-svn/hooks/pre-revprop-change 

Теперь вы можете синхронизировать проект со своей локальной машиной, вызвав svnsync init с параметрами, задающими исходный и целевой репозиторий:

$ svnsync init file:///tmp/test-svn http://progit-example.googlecode.com/svn/ 

Эта команда подготовит процесс синхронизации. Затем склонируйте код, выполнив:

$ svnsync sync file:///tmp/test-svn Committed revision 1. Copied properties for revision 1. Committed revision 2. Copied properties for revision 2. Committed revision 3. . 

Хотя выполнение этой операции и может занять всего несколько минут, однако, если вы попробуете скопировать исходный репозиторий в другой удалённый репозиторий, а не в локальный, то процесс займёт почти час, хотя в этом проекте менее ста коммитов. Subversion вынужден клонировать ревизии по одной, а затем отправлять их в другой репозиторий — это чудовищно неэффективно, однако это единственный простой способ выполнить это действие.

Приступим к работе

Теперь, когда в вашем распоряжении имеется SVN-репозиторий, для которого вы имеете право на запись, давайте выполним типичные действия по работе с СКВ. Начнём с команды git svn clone , которая импортирует весь SVN-репозиторий в локальный Git-репозиторий. Помните, что если вы производите импорт из настоящего удалённого SVN-репозитория, вам надо заменить file:///tmp/test-svn на реальный адрес вашего SVN-репозитория:

$ git svn clone file:///tmp/test-svn -T trunk -b branches -t tags Initialized empty Git repository in /Users/schacon/projects/testsvnsync/svn/.git/ r1 = b4e387bc68740b5af56c2a5faf4003ae42bd135c (trunk) A m4/acx_pthread.m4 A m4/stl_hash.m4 . r75 = d1957f3b307922124eec6314e15bcda59e3d9610 (trunk) Found possible branch point: file:///tmp/test-svn/trunk => \ file:///tmp/test-svn /branches/my-calc-branch, 75 Found branch parent: (my-calc-branch) d1957f3b307922124eec6314e15bcda59e3d9610 Following parent with do_switch Successfully followed parent r76 = 8624824ecc0badd73f40ea2f01fce51894189b01 (my-calc-branch) Checked out HEAD: file:///tmp/test-svn/branches/my-calc-branch r76 

Эта команда эквивалентна выполнению для указанного вами URL двух команд — git svn init , а затем git svn fetch . Процесс может занять некоторое время. Тестовый проект имеет всего лишь около 75 коммитов, и кода там не очень много, так что, скорее всего, вам придётся подождать всего несколько минут. Однако, Git должен по отдельности проверить и выполнить коммит для каждой версии. Для проектов, имеющих историю с сотнями и тысячами изменений, этот процесс может занять несколько часов или даже дней.

Часть команды -T trunk -b branches -t tags сообщает Git’у, что этот SVN-репозиторий следует стандартным соглашениям о ветвлении и метках. Если вместо trunk, branches и tags вы используете какие-то другие, нестандартные имена, то должны изменить эти параметры соответствующим образом. В связи с тем, что такие соглашения являются общепринятыми, вы можете использовать короткий формат, заменив всю эту часть на -s , заменяющую собой все эти параметры. Следующая команда эквивалента предыдущей:

$ git svn clone file:///tmp/test-svn -s 

Таким образом, вы должны были получить корректный Git-репозиторий с импортированными ветками и метками:

$ git branch -a * master my-calc-branch tags/2.0.2 tags/release-2.0.1 tags/release-2.0.2 tags/release-2.0.2rc1 trunk 

Важно отметить, что эта утилита именует ваши ссылки на удалённые ресурсы по-другому. Когда вы клонируете обычный Git-репозиторий, вы получаете все ветки с удалённого сервера на локальном компьютере в виде: origin/[ветка] — в пространстве имён с именем удалённого сервера. Однако, git svn полагает, что у вас не будет множества удалённых источников данных и сохраняет все ссылки на всякое, находящееся на удалённом сервере, без пространства имён. Для просмотра всех имён ссылок вы можете использовать служебную команду Git’а show-ref :

$ git show-ref 1cbd4904d9982f386d87f88fce1c24ad7c0f0471 refs/heads/master aee1ecc26318164f355a883f5d99cff0c852d3c4 refs/remotes/my-calc-branch 03d09b0e2aad427e34a6d50ff147128e76c0e0f5 refs/remotes/tags/2.0.2 50d02cc0adc9da4319eeba0900430ba219b9c376 refs/remotes/tags/release-2.0.1 4caaa711a50c77879a91b8b90380060f672745cb refs/remotes/tags/release-2.0.2 1c4cb508144c513ff1214c3488abe66dcb92916f refs/remotes/tags/release-2.0.2rc1 1cbd4904d9982f386d87f88fce1c24ad7c0f0471 refs/remotes/trunk 

Обычный Git-репозиторий выглядит скорее так:

$ git show-ref 83e38c7a0af325a9722f2fdc56b10188806d83a1 refs/heads/master 3e15e38c198baac84223acfc6224bb8b99ff2281 refs/remotes/gitserver/master 0a30dd3b0c795b80212ae723640d4e5d48cabdff refs/remotes/origin/master 25812380387fdd55f916652be4881c6f11600d6f refs/remotes/origin/testing 

Здесь два удалённых сервера: один с именем gitserver и веткой master , и другой с именем origin с двумя ветками: master и testing .

Обратите внимание, что в примере, где ссылки импортированы из git svn , метки были добавлены в Git как удалённые ветки, а не как настоящие метки. Импортированные из Subversion данные выглядят так, как будто под именами меток с удалённого ресурса скрываются ветки.

Коммит в Subversion

Теперь, когда у вас есть рабочий репозиторий, вы можете выполнить какую-либо работу с кодом и выполнить коммит в апстрим, эффективно используя Git в качестве SVN-клиента. Если вы редактировали один из файлов и закоммитили его, то вы внесли изменение в локальный Git-репозиторий, которое пока не существует на Subversion-сервере:

$ git commit -am 'Adding git-svn instructions to the README' [master 97031e5] Adding git-svn instructions to the README 1 files changed, 1 insertions(+), 1 deletions(-) 

После этого вам надо отправить изменения в апстрим. Обратите внимание, как Git изменяет способ работы с Subversion — вы можете сделать несколько коммитов оффлайн, а затем отправить их разом на Subversion-сервер. Для передачи изменений на Subversion-сервер требуется выполнить команду git svn dcommit :

$ git svn dcommit Committing to file:///tmp/test-svn/trunk . M README.txt Committed r79 M README.txt r79 = 938b1a547c2cc92033b74d32030e86468294a5c8 (trunk) No changes between current HEAD and refs/remotes/trunk Resetting to the latest refs/remotes/trunk 

Это действие возьмёт все коммиты, сделанные поверх того, что есть в SVN-репозитории, выполнит коммит в Subversion для каждого из них, а затем перепишет ваш локальный коммит в Git’е, чтобы добавить к нему уникальный идентификатор. Это важно, поскольку это означает, что изменятся все SHA-1 контрольные суммы ваших коммитов. В частности и поэтому работать с одним и тем же проектом одновременно и через Git, и через Subversion — это плохая идея. Взглянув на последний коммит, вы увидите, что добавился новый git-svn-id :

$ git log -1 commit 938b1a547c2cc92033b74d32030e86468294a5c8 Author: schacon Date: Sat May 2 22:06:44 2009 +0000 Adding git-svn instructions to the README git-svn-id: file:///tmp/test-svn/trunk@79 4c93b258-373f-11de-be05-5f7a86268029 

Обратите внимание — контрольная сумма SHA, которая начиналась с 97031e5 когда вы делали коммит, теперь начинается с 938b1a5 . Если вы хотите отправить изменения как на Git-сервер, так и на SVN-сервер, вы должны отправить их ( dcommit ) сначала на Subversion-сервер, поскольку это действие изменит отправляемые данные.

Получение новых изменений

Если вы работаете вместе с другими разработчиками, значит, когда-нибудь вам придётся столкнуться с ситуацией, когда кто-то из вас отправит изменения на сервер, а другой, в свою очередь, будет пытаться отправить свои изменения, конфликтующие с первыми. Это изменение не будет принято до тех пор, пока вы не сольёте себе чужую работу. В git svn эта ситуация выглядит следующим образом:

$ git svn dcommit Committing to file:///tmp/test-svn/trunk . Merge conflict during commit: Your file or directory 'README.txt' is probably \ out-of-date: resource out of date; try updating at /Users/schacon/libexec/git-\ core/git-svn line 482 

Для разрешения этой проблемы вам нужно выполнить команду git svn rebase , которая получит все изменения, имеющиеся на сервере, которых ещё нет на вашей локальной машине, и переместит все ваши недавние изменения поверх того, что было на сервере:

$ git svn rebase M README.txt r80 = ff829ab914e8775c7c025d741beb3d523ee30bc4 (trunk) First, rewinding head to replay your work on top of it. Applying: first user change 

Теперь все ваши изменения находятся сверху того, что есть на SVN-сервере, так что вы можете спокойно выполнить dcommit :

$ git svn dcommit Committing to file:///tmp/test-svn/trunk . M README.txt Committed r81 M README.txt r81 = 456cbe6337abe49154db70106d1836bc1332deed (trunk) No changes between current HEAD and refs/remotes/trunk Resetting to the latest refs/remotes/trunk 

Следует помнить, что в отличие от Git’а, который требует сливать себе изменения в апстриме, которых у вас ещё нет локально, перед тем как отправить свои изменения, git svn заставляет делать такое только в случае конфликта правок. Если кто-либо внесёт изменения в один файл, а вы внесёте изменения в другой, команда dcommit сработает без ошибок:

$ git svn dcommit Committing to file:///tmp/test-svn/trunk . M configure.ac Committed r84 M autogen.sh r83 = 8aa54a74d452f82eee10076ab2584c1fc424853b (trunk) M configure.ac r84 = cdbac939211ccb18aa744e581e46563af5d962d0 (trunk) W: d2f23b80f67aaaa1f6f5aaef48fce3263ac71a92 and refs/remotes/trunk differ, \ using rebase: :100755 100755 efa5a59965fbbb5b2b0a12890f1b351bb5493c18 \ 015e4c98c482f0fa71e4d5434338014530b37fa6 M autogen.sh First, rewinding head to replay your work on top of it. Nothing to do. 

Это важно помнить, поскольку последствием этих действий может стать такое состояние проекта, которого нет ни на одном из ваших компьютеров. Если изменения несовместимы, но не ведут к конфликту изменений, у вас могут возникнуть проблемы, которые трудно будет диагностировать. Это отличается от работы с Git-сервером — в Git’е вы можете полностью проверить состояние проекта на клиентских машинах до публикации, в то время как в SVN вы не можете даже быть уверены в том, что состояние проекта непосредственно перед коммитом и после него идентично.

Кроме того, вам нужно выполнить следующую команду для получения изменений с сервера Subversion, даже если вы не готовы сами сделать коммит. Вы можете выполнить git svn fetch для получения новых данных, но git svn rebase и извлечёт новые данные с сервера, и обновит ваши локальные коммиты.

$ git svn rebase M generate_descriptor_proto.sh r82 = bd16df9173e424c6f52c337ab6efa7f7643282f1 (trunk) First, rewinding head to replay your work on top of it. Fast-forwarded master to refs/remotes/trunk. 

Выполняйте команду git svn rebase периодически, чтобы быть уверенным в том, что ваш код имеет самую свежую версию. Перед выполнением этой команды убедитесь, что ваш рабочий каталог чист. Если нет, вы должны либо «спрятать» свои изменения, либо временно закоммитить их перед выполнением git svn rebase , иначе выполнение этой команды прекратится, если она обнаружит возникновение конфликта слияния.

Проблемы с ветвлением в Git

После того как вы привыкли к работе с Git’ом, вы наверняка будете создавать ветки для работы над отдельными задачами, а затем сливать их. Если вы отправляете изменения на Subversion-сервер через git svn , вам, скорее всего, потребуется перемещать свою работу каждый раз в одну ветку, а не сливать ветки вместе. Причина, по которой предпочтение должно быть отдано именно такому подходу, заключается в том, что Subversion имеет линейную историю изменений и не может обрабатывать слияния так, как это делает Git. Поэтому git svn проходит только по первым родителям при конвертации снимков состояния в коммиты Subversion.

Допустим, что история изменений выглядит следующим образом: вы создали ветку experiment , сделали два коммита, а затем слили их в ветку master . Если вы выполните dcommit , результат будет следующим:

$ git svn dcommit Committing to file:///tmp/test-svn/trunk . M CHANGES.txt Committed r85 M CHANGES.txt r85 = 4bfebeec434d156c36f2bcd18f4e3d97dc3269a2 (trunk) No changes between current HEAD and refs/remotes/trunk Resetting to the latest refs/remotes/trunk COPYING.txt: locally modified INSTALL.txt: locally modified M COPYING.txt M INSTALL.txt Committed r86 M INSTALL.txt M COPYING.txt r86 = 2647f6b86ccfcaad4ec58c520e369ec81f7c283c (trunk) No changes between current HEAD and refs/remotes/trunk Resetting to the latest refs/remotes/trunk 

Выполнение dcommit для ветки с объединённой историей не вызовет никаких проблем. Однако, если вы посмотрите на историю проекта в Git’е, то увидите, что ни один из коммитов, которые вы сделали в ветке experiment не были переписаны — вместо этого, все эти изменения появятся в SVN версии как один объединённый коммит.

Когда кто-нибудь склонирует себе эту работу, всё, что он увидит — это коммит, в котором все изменения слиты воедино; он не увидит данных о том, откуда они взялись и когда они были внесены.

Ветвление в Subversion

Работа с ветвями в Subversion отличается от таковой в Git’е; если у вас есть возможность избегать её, то это, наверное, лучший вариант. Хотя, вы можете создавать и вносить изменения в ветки в Subversion, используя git svn .

Создание новой ветки в SVN

Для того чтобы создать новую ветку в Subversion, выполните git svn branch [имя ветки] :

$ git svn branch opera Copying file:///tmp/test-svn/trunk at r87 to file:///tmp/test-svn/branches/opera. Found possible branch point: file:///tmp/test-svn/trunk => \ file:///tmp/test-svn/branches/opera, 87 Found branch parent: (opera) 1f6bfe471083cbca06ac8d4176f7ad4de0d62e5f Following parent with do_switch Successfully followed parent r89 = 9b6fe0b90c5c9adf9165f700897518dbc54a7cbf (opera) 

Эта команда эквивалентна команде Subversion svn copy trunk branches/opera и выполняется на Subversion-сервере. Важно отметить, что эта команда не переключает вас на указанную ветку. Так что, если вы сейчас сделаете коммит, он попадёт на сервере в trunk , а не в opera .

Переключение активных веток

Git определяет ветку, в которую он отправит ваши коммиты при выполнении dcommit , ища верхушку Subversion-ветки в вашей истории — она должна быть одна и она должна быть последней в текущей истории веток, имеющей метку git-svn-id .

Если вы хотите работать одновременно с несколькими ветками, вы можете настроить локальные ветки на внесение изменений через dcommit в конкретные ветки Subversion, начиная их на основе импортированного SVN-коммита для нужной ветки. Если вам нужна ветка opera , в которой вы можете поработать отдельно, можете выполнить:

$ git branch opera remotes/opera 

Теперь, если вы захотите слить ветку opera в trunk (вашу ветку master ), вы сможете сделать это с помощью обычной команды git merge . Однако вам потребуется добавить подробное описание к коммиту (через параметр -m ), иначе при слиянии комментарий будет иметь вид «Merge branch opera» вместо чего-нибудь полезного.

Помните, что хотя вы и используете git merge для этой операции, и слияние, скорее всего, произойдёт намного проще, чем было бы в Subversion (потому что Git автоматически определяет подходящую основу для слияния), оно не является обычным коммитом-слиянием в Git’е. Вы должны передать данные обратно на сервер в Subversion, который не способен справиться с коммитом, имеющим более одного родителя, так что после передачи этот коммит будет выглядеть как один коммит, в который затолканы все изменения с другой ветки. После того как вы сольёте одну ветку в другую, вы не сможете просто так вернуться к работе над ней, как могли бы в Git’е. Команда dcommit удаляет всю информацию о том, какая ветка была влита, так что последующие вычисления базы слияния будут неверными — команда dcommit сделает результаты выполнения git merge такими же, какими они были бы после выполнения git merge —squash . К сожалению, избежать подобной ситуации вряд ли удастся — Subversion не способен сохранять подобную информацию, так что вы всегда будете связаны этими ограничениями. Во избежание проблем вы должны удалить локальную ветку (в нашем случае opera ) после того, как вы вольёте её в trunk .

Команды Subversion

Набор утилит git svn предоставляет в ваше распоряжение несколько команд для облегчения перехода на Git, путём предоставления функциональности, подобной той, которую вы имеете в Subversion. Ниже приведены несколько команд, которые дают вам то, что вы имели в Subversion.

Просмотр истории в стиле SVN

Если вы привыкли к Subversion и хотите просматривать историю в стиле SVN, выполните команду git svn log , чтобы увидеть историю коммитов в таком же формате, как в SVN:

$ git svn log ------------------------------------------------------------------------ r87 | schacon | 2009-05-02 16:07:37 -0700 (Sat, 02 May 2009) | 2 lines autogen change ------------------------------------------------------------------------ r86 | schacon | 2009-05-02 16:00:21 -0700 (Sat, 02 May 2009) | 2 lines Merge branch 'experiment' ------------------------------------------------------------------------ r85 | schacon | 2009-05-02 16:00:09 -0700 (Sat, 02 May 2009) | 2 lines updated the changelog 

Вы должны знать две важные вещи о команде git svn log . Во-первых, она работает в оффлайне, в отличие от оригинальной команды svn log , которая запрашивает информацию с Subversion-сервера. Во-вторых, эта команда отображает только те коммиты, которые были переданы на Subversion-сервер. Локальные Git-коммиты, которые вы ещё не отправили с помощью dcommit , не будут отображаться, равно как и коммиты, отправленные на Subversion-сервер другими людьми с момента последнего выполнения dcommit . Результат действия этой команды скорее похож на последнее известное состояние изменений на Subversion-сервере.

SVN-Аннотации

Так же как команда git svn log симулирует в оффлайне команду svn log , эквивалентом команды svn annotate является команда git svn blame [ФАЙЛ] . Её вывод выглядит следующим образом:

$ git svn blame README.txt 2 temporal Protocol Buffers - Google's data interchange format 2 temporal Copyright 2008 Google Inc. 2 temporal http://code.google.com/apis/protocolbuffers/ 2 temporal 22 temporal C++ Installation - Unix 22 temporal ======================= 2 temporal 79 schacon Committing in git-svn. 78 schacon 2 temporal To build and install the C++ Protocol Buffer runtime and the Protocol 2 temporal Buffer compiler (protoc) execute the following: 2 temporal 

Опять же, эта команда не показывает коммиты, которые вы сделали локально в Git’е или те, которые за то время были отправлены на Subversion-сервер.

Информация о SVN-сервере

Вы можете получить ту же информацию, которую даёт выполнение команды svn info , выполнив команду git svn info :

$ git svn info Path: . URL: https://schacon-test.googlecode.com/svn/trunk Repository Root: https://schacon-test.googlecode.com/svn Repository UUID: 4c93b258-373f-11de-be05-5f7a86268029 Revision: 87 Node Kind: directory Schedule: normal Last Changed Author: schacon Last Changed Rev: 87 Last Changed Date: 2009-05-02 16:07:37 -0700 (Sat, 02 May 2009) 

Так же, как blame и log , эта команда выполняется оффлайн и выводит информацию, актуальную на момент последнего вашего обращения к серверу Subversion.

Игнорирование того, что игнорирует Subversion

Если вы клонируете Subversion-репозиторий, в котором где-то установлены свойства svn:ignore , скорее всего, вы захотите создать соответствующие им файлы .gitignore , чтобы ненароком не добавить в коммит те файлы, которые не стоит добавлять. Для решения этой проблемы в git svn имеется две команды. Первая — git svn create-ignore — автоматически создаст соответствующие файлы .gitignore , которые вы затем можете добавить в свой следующий коммит.

Вторая команда — git svn show-ignore , которая выводит на стандартный вывод строки, которые вы должны включить в файл .gitignore . Таким образом, вы можете перенаправить вывод этой команды в файл исключений вашего проекта:

$ git svn show-ignore > .git/info/exclude 

Поступая таким образом, вы не захламляете проект файлами .gitignore . Это правильный подход, если вы являетесь единственным пользователем Git’а в команде, использующей Subversion, и ваши коллеги выступают против наличия файлов .gitignore в проекте.

Заключение по Git-Svn

Утилиты git svn полезны в том случае, если ваша разработка по каким-то причинам требует наличия рабочего Subversion-сервера. Однако, вам стоит смотреть на Git, использующий мост в Subversion, как на урезанную версию Git’а. В противном случае вы столкнётесь с проблемами в преобразованиях, которые могут сбить с толку вас и ваших коллег. Чтобы избежать неприятностей, старайтесь следовать следующим рекомендациям:

  • Держите историю в Git линейной, чтобы она не содержала коммитов-слияний, сделанных с помощью git merge . Перемещайте всю работу, которую вы выполняете вне основной ветки обратно в неё; не выполняйте слияний.
  • Не устанавливайте отдельный Git-сервер для совместной работы. Можно иметь один такой сервер для того, чтобы ускорить клонирование для новых разработчиков, но не отправляйте на него ничего, не имеющего записи git-svn-id . Возможно, стоит даже добавить перехватчик pre-receive , который будет проверять каждый коммит на наличие git-svn-id и отклонять git push , если коммиты не имеют такой записи.

При следовании этим правилам, работа с Subversion-сервером может быть более-менее сносной. Однако, если возможен перенос проекта на реальный Git-сервер, преимущества от этого перехода дадут вашему проекту намного больше.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *