Я уже несколько раз писал в блоге о Git (который я произносил с жестким «g» a la «get», так как он должен был быть назван в честь Линуса Торвальдса, самоописанного git , но я также слышал, что произносится с мягким «г», как «струя»). В любом случае, я считаю, что это более эффективно и менее болезненно, чем в сочетании с CVS или SVN.
Итак, чтобы продолжить эту серию ( [1] , [2] , [3] ), вот как (и почему) использовать SVN-репо как Git-репо, но с пропуском старых (не относящихся к делу) ревизий и веток ,
Использование SVN для репозиториев SVN
В прежние времена при работе с репозиториями JBoss Tools и JBoss Developer Studio SVN я хранил копию всего, что находится в стволе на диске, плюс текущую активную ветвь (последняя веха или стабильная поддержка ветвления). Со всеми метаданными SVN это потребляет значительный объем дискового пространства, но все же требует доступа к сети для извлечения любой старой истории файлов. Два репозитория занимали около 2 ГБ места на диске для каждой ветви. Конечно, есть инструменты, позволяющие различать и объединять ветви без физической проверки обеих ветвей, но ничто не сравнится с возможностью размещать две папки рядом OFFLINE для глубоких сравнений. Поэтому иногда мне приходилось записывать целых 6–8 ГБ диска, чтобы иметь несколько источников для сравнения и объединения. С моим мучительно медленным приводом IDE это остановило бы мою машину,особенно при выполнении каких-либо операций SVN или подсчете файлов / использования диска.
Использование Git для репозиториев SVN наивно
Недавно я начал использовать git-svn, чтобы переместить весь репозиторий JBDS в локальное репозиторий Git, но его создание было медленным и все еще громоздким. А репозиторий JBoss Tools был слишком велик, чтобы его можно было даже создать в виде репозитория Git — операции не хватило бы памяти при обработке старых версий кода для воспроизведения вперед.
В этот момент я застрял, имея отдельные репозитории Git для каждого компонента JBoss Tools (основная исходная папка) в SVN : архивы as, birt, bpel, build и т. Д. Это работало, но реплицировало его, когда мне нужно было создать соответствующий репозиторий. Сбор на ветку был болезненным и трудоемким. Кроме того, вся старая информация о ревизиях поглощала даже больше диска, чем раньше:
- Ствол jbosstools как несколько клонов git-svn: 6.1G
- ствол devstudio как одиночный клон git-svn: 1.3G
Итак, теперь вместо пары Гб на ветку я использовал почти в 4 раза больше дискового пространства. Но, по крайней мере, я мог работать в автономном режиме и не иметь дело с интенсивными сетевыми действиями, просто чтобы проверить историю или зафиксировать изменения. Тем не менее, далеко от идеала.
Клонирование SVN со стандартной версткой и частичной историей
На прошлой неделе я обнаружил два способа улучшить работу с git-svn как минимум на порядок:
- Стандартный макет (-ы) — это позволяет вашему сгенерированному репозиторию Git содержать обычный макет ствола, ветвей / * и тегов / *, присутствующий в исходном репозитории SVN. Это выигрыш, поскольку это означает, что в вашем репо будет храниться информация о филиалах, поэтому вы можете легко переключаться между филиалами в одном и том же репо на диске. Больше не требуется удаленный доступ к сети!
- Фильтр ревизий (-r) — это позволяет вашему сгенерированному репозиторию Git начинать с известного номера ревизии, а не начинать с его рождения. Теперь вместо генерации часов вы можете получить репо за считанные минуты, исключив ненужные (древние) ревизии.
Итак, почему это круто? Потому что теперь вместо 2G метаданных источника + для копирования, когда я хочу выполнить локальное сравнение между ветвями, размер на диске просто:
- Ствол jbosstools как один клон git-svn с транком и одной веткой: 1.3G
- ствол devstudio как одиночный клон git-svn с стволом и одна ветвь: 0.13G
Таким образом, не только занимает меньше места, но и производительность лучше, и мне больше не нужно делать полный клон (или извлечение svn) — вместо этого я могу просто скопировать существующее репозиторий Git и переназначить его в другую ветку. Вместо часов эта операция занимает секунды (или минуты) и происходит без необходимости подключения к сети.
Ладно, хватит болтать. Покажи мне код!
Проверьте репо, включая только транк и самую последнюю ветку
# Figure out the revision number based on when a branch was created, then
# from r28571, returns -r28571:HEAD
rev=$(svn log --stop-on-copy \
http://svn.jboss.org/repos/jbosstools/branches/jbosstools-3.2.x \
| egrep "r[0-9]+" | tail -1 | sed -e "s#\(r[0-9]\+\).\+#-\1:HEAD#")
# now, fetch repo starting from the branch's initial commit
git svn clone -s $rev http://svn.jboss.org/repos/jbosstools jbosstools_GIT
Теперь у вас есть репо, содержащее ствол и одну ветку
git branch -a # list local (Git) and remote (SVN) branches
* master
remotes/jbosstools-3.2.x
remotes/trunk
Переключиться на ветку
git checkout -b local/jbosstools-3.2.x jbosstools-3.2.x # connect a new local branch to remote one
Checking out files: 100% (609/609), done.
Switched to a new branch 'local/jbosstools-3.2.x'
git svn info # verify now working in branch
URL: http://svn.jboss.org/repos/jbosstools/branches/jbosstools-3.2.x
Repository Root: http://svn.jboss.org/repos/jbosstools
Переключиться обратно на багажник
git checkout -b local/trunk trunk # connect a new local branch to remote trunk
Switched to a new branch 'local/trunk'
git svn info # verify now working in branch
URL: http://svn.jboss.org/repos/jbosstools/trunk
Repository Root: http://svn.jboss.org/repos/jbosstools
Перемотайте изменения, извлеките обновления из репозитория SVN, примените изменения; не будет работать, если у вас есть локальные незафиксированные изменения
git svn rebase
Получить обновления из репозитория SVN (игнорируя локальные изменения?)
git svn fetch
Создать новую ветку (удаленно с SVN)
svn copy \
http://svn.jboss.org/repos/jbosstools/branches/jbosstools-3.2.x \
http://svn.jboss.org/repos/jbosstools/branches/some-new-branch
От http://divby0.blogspot.com/2011/01/howto-partially-clone-svn-repo-to-git.html