вторник, 13 апреля 2010 г.

git-svn. Проблема отката svn-репозитория

Введение.

После ошибки при dcommit'е в svn из git-репозитория пришлось откатить svn из бэкапа. Далее git-svn отказывался выполнять dcommit, т к в git-репозитории номер коммита выше, чем в svn (который был восстановлен).

Предыстория.

Возникла необходимость совместной разработки. Так как с DVCS я толком знаком не был, решил использовать svn. Просто, удобно. Легко обучить человека, который систем контроля версий не видел ни разу.
Разработка под винды, соответственно, выбран консольный svn + tortoiseSvn (лишний раз svn status набирать не надо, все такое).

В какой-то момент пришлось дорабатывать систему на стенде, где сети уже не было. А VCS хотелось. Выбор пал на git, хотя, наверное, тогда стоило обратить внимание на mercurial.

git-svn.

git-svn прекрасно подцепился к репозиторию в сети, выкачал некоторое количество коммитов и прекрасно работал. До тех пор, пока не добавил нечаянно файл с русским именем.
git не испытывал никаких сложностей с этим. Зато на очередном git-svn dcommit svn не оценил такой шутки и остановился на коммите с кривым именем файла. Пришлось откатить svn из бэкапа.
Во избежание повторения баги этот файл был вычищен из истории (той, что не было в svn, ессно, т к в репозитории теперь номер ревизии ниже, чем считает git).

Дальнейшие попытки выполнить git-svn dcommit привели к провалу. git считал, что пора заливать 137 коммит, а svn - 118. Все это происходило в git версии 1.6.3 (текущей в ubuntu 9.10). Попытки исправления метаданных руками не помогли.

Решение.

Прочтение man'а помогло не сильно. Решив поискать решение в сети, наткнулся на man новой версии.

В новом релизе 1.7.0 появилась прелестная команда git-svn reset -rXX позволяющая откатить метаданные до соответствующей ревизии.

Итак, запускаем git-svn reset -r117, git рапортует, что refs/remotes/git-svn соответствует ревизии 117 и прочие прелести.

После этого можно спокойно делать git-svn fetch, чтобы обновить refs/remotes/git-svn. И git rebase --onto remotes/git-svn <upstream> <branch>, чтобы перенести ветку на новое дерево.

В принципе, все.

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

P. S. Это то, что не прошло-таки модерацию на хабре..