Допустим, что история изменений выглядит следующим образом: вы создали ветку 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 определяет ветку, куда вносятся ваши коммиты, путём выбора самой последней 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: