Что такое svn git
Subversion vs. Git: Развенчивание мифов о развенчивании мифов
Я относительно недавно сменил работу, попал в компанию, где используется svn, но переход на git часто всплывает в обсуждениях.
Однажды я стал свидетелем обсуждения этой темы. Коллеги обсуждали тот самый сайт и пришли к выводу, что «меняем шило на мыло».
В этом диалоге я был невольным слушателем, но что там за сайт и его аргументы меня заинтересовали. Пошел разбираться.
Начнем с первого заявления
The particular delta compression algorithms used in both version control systems differ in many details, but in general Subversion and Git store data in the same way. This results in the fact that Subversion and Git repositories with equivalent data will have approximately the same size. Except for the case of storing a lot of binary files, when Subversion repositories could be significantly smaller than Git ones (because Subversion’s xdelta delta compression algorithm works both for binary and text files).
Ниже есть пример, где они сравнивают размер репозитория. Вывод – разница не существенна.
Меня смутило различное число коммитов, и фактически разные первоисточники(кто знает, как они там синхронизируют эти репозитории). Так же меня не устроил уровень детализации описания процесса получения этих чисел.
Итак, начнем свой эксперимент!
Получаем svn репозиторий
У нас локальная копия всего репозитория в формате svn. Это папка размером 213 МБ, которая содержит 79758 файлов и 88 папок.
На этот момент в репозитории насчитывается 39864 коммита. Рабочая копия проекта состоит из 1701 файла и 160 папок.
Начинаем миграцию в гит
Этот этап был самым длительным, затянулся более чем на сутки (примерно 32 часа). В результате имеем git репозиторий — копия оригинального svn репозитория(не совсем копия, но для нас различия не существенны).
Здесь я сделал небольшую глупость, стоило бы создавать репозиторий без рабочей копии, но еще раз ждать более суток я был не готов.
Итак, папка git_from_svn/.git: 208 МБ содержит 7841 файлов и 509 папок. На данном этапе действительно можно говорить о незначительном перевесе в пользу git, видимо как раз на этом этапе и остановились те, кто ведет сайт. Но ведь у гита есть 2 формата хранения: “loose” object и “packfile».
Посмотрим, что же мы имеем:
count: 6826
size: 30.21 MiB
in-pack: 249852
packs: 25
size-pack: 145.51 MiB
prune-packable: 73
garbage: 0
size-garbage: 0 bytes
То есть у нас есть множество пакетов и 6826 (30.21 МБ) не сжатых объектов.
Оптимизируем хранение
count: 0
size: 0 bytes
in-pack: 256605
packs: 1
size-pack: 104.54 MiB
prune-packable: 0
garbage: 0
size-garbage: 0 bytes
Размер самой папки «.git» получается 136 МБ(945 файлов, 255 папок). Мне кажется такое преимущество уже сложно назвать незначительным.
Еще подчистим
Но и это еще не все, если избавиться от наследия svn — пушнуть это все в bare репозиторий получаем еще интересней картинку: 106 MБ, 19 файлов, 8 папок.
Соберем все вместе
svn — 213 MБ (79 758 файлов, 88 папок)
svn(после pack) — 214 MБ (4 644 файлов, 89 папок) (дополнение после публикации)
git svn — 208 MБ (7 841 файлов, 509 папок)
git svn(pack) — 136 MБ (945 файлов, 255 папок)
git bare(pack) — 106 MБ (19 файлов, 8 папок)
Мне кажется на этом этапе развенчивание мифа можно считать развенчанным(утверждение на сайте опровергнуто).
Еще стоит упомянуть, что loose объекты у вас все же будут, предназначены они для повышения производительности работы с часто используемыми файлами. Обычно в таком формате будут храниться файлы из веток, в которых сейчас активно идет работа. Их количество можно регулировать через конфигурационные файлы.
Идем дальше
Branches in Subversion are implemented with Copy-On-Write strategy (referred to as ‘Cheap Copies’ in the svnbook). No matter how large a repository or project is, it takes a constant amount of time and space to make a branch. In fact, Subversion branches are extremely cheap beginning with version 1.0 and you can branch even for small bugfixes in a very busy and large project.
И эксперимент это «подтверждающий».
Вывод – создание бранчи происходит быстрей чем вы глазом моргнуть успеете. Мне показалось, что если вся операция занимает меньше 0,01 секунды то тут и сравнивать нечего. Но почему-то на заявление о дороговизне бранчей в svn, сайт проверил только их создание. Но есть другие операции, например клонирование( или svn checkout). В этом эксперименте все происходит локально, возможное влияние сети исключено.
Первый эксперимент – клонирование
Git проиграл. Но здесь стоит учесть, git получил всю историю, а svn — одну ревизию.
Второй эксперимент – смена бранчи
Здесь все наоборот, при этом на одном переключении мы отыграли половину от потери при клонировании.
На этом я пожалуй закончу. Пойду обсуждать эти результаты с сотрудниками.
PS: Несмотря на то, что посыл этой заметки банален «не стоит доверять непроверенным источникам в интернете», но, оказывается, есть еще люди, не развившие достаточный уровень здорового скептицизма.
KNZSOFT Разработка ПО, консультации, учебные материалы
Князев Алексей Александрович. Независимый программист и консультант.
SVN и Git для начинающих. Практика использования
Материал страницы находится в разработке!
Введение
Данное руководство написано для практического ознакомления с популярной сегодня системой контроля версий Subversion, также известной как SVN. Пользователи Linux смогут повторить все описанные в статье эксперименты на своём компьютере. Пользователи других операционных систем должны будут внести некоторые поправки.
Одной из отличительных черт данного руководства является проведение сравнений и аналогий между SVN и Git. Git был разработан несколько позже SVN, и был ориентирован на очень специфический проект — разработка ядра Linux, которая ведется очень большим кругом разработчиков разбросанных по всему миру. Архитектура и реализация Git оказалась привлекательной для ведения других программных проектов и сегодня, наверное, именно SVN и Git являются самыми популярными системами контроля версий. SVN и Git сильно отличаются по своим базовым идеям, и выбор между использованием SVN или Git должен опираться на понимание этих различий. В рамках данного руководства, мы будем не только изучать SVN и Git, но и акцентировать внимание на отличительных особенностях этих систем, что, кроме прочего, должно усилить продуктивность изучения — знакомство с тем, что и как может быть сделано по-другому, упростит запоминание материала.
Последний раздел посвящён специальным возможностям системы Git по трансформациям между своим локальным репозиторием и центральным репозиторием SVN. Многим будет интересно знать, что с центральным репозиторием SVN можно работать средствами Git. Такая синхронизация разноархитектурных репозиториев, доступная благодаря возможностям Git, поможет вам увидеть преимущества и недостатки разных подходов.
Примечание Данное руководство написано в контексте использования операционной системы Linux. Для других операционных систем необходимо вносить соответствующие коррективы.
Историческая справка
Subversion
Subversion — система управления версиями в свободной лицензии. Известна под сокращенным именем SVN. Разработка Subversion началась в 2000 году по инициативе и финансовой поддержке компании CollabNet Inc.
Основной целью проекта Subversion считается замена устаревший, на тот момент системы контроля версий CVS (Concurrent Versions System). Новый проект должен был сохранить всю функциональность CVS и избавиться от ряда его недостатков.
Официальный выпуск Subversion — 2004 год.
Разработка Git началась в 2005 году, по инициативе разработчика Linux — Линуса Торвальдса.
Двумя важнейшими требованиями к разрабатываемой системе контроля версий были требования эффективности (по скорости и объему) для больших проектов в миллионы строк и поддержки нелинейной разработки (тысячи параллельных веток). Кроме того, Git изначально ориентировался на удаленную специфику разработки проектов.
Технические вопросы устройства
Две концепции, используемые для разделения файлов
Чтобы разделить файловое хранилище на множество пользователей можно использовать одну из двух известных схем разделения.
Обе системы, Subversion и Git, используют вторую схему разделения данных (Copy-Modify-Merge), но делают это немного по-разному.
Физическое представление репозитория
Subversion
SVN относится к типу централизованных систем, в отличии от Git и Mercurial, которые являются представителями класса распределенных систем. Централизованность означает работу схемы только при наличии централизованного хранилища данных.
Развертывание системы Subversion может опираться на две разные физические системы хранения данных репозитория. Исторически, первый вариант организации репозитория был основан на использовании СУБД Berkeley DB. Позже, была выполнена реализация на основе специального файлового хранилища данных (FSFS), поддерживаемое собственными программными библиотеками. Начиная с релиза 1.2 для новых хранилищ, по умолчанию, используется FSFS.
Реализацию на основе СУБД Berkley DB можно считать более капризной. Во-первых, ее настройка требует большего внимания администратора. Во-вторых, Berkley DB требовательна к выбору низлежащей файловой системы — она должна поддерживать блокировки.
Подробности о преимуществах и недостатках разных форм представления репозитория надо уточнять в руководствах по конкретным версиям, и, можно лишь заметить, что на основании некоторых непроверенных фактов, можно допустить, что, в современных реализациях, функциональные преимущества в той или иной модели хранения данных не присутствуют, однако, могут быть различия в производительности на разных операциях с репозиторием.
Логическое представление репозитория
Формально, репозиторий SVN не делится на проекты. Пользователь репозитория может самостоятельно разделить пространство репозитория на директории условно считая их
проектами или подпроектами. Прежде всего это сказывается на то, что при фиксации любой части репозитория (условного проекта) будет увеличен номер ревизии общего репозитория.
SVN vs Git. Здесь мы наблюдаем существенное различие в использовании, и, особенно,
администрировании систем SVN и Git. В Git, под каждый проект в любой директории
можно реализовать работу локального репозитория, чего, часто, для индивидуальной
работы, бывает достаточно. Централизованный репозиторий, при его необходимости,
так же организуется под каждый проект отдельно, позволяя для каждого проекта
построить свою политику прав доступа. Если быть более точным, то Git значительно
сосредоточен именно на средствах управления версиями и, при использовании
централизованных репозиториев, для тонкого разделения доступа к коду проекта
множества пользователей удобнее использовать дополнительные оберточные средства
администрирования Git. Cреди последних, известными являются gitolite и gitosys.
Различают понятия стержневых ревизий (peg revision) и оперативных ревизий (operative revision). Стержневая ревизия представляет собой номер ревизии предназначенный для уточнения файловых историй для оперативных ревизий по которым выполняются операции команд. Т.е. Команда может быть задана по диапазону оперативных ревизий в которых может быть коллизии файловых историй связанных с операциями копирования, перемещения и уничтожения файлов. Чтобы однозначно указать требуемую файловую историю необходимо указывать стержневую ревизию по правому краю диапазона оперативных ревизий, так как история файла однозначно отслеживается только в обратном направлении. При
отслеживании истории в прямом направлении можно столкнуться, например, с разветвлением, созданным при копировании файла. Работа пользователя с файлами проекта выполняется в рабочей копии репозитория, которая создается получением файлового снимка всего репозитория SVN или его части (через уточнение нужной поддиректории) с помощью операции svn checkout (по умолчанию будет передана последняя ревизия). Если пользователь хочет зафиксировать изменения в репозитории проекта, то он должен выполнить операцию svn commit. При каждой фиксации кода создается новая ревизия с большим номером.
Основная суть организации репозитория Git в том, что он хранит файлы в виде файлов, а в качестве имени файла в репозитории используется значение хэш-функции SHA1, вычисленной по содержимому файла.
Таким образом, одинаковые файлы имеют одинаковое значение хеш-функции и хранятся один раз.
Одной из особенностей такого файлового хранения является то, что в Git не хранятся директории как таковые, а только в виде файловых путей. Следовательно, пустую директорию нельзя сохранить в репозитории Git.
Логическое представление репозитория
Объекты репозитория Git бывают четырех типов — blob, tree, commit и tag.
Использование систем контроля версий
Получение справочной информации
Subversion (SVN)
Справочная информация по командам svn может быть получена обращением к самой утилите svn через команду svn help. Введя эту команду в консоли, вы получите полный список всех команд поддерживаемых текущей версией утилиты svn. Для получения информации по конкретной команде надо добавить ее после help. Например:
svn help checkout
svn help commit
svn help mkdir
Создание репозитория
Subversion (SVN)
Продумаем размещение и выберем имя для директории будущего репозитория SVN. При этом подумайте о правах доступа, если репозиторий будет разделяемый. Для простоты я
сделаю репозиторий в своем домашнем каталоге /home/knz с именем 0-svn-repository. Имя начинающееся с нуля предоставит дополнительный приоритет для данной директории для
многих типов сортировок при выводе списка директорий и такая директория не затеряется в окружении многих других директорий домашнего каталога.
Находясь в домашней директории выполним команду.
svnadmin create 0-svn-repository
Репозиторий создан. Пустой репозиторий имеет нулевой номер ревизии. Теперь в него можно добавлять проекты для управления. Дальнейшая последовательность действий может быть такая.
Добавить комментарий Отменить ответ
Для отправки комментария вам необходимо авторизоваться.
Git as Subversion
Некоторое время назад при старте нового проекта было решено попробовать использовать Git вместо Subversion. Через некоторое время коллектив разделился на тех, кто любит Git (программисты), и тех, кто его ненавидит (дизайнеры и художники). Эксперимент по замене Subversion на Git провалился и на горизонте замаячила перспектива возвращения Subversion.
Почесав репу и содрогнувшись от связанных с Subversion воспоминаний мужики решили: «А что, мы же программисты!» и запилили свой Subversion с Git-ом и печеньками. Так родился проект git-as-svn.
Теперь мы можем использовать и Git, и Subversion с одним и тем же репозиторием. Причем доступ через Subversion напрямую использует данные Git-репозитория, в отличие, скажем, от SubGit, где для Subversion используется отдельный репозиторий.
Зачем понадобился еще один велосипед?
Что это и как оно работает
Как работает коммит?
Где хранятся svn-данные репозитория?
Для представления Subversion репозитория нужен ряд данных, которые в Git либо отсутствуют (например, данные о том, откуда скопирован файл), либо очень дорого получить (например, номер ревизии, когда файл менялся в последний раз). Чтобы не заниматься их расчетом каждый запуск, они кэшируются в ветках refs/git-as-svn/*. Этот же кэш позволяет не ломаться соответствии Git-коммитов Subversion-ревизиям из-за операций force push. 😉
Известные проблемы и ограничения
Svn properties
То есть, с настройками по-умолчанию Git меняет содержимое текстовых файлов.
Это потребует от Git не трогать окончания строк у файлов до тех пор, пока его об этом явно не попросят.
И что в итоге?
На данный момент проект находится в неторопливой разработке и эксплуатируется в одной из команд Mail.Ru Group. В результате, люди вольны использовать подходящий для их нужд инструмент: дизайнеры используют TortoiseSvn и заливают им изменения напрямую в master, а программисты пользуются Git-ом и живут в своих уютненьких веточках. Обстановка в целом стала здоровее, и у коллег перестали сжимать кулаки, когда кто-то рядом произносит слова Git или Subversion.
Что нужно сделать, чтобы потыкать в проект палочкой?
Системы управления версиями git и svn
SVN или Subversion является свободной централизованной системой управления версиями. Такие системы используются для облегчения работы с информацией, которая постоянно изменяется. Это может быть исходный код программы, скрипта, веб-страницы, сайта, текстового документа и других. Позволяет хранить несколько версий одного и того же документа, с возможностью возврата к более ранним версиям и просмотра информации о том, кто и какие изменения вносил.
SVN довольно часто используют многие разработчики в качестве открытого ПО. К примеру, Subversion применяется в таких популярных проектах как Apache, GCC, Free Pascal, Python, Ruby, FreeBSD, AROS, Blender, Boost, Tor.
SVN используют для автоматизации процесса разработки и избавления от рутинной работы. Прежде всего, эта программа полезна для веб-специалистов:
Кроме всего этого, система не допускает ошибок, которые веб-разработчик мог бы допустить, выполняя все эти действия вручную.
Среди возможностей данного ПО стоит выделить следующие полезные функции :
В отличии от систем распределения таких как Git, Subversion хранит информацию в одном едином хранилище, которое может быть или на локальном диске или на сетевом сервере. Простая в использовании и одновременно мощная по функционалу система пользуется популярностью у веб-разработчиков.
Для чего используют git : для синхронизации работы с сайтом и хранения/обновлений версий сайтов. Эта система удобна, когда над одним проектом работают одновременно несколько разработчиков. Гит позволяет обновлять и править файлы сайта учитывая изменения, которые были внесенные другими.
Преимущества использования Git:
Git отличается высокой производительностью, имеет развитые средства интеграции с другими VCS. Также включает продуманную систему команд и приятный для работы веб-интерфейс “из коробки”.
Работая с Git вы получаете абсолютный контроль над репозиторием и быстроту работы.
Среди недостатков пользователи чаще всего выделяют: неудобный переход с других VCS; использование для идентификации ревизий хэшей SHA1; система не отслежывает пустые каталоги; уходит много времени на формирование истории конкретного файла, истории правок конкретного пользователя, поиска изменений, относящихся к заданному месту определённого файла и тп.
Компания HyperHost™ желает Вам приятной работы!
Про Git на пальцах (для переходящих с SVN)
Год назад мы с командой решили перейти с SVN на Git. Зачем это было надо — писать не буду, т.к. на эту тему уже и так много написано. А хочу я описать типичные алгоритмы работы, понятные человеку, который долгое время пользовался SVN. Ниже — памятка, написанная для команды год назад, чтобы легче было мигрировать. Надеюсь, кому-нибудь пригодится.
Немного об устройстве Git (упрощённо).
Git — распределённая VCS. Это значит, что мы работаем не с одним репозитарием на сервере, а каждый имеет у себя локальную копию репозитария. Соответственно, такие операции, как checkout и commit производятся с локальным репозитарием. Друг с другом же (или с тем, что на сервере) репозитарии синхронизируются специально предназначенными командами pull (fetch) и push.
Это удобно. Это позволяет коммитить столь часто, сколь угодно, даже если в данный момент отсутствует соединение с сервером.
Важное преимущество Git’а — внятная работа с ветками и удобный механизм слияний (merge). В SVN мы, как правило, работали с одной веткой trunk (в git ветка, с которой мы работаем по умолчанию, называется master). Эта же ветка заливалась на продакшн. Главное неудобство здесь — то, что если мы производим какие-то изменения, или разрабатываем новый функционал, мы вынуждены либо сидеть и не коммитить до тех пор, пока задача не будет доделана до конца, либо (если нам нужна помощь коллеги), закоммитить недоделанный функционал, как есть, сделав таким образом trunk непригодным к заливке на продакшн. Особенно это неприятно, если новый функционал делается не один день, а в это время возникает необходимость что-нибудь срочно починить в рабочей системе.
Надо отметить, что в SVN, конечно, есть ветки, но сделаны они, видимо, для другого, и поэтому плохо приспособлены для того, чтобы их сливать в trunk. В git операция merge сделана изящно и удобно, что позволяет нам существенно изменить workflow на более оптимальный.
Ещё одно отличие git в том, что он хранит не изменения, а текущее состояние проекта в каждый момент времени.
О главном.
Поэтому, хорошим правилом будет, всё же, создание отдельной ветки (за исключением совсем уж простых случаев).
Настройка.
Дополнительно можно настроить shell-alias’ы, как описано в статье №2.
Cтандартный workflow.
Шаг 1. Начало работы — клонирование репозитария.
Предполагается, что у вас уже есть и настроен gitosis, на котором лежит проект.
git clone gitosis@git.yourserver.com:yourproject.git — этот шаг делается один раз.
Результатом будет папка yourproject с проектом у вас на жёстком диске. Команда clone делает следующие вещи: клонирует удалённый репозитарий в новую папку (yourproject в данном случае), создаёт в локальном репозитарии remote-tracking ветки для всех веток удалённого репозитария, создаёт локальную копию активной в данный момент удалённой ветки и делает из неё checkout.
Шаг 2а. Написание нового кода или багфикс.
2. Допустим, мы хотим заимплементить фичу feature. Создаём локально новую ветку с помощью команды branch. Командой checkout можно переключаться между ветками:
$ git branch feature
$ git checkout feature
Switched to branch «feature»
Или, что тоже самое, только короче:
3. В git есть такое понятие как индекс. Например, команда commit добавляет в репозитарий только те файлы, которые есть в данный момент в индексе. Поэтому, во время работы не забываем добавлять (git add ) или удалять (git rm ) файлы в/из индекса репозитария. Обратите внимание, что, в отличие от SVN, если вы изменили файл, его заново нужно добавить в индекс командой git add.
Текущее состояние индекса можно посмотреть командой git status:
Коммиты в репозитарии смотрятся командой git log.
4. Если мы хотим разрабатывать новый функционал совместно, нам нужно опубликовать нашу ветку на сервере, чтобы другие могли с ней работать. Вот как это делается (перед этим необходимо закоммитить все изменения в данной ветке):
(в новых версиях git можно просто git push origin feature:feature)
Команда push отправляет изменения в удалённый репозитарий (origin) из локальной ветки feature в удалённую ветку featurе, предварительно создав её там (refs/heads/feature нужно как раз для создания ветки). В дальнейшем можно будет использовать git push origin feature (по умолчанию git push публикует изменения из всех веток).
Но при таком способе публикации, не устанавливается связь между локальной версией ветки и опубликованной. Т.е. если кто-то закоммитит изменения в эту удаленную ветку и вы сделаете git pull, то будет ошибка:
If you often merge with the same branch, you may want to
configure the following variables in your configuration
file:
See git-config(1) for details.
Т.е. гит не знает с какой ветки ему мерджить. Поэтому можно либо каждый раз указывать это руками:
git pull origin feature
Либо прописать в конфиге:
git config branch.feature.remote origin
git config branch.feature.merge refs/heads/feature
Кроме того можно воспользоваться скриптиком от William Morgan и делать git publish-branch feature вместо всего остального.
Шаг 2б. Как присоединиться к работе над веткой.
Это важно на данном этапе, поскольку просто команда pull смержит удалённую ветку к нам в master, а это не то, что нам нужно.
Далее можно работать аналогично описанному в шаге 2а, синхронизируя репозитарий в каждой из веток командами git pull и git push.
Шаг 2в. Как переключиться в другую ветку, когда в текущей есть изменения и коммитить их рано.
Иногда возникает необходимость срочно переключиться в другую ветку, например для багфикса. Но на полноценный коммит в этой ветке еще не хватает. Для этого существует команда git stash:
Теперь можно смело переключаться в другую ветку и работать там.
По возвращению в эту ветку, необходимо сделать git stash apply:
Шаг 3. merge и rebase.
Подливаем изменения из master в рабочую ветку feature, ветку feature нигде не публикуем, работаем с ней только локально:
$ git checkout feature
Switched to branch «feature»
$ git rebase master
First, rewinding head to replay your work on top of it.
HEAD is now at 89f6a20 file2
Applying feature1
Сливаем изменения из рабочей ветки feature в master, ветка feature нигде не публиковалась, никто из коллег с ней не работал:
$ git checkout master
Switched to branch «master»
$ git rebase feature
First, rewinding head to replay your work on top of it.
HEAD is now at 9bfac0a feature1
Applying file2
Подливаем изменения из master в рабочую ветку feature, ветка feature опубликована на удалённом репозитарии, с ней также работают коллеги:
$ git checkout feature
Switched to branch «feature»
$ git merge master
Merge made by recursive.
file2 | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
create mode 100644 file2
Сливаем изменения из рабочей ветки feature в master, ветка feature публиковалась на удалённом репозитарии для совместной работы:
$ git checkout master
Switched to branch «master»
$ git merge feature
Merge made by recursive.
feature1 | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
create mode 100644 feature1
Шаг 4. Удаление ветки.
После того, как мы закончили работать с веткой и слили изменения в master (или в другую ветку), можно удалить ветку.
Для удаления локальной ветки:
Для удаления remote tracking ветки:
$ git push origin :feature
— [deleted] feature
Вот, вроде, и всё. Этого должно быть достаточно в первое время при миграции с SVN на Git.
Отдельное спасибо хабраюзеру mironov_anton за всяческие дополнения и улучшения данного текста.