$git svn clone file:///tmp/test-svn -T trunk -b branches -t tags
Initialized empty Git repository in /private/tmp/progit/test-svn/.git/
r1 = dcbfb5891860124cc2e8cc616cded42624897125 (refs/remotes/origin/trunk)
A m4/acx_pthread.m4
A m4/stl_hash.m4
A java/src/test/java/com/google/protobuf/UnknownFieldSetTest.java
A java/src/test/java/com/google/protobuf/WireFormatTest.java
…
r75 = 556a3e1e7ad1fde0a32823fc7e4d046bcfd86dae (refs/remotes/origin/trunk)
Found possible branch point: file:///tmp/test-svn/trunk => file:///tmp/test-svn/branches/my-calc-branch, 75
Found branch parent: (refs/remotes/origin/my-calc-branch) 556a3e1e7ad1fde0a32823fc7e4d046bcfd86dae
Following parent with do_switch
Successfully followed parent
r76 = 0fb585761df569eaecd8146c71e58d70147460a2 (refs/remotes/origin/my-calc-branch)
Checked out HEAD:
file:///tmp/test-svn/trunk r75
Приведённая выше команда является композицией двух других — git svn init и git svn fetch для указанного URL. Процесс копирования займёт некоторое время. Тестовый проект невелик — всего 75 коммитов — но Git вынужден последовательно скачивать SVN ревизии и превращать их в Git коммиты по одной за раз. Для проекта с сотней или тысячей ревизий это может занять часы или даже дни!
Параметры -T trunk -b branches -t tags говорят Git о том, что клонируемый репозиторий следует стандартному, принятому в Subversion, расположению директорий с транком, ветками и метками. Если же директории названы по-другому, можно указать их явно, используя эти параметры. Большинство Subversion репозиториев следуют этому соглашению, поэтому для этой комбинации параметров существует сокращение -s, что означает "стандартное расположение директорий" Следующая команда эквивалентна приведённой выше:
$git svn clone file:///tmp/test-svn -s
На этом этапе у вас должен быть обычный Git репозиторий с импортированными ветками и метками:
$git branch -a
* master
remotes/origin/my-calc-branch
remotes/origin/tags/2.0.2
remotes/origin/tags/release-2.0.1
remotes/origin/tags/release-2.0.2
remotes/origin/tags/release-2.0.2rc1
remotes/origin/trunk
Обратите внимание, как git svn представляет метки Subversion в виде ссылок. Давайте посмотрим на это повнимательней, используя команду show-ref:
$git show-ref
556a3e1e7ad1fde0a32823fc7e4d046bcfd86dae refs/heads/master
0fb585761df569eaecd8146c71e58d70147460a2 refs/remotes/origin/my-calc-branch
bfd2d79303166789fc73af4046651a4b35c12f0b refs/remotes/origin/tags/2.0.2
285c2b2e36e467dd4d91c8e3c0c0e1750b3fe8ca refs/remotes/origin/tags/release-2.0.1
cbda99cb45d9abcb9793db1d4f70ae562a969f1e refs/remotes/origin/tags/release-2.0.2
a9f074aa89e826d6f9d30808ce5ae3ffe711feda refs/remotes/origin/tags/release-2.0.2rc1
556a3e1e7ad1fde0a32823fc7e4d046bcfd86dae refs/remotes/origin/trunk
При работе с Git репозиторием Git поступает иначе, вот как выглядит Git репозиторий сразу после клонирования:
$git show-ref
c3dcbe8488c6240392e8a5d7553bbffcb0f94ef0 refs/remotes/origin/master
32ef1d1c7cc8c603ab78416262cc421b80a8c2df refs/remotes/origin/branch-1
75f703a3580a9b81ead89fe1138e6da858c5ba18 refs/remotes/origin/branch-2
23f8588dde934e8f33c263c6d8359b2ae095f863 refs/tags/v0.1.0
7064938bd5e7ef47bfd79a685a62c1e2649e2ce7 refs/tags/v0.2.0
6dcb09b5b57875f334f61aebed695e2e4193db5e refs/tags/v1.0.0
Заметили? Git помещает метки прямиком в refs/tags, но в случае с Subversion репозиторием они трактуются как удалённые ветки.
Отправка изменений в Subversion
Теперь, когда вы настроили репозиторий, можно проделать некую работу и отправить изменения обратно в Subversion, используя Git как SVN клиент. Если вы отредактируете какой-либо файл и зафиксируете изменения, полученный коммит будет существовать в локальном Git репозитории, но не на сервере Subversion.
$git commit -am 'Adding git-svn instructions to the README'
[master 4af61fd] Adding git-svn instructions to the README
1 file changed, 5 insertions(+)
Далее следует отправить изменения на сервер. Обратите внимание как это меняет привычный сценарий работы с Subversion: вы фиксируете изменения без связи с сервером, а затем отправляете их все при удобном случае. Чтобы отправить изменения на Subversion сервер, следует выполнить команду git svn dcommit:
$git svn dcommit
Committing to file:///tmp/test-svn/trunk ...
M README.txt
Committed r77
M README.txt
r77 = 95e0222ba6399739834380eb10afcd73e0670bc5 (refs/remotes/origin/trunk)
No changes between 4af61fd05045e07598c553167e0f31c84fd6ffe1 and refs/remotes/origin/trunk
Resetting to the latest refs/remotes/origin/trunk
Эта команда берёт все изменения, зафиксированные поверх последних ревизий с Subversion сервера, создаёт для каждого новую Subversion ревизию, а затем переписывает их, добавляя уникальный идентификатор. Это важно, потому что изменяются SHA-1 хеши коммитов. Это одна из причин, почему не рекомендуется смешивать Subversion и Git сервер в одном проекте. Если посмотреть на последний коммит, вы увидите, что добавилась строка git-svn-id:
$git log -1
commit 95e0222ba6399739834380eb10afcd73e0670bc5
Author: ben
Date: Thu Jul 24 03:08:36 2014 +0000
Adding git-svn instructions to the README
git-svn-id: file:///tmp/test-svn/trunk@77 0b684db3-b064-4277-89d1-21af03df0a68
Обратите внимание, что SHA-1 хеш, прежде начинавшийся с 4af61fd, теперь начинается с 95e0222. Если всё же хотите работать как с Git, так и с Subversion серверами в одном проекте, сначала следует отправлять (dcommit) изменения на Subversion сервер, так как это изменяет хеши.
Получение новых изменений
Читать дальше