Презентация по VCS — различия между версиями
м |
м (→Нюанс @@) |
||
(не показано 6 промежуточных версий этого же участника) | |||
Строка 1: | Строка 1: | ||
− | <slideshow title="" style=" | + | <slideshow title="" style="nobook" scaled="true" font="Calibri" headingmark="@@" centermark="%%" incmark="++" subfooter="Системы контроля версий" footer="" /> |
+ | == @@ == | ||
− | + | [[Файл:FishVCS.svg]] | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | Виталий Филиппов, CUSTIS | |
− | Зачем? | + | === Контроль версий: '''Зачем?''' @@ === |
− | * | + | * Бэкап на случай утери кода<br />{{gray|спонсоры: rm -rf /, Джамшуты, школоло с вирусами}} |
− | * Неблокирующие совместные правки | + | * Неблокирующие совместные правки, синхронизация |
+ | * Поиск виновного (annotate/blame) | ||
* Code review | * Code review | ||
* Поддержка старых версий | * Поддержка старых версий | ||
+ | |||
+ | === История VCS @@ === | ||
+ | |||
+ | …по большей части свободных. | ||
+ | |||
+ | <!-- <div style="margin: 10px; padding: 10px; float: left; box-shadow: 0 0 10px rgba(0,0,0,0.5); text-align: center"> --> | ||
+ | <graph> | ||
+ | digraph rcs { | ||
+ | |||
+ | rankdir = LR; | ||
+ | ranksep = 0; | ||
+ | bgcolor = transparent; | ||
+ | node [fillcolor="#fff0e0", style=filled, fontname=sans, fontsize=12]; | ||
+ | edge [fontname=sans, fontsize=12]; | ||
+ | |||
+ | node [shape=box, style="filled, rounded"]; | ||
+ | lvcs [label="Локальные", fillcolor="#e0ffe0"]; | ||
+ | cvcs [label="Централизованные", fillcolor="#e0f0ff"]; | ||
+ | dvcs [label="Распределённые"]; | ||
+ | lvcs -> cvcs [minlen=2]; | ||
+ | cvcs -> dvcs [minlen=2]; | ||
+ | |||
+ | node [shape=plaintext, style=solid]; | ||
+ | 1972 -> 1985 -> 1990 -> 1998 -> 2000 -> 2003 -> 2005 -> 2007; | ||
+ | |||
+ | node [shape=oval, style=filled]; | ||
+ | SCCS [fillcolor="#e0ffe0"]; | ||
+ | RCS [fillcolor="#e0ffe0"]; | ||
+ | CVS [fillcolor="#e0f0ff"]; | ||
+ | CVSnt [fillcolor="#e0f0ff"]; | ||
+ | Subversion [fillcolor="#e0f0ff"]; | ||
+ | SCCS -> BitKeeper [minlen=4]; | ||
+ | SCCS -> RCS [label=free, style=dashed]; | ||
+ | RCS -> CVS; | ||
+ | CVS -> Subversion [label="CVS done right", style=dashed, minlen=2]; | ||
+ | CVS -> CVSnt; | ||
+ | Monotone -> Git [style=dashed]; | ||
+ | Monotone -> Mercurial [style=dashed]; | ||
+ | BitKeeper -> Git [style=dashed, minlen=2]; | ||
+ | BitKeeper -> Mercurial [style=dashed, minlen=2]; | ||
+ | tla [label="GNU Arch"]; | ||
+ | CVS -> tla [style=dashed, minlen=2, label="альтернатива CVS"]; | ||
+ | tla -> Baz; | ||
+ | tla -> darcs [style=dashed]; | ||
+ | Baz -> Bazaar [style=dashed, minlen=2]; | ||
+ | |||
+ | } | ||
+ | </graph> | ||
+ | |||
+ | === Терминология @@ === | ||
+ | |||
+ | <tab sep="bar" class="wikitable" head="left" col2="text-align: center"> | ||
+ | Метка | tag | именованная версия проекта | ||
+ | Ветка | branch | «метка, имеющая историю развития» | ||
+ | Репозиторий | repository | хранилище версий | ||
+ | Рабочая копия | work copy | копия проекта, связанная с репозиторием | ||
+ | Коммит, фиксация | commit, checkin | сохранение изменений в репозитории | ||
+ | Чекаут, извлечение | checkout | получение рабочей копии (без истории) | ||
+ | Push, pull | | отправка/получение изменений в/из другого репозитория | ||
+ | cvs HEAD<br />svn trunk<br />git master | | Основная ветка | ||
+ | </tab> | ||
+ | |||
+ | === На заметку: интерфейсы @@ === | ||
+ | |||
+ | * {{mag|$ командная строка}} | ||
+ | * Web-интерфейсы (для просмотра и поиска). | ||
+ | * GUI, обычные и встроенные в IDE. | ||
== Локальные VCS @@ == | == Локальные VCS @@ == | ||
− | Простейший | + | Простейший вариант — архивы или папочки со старыми версиями.<br /> |
''(не надо так делать)'' | ''(не надо так делать)'' | ||
Строка 48: | Строка 113: | ||
</graph> | </graph> | ||
− | == Diff, patch @@ == | + | === Diff, patch, merge @@ === |
[[File:Diff-screenshot.png|right|200px]] | [[File:Diff-screenshot.png|right|200px]] | ||
− | * diff (1970) | + | * {{mag|diff (1970)}} — подсчёт разницы между текстовыми файлами ([[rupedia:наибольшая общая подпоследовательность|алгоритм]]) |
− | + | * {{mag|patch (1984)}} — применение этих разниц — '''патчей''' | |
− | * | + | *: Автор — Лэрри Уолл (создатель Perl’а) |
− | *: | + | * {{mag|rcsmerge (1982), diff3}} (поновее) — слияние изменений |
<div style="clear: both"></div> | <div style="clear: both"></div> | ||
− | == | + | === Как это было в RCS @@ === |
− | + | Команды RCS называются просто '''co''' и '''ci'''. | |
− | + | ||
− | ''' | + | «Репозиторий» для каждого файла «свой» — '''{{green|файл.txt,v}}''' является «репозиторием» для файла.txt. Лежит либо прямо рядом, либо в подпапке RCS. |
+ | |||
+ | ''{{blue|<создали файл.txt>}}'' | ||
+ | {{mag|$ '''ci''' -t-'В этом файле содержится мудрость Господня' файл.txt}} | ||
+ | '''{{green|файл.txt,v}}''' <-- файл.txt | ||
+ | initial revision: 1.1 | ||
+ | done | ||
+ | {{mag|$ co файл.txt}} {{brown|# на посмотреть}} | ||
+ | '''{{green|файл.txt,v}}''' --> файл.txt | ||
+ | revision 1.1 | ||
+ | done | ||
+ | {{mag|$ co -l файл.txt}} {{brown|# блокируем файл (хотим править)}} | ||
+ | '''{{green|файл.txt,v}}''' --> файл.txt | ||
+ | revision 1.1 (locked) | ||
+ | done | ||
+ | {{blue|''<...правим...>''}} | ||
+ | {{mag|$ ci -m'Мудрость исправлена' файл.txt}} | ||
+ | '''{{green|файл.txt,v}}''' <-- файл.txt | ||
+ | new revision: 1.2; previous revision: 1.1 | ||
+ | done | ||
+ | |||
+ | == Централизованные VCS %% @@ == | ||
<graph> | <graph> | ||
Строка 105: | Строка 190: | ||
</graph> | </graph> | ||
− | + | * История версий хранится на центральном сервере | |
+ | * Рабочие копии создаются на компьютерах разработчиков | ||
− | + | '''CVS (1990), Subversion (2000).''' | |
− | + | ||
− | + | ||
− | ''' | + | === CVS: прикрученный к RCS сервер @@ === |
+ | |||
+ | Справедливо решили, что файлы и репозиторий вперемешку — '''{{red|не дело}}'''! | ||
+ | |||
+ | Репозиторий теперь хранится '''отдельно''', а то и '''удалённо'''. Однако, всё равно пофайлово. | ||
+ | |||
+ | {{mag|1=$ export CVSROOT=/path/to/new/repo}} {{brown|# задаём путь к репозиторию}} | ||
+ | {{mag|$ cvs init}} {{brown|# создаём репозиторий}} | ||
+ | cvs init: Repository /path/to/new/repo initialised | ||
+ | {{mag|$ cvs import module custis}} {{brown|# импорт текущей папки}} | ||
+ | N module/file | ||
+ | ... | ||
+ | |||
+ | No conflicts created by this import | ||
+ | {{mag|$ cvs co module}} {{brown|# извлекаем}} | ||
+ | cvs checkout: Updating module | ||
+ | U module/file | ||
+ | {{blue|''<...правим файлы...>''}} | ||
+ | cd module | ||
+ | {{mag|$ cvs ci -m 'Сообщение об исправлении'}} | ||
+ | cvs commit: Examining . | ||
+ | Checking in file; | ||
+ | '''/path/to/repo/mod/file,v''' <-- file | ||
+ | new revision: 1.2; previous revision: 1.1 | ||
+ | done | ||
+ | |||
+ | === CVS: и даже… @@ === | ||
+ | |||
+ | <div style="float: left; margin-right: 2em">[[File:TortoiseCVS.png|link=http://www.tortoisecvs.org/]]</div> | ||
+ | * …умеет annotate (blame). | ||
+ | * …умеет ветвиться и сливаться, хоть и криво. | ||
+ | * …умеет хуки. | ||
+ | * …имеет ГУИ — например, [http://www.tortoisecvs.org/ TortoiseCVS]. | ||
+ | |||
+ | '''Однако…''' | ||
+ | |||
+ | * Репозиторий {{red|пофайловый}} на основе RCS<br />{{red|☹}} версии у файлов отдельные (и дурацкие типа 1.128.2.5)<br />{{red|☹}} коммиты неатомарны | ||
+ | * Протокол сервера неудобен | ||
+ | * Устарел в целом (различные мелкие недостатки) | ||
+ | *: {{gray|Маразм: порядок аргументов в командной строке влияет на результат}} | ||
+ | |||
+ | === Subversion: «{{mag|CVS Done Right}}» @@ === | ||
+ | |||
+ | [[File:Apache Software Foundation Logo.svg|200px|right]] | ||
+ | [[File:Subversion-logo.jpg|150px|right]] | ||
+ | {{green|☺}} Всё поновее, пошустрее, поудобнее (форматы, протоколы…)<br /> | ||
+ | {{green|☺}} Общий номер ревизии, атомарные коммиты<br /> | ||
+ | {{green|☺}} Права доступа{{mag|**}}<br /> | ||
+ | {{green|☺}} UTF-8, mime типы, свойства файлов<br /> | ||
+ | {{brown|?}} Копирование вместо веток/меток; {{green|☺}} mergeinfo | ||
+ | |||
+ | Web: [[File:Viewvc-logo.png|128px|link=ViewVC]] | ||
+ | |||
+ | ГУИ: [[File:RabbitVCS-rabbit.png|32px|link=http://rabbitvcs.org/]] [http://rabbitvcs.org/ RabbitVCS], [[File:TortoiseSVN-tort.png|64px|link=http://tortoisesvn.net/]] [http://tortoisesvn.net/ TortoiseSVN]<br /> | ||
+ | (для конченых виндузятников) [http://www.visualsvn.com/ VisualSVN], [http://ankhsvn.open.collab.net/ AnkhSVN] | ||
+ | |||
+ | ----- | ||
+ | {{mag|**}} Благодаря оным — горячо любим компаниями, в том числе и Этой. | ||
+ | |||
+ | ==== Subversion: однако… @@ ==== | ||
+ | |||
+ | {{red|☹}} Нет контроля целостности<br /> | ||
+ | {{red|☹}} Не очень удобные ветвления/слияния<br /> | ||
+ | {{red|☹}} Нет ''родного'' Web-интерфейса<br /> | ||
+ | {{red|☹ (?)}} Централизованная<br /> | ||
+ | {{red|☹}} Торвальдс: '''«There is no way to do CVS right»''' | ||
+ | |||
+ | == Распределённые VCS @@ == | ||
+ | <div style="float: left; margin-right: 2em"> | ||
<graph> | <graph> | ||
digraph local { | digraph local { | ||
Строка 131: | Строка 283: | ||
} | } | ||
</graph> | </graph> | ||
+ | </div> | ||
− | === Пример | + | * Каждая копия содержит всю историю ревизий |
+ | * Возможен обмен между любыми участниками | ||
+ | * Лёгкость ветвления и слияния | ||
+ | |||
+ | '''[http://www.gnu.org/software/gnu-arch/ TLA / GNU Arch] (2001); [http://monotone.ca/ Monotone], [http://darcs.net/ Darcs] (2003); [http://git-scm.com/ Git], [http://mercurial.selenic.com/ Mercurial] (2005); [http://bazaar.canonical.com/ Bazaar] (2007).''' | ||
+ | |||
+ | [[File:GNU Arch.png|64px|link=http://www.gnu.org/software/gnu-arch/]] | ||
+ | [[File:Monotone.png|64px|link=http://monotone.ca/]] | ||
+ | [[File:Darcs.png|96px|link=http://darcs.net/]] | ||
+ | [[File:Git.png|80px|link=http://git-scm.com/]] | ||
+ | [[File:Mercurial.png|64px|link=http://mercurial.selenic.com/]] | ||
+ | [[File:Bazaar.png|64px|link=http://bazaar.canonical.com/]] | ||
+ | |||
+ | <p style="text-align: right">{{red|*}} Ещё были выкидыши типа [http://svk.bestpractical.com/view/HomePage SVK]</p> | ||
+ | |||
+ | <div style="clear: both"></div> | ||
+ | |||
+ | === Пример ветвления — Feature Branches %% @@ === | ||
Смысл: каждая доработка ''в отдельной ветке''. | Смысл: каждая доработка ''в отдельной ветке''. | ||
− | + | Создаются → правятся → сливаются обратно в trunk. | |
− | + | [[Файл:TN-IShop-Revision-Graph.svg|300px]] | |
− | + | ==== Нюанс @@ ==== | |
+ | |||
+ | Слияние отменить {{red|невозможно}}!<br /> | ||
+ | {{green|⇒}} разрешайте конфликты в ветке «фичи», а не в «мастере». | ||
+ | |||
+ | [[File:CantRedoMerge.svg]] | ||
+ | |||
+ | === Как можно обмениваться: дерево доверия %% @@ === | ||
+ | |||
+ | (Репозитории или ветки) | ||
<graph> | <graph> | ||
Строка 146: | Строка 325: | ||
rankdir=BT; | rankdir=BT; | ||
compound=true; | compound=true; | ||
+ | bgcolor=transparent; | ||
node [fillcolor="#e0e0e0", shape=box, style="filled,rounded", fontname=sans]; | node [fillcolor="#e0e0e0", shape=box, style="filled,rounded", fontname=sans]; | ||
− | prod [label="Продукт"]; | + | prod [fillcolor="#e0ffe0", label="Продукт"]; |
test [label="Проверяющий"]; | test [label="Проверяющий"]; | ||
test -> prod; | test -> prod; | ||
Строка 173: | Строка 353: | ||
</graph> | </graph> | ||
− | === Эмуляция централизации @@ === | + | === Эмуляция централизации %% @@ === |
Можно работать с DVCS, ''почти''{{red|*}} как с централизованной! | Можно работать с DVCS, ''почти''{{red|*}} как с централизованной! | ||
Строка 179: | Строка 359: | ||
<twopi> | <twopi> | ||
digraph x { | digraph x { | ||
+ | bgcolor=transparent; | ||
node [fillcolor="#e0e0e0", shape=box, style="filled,rounded", fontname=sans]; | node [fillcolor="#e0e0e0", shape=box, style="filled,rounded", fontname=sans]; | ||
s [fillcolor="#ffe0e0", label="Сервер"]; | s [fillcolor="#ffe0e0", label="Сервер"]; | ||
Строка 192: | Строка 373: | ||
{{red|*}} Вынеся за скобки отсутствие пофайловости. | {{red|*}} Вынеся за скобки отсутствие пофайловости. | ||
− | == | + | === Минусы DVCS @@ === |
− | + | * Репозиторий пухнет | |
+ | *: {{blue|Хочешь Андроид? Слей 6 гигов!}} | ||
+ | * Отсутствие пофайловости (и {{green|☺}}, и {{red|☹}}) | ||
+ | * Бывает нужно переписывать историю всех репозиториев в Москве | ||
− | + | === Откуда ноги растут? %% @@ === | |
− | + | ||
− | + | ||
− | + | Из разработки ядра Linux! | |
− | + | ||
− | + | ||
− | + | [[File:Tux.svg|100px]] | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ==== Linux @@ ==== | |
− | + | ||
− | + | * 1992—2002: тарболлы и патчи | |
− | + | *: ''{{green|«и это была лучшая система контроля версий, чем CVS»}}'' | |
− | + | * 2002—2005 — BitKeeper | |
− | + | *: ''проприетарщики такие проприетарщики'' | |
− | + | *: обиделись на «реверс-инжиниринг» — команду help на сервере | |
− | + | * Monotone и Darcs уже тоже были | |
− | + | *: но первый {{red|O(n<sup>3</sup>)}}, второй {{red|O(e<sup>n</sup>)}} | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | Monotone | + | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | Из идей Monotone и BitKeeper родились '''Git''' (Linus Torvalds) и '''Mercurial''' (Matt Mackall). | |
− | + | ||
− | + | : [[File:Linus-torvalds-fuck-nvidia.jpg|200px]] ⇒ [[File:Git.png|100px]] [[File:Matt Mackall.jpg|145px]] ⇒ [[File:Mercurial.png|80px]] | |
− | + | === Git и Mercurial @@ === | |
− | + | ||
− | + | ||
− | + | ||
− | + | * Git: Tracking Branches (и {{green|☺}}, и {{red|☹}}) | |
+ | * Mercurial: Гораздо интиутивнее система команд (см. [http://www.wikivs.com/wiki/Git_vs_Mercurial сюда]) | ||
+ | * Git: {{green|В целом быстрее}}, но не всегда, плюс {{red|имеет задержки GC}} | ||
+ | * Git: Хранит эффективнее {{green|в 1.5-2 раза}} (в нём граф объектов) | ||
+ | * Мощность функционала {{green|<big>≈</big>}} | ||
+ | * Mercurial: {{blue|Python}}, вместо Gitовского микса {{red|C+Bash+Perl}} | ||
+ | * Git: Есть [http://code.google.com/p/gerrit/ Gerrit]! | ||
− | == | + | === Bazaar @@ === |
− | + | Bazaar — творение Ubuntu (с [[lurkmore:Блэкджек и шлюхи|БДж и Ш]]) | |
− | + | ||
− | + | {{red|☹}} 1 клон = 1 ветка {{red|☹☹☹}}<br /> | |
− | + | {{red|☹}} Принудительные слияния, один HEAD, пляски ревизий {{red|☹☹☹}}<br /> | |
− | + | {{green|☺}} Есть легковесные Checkout’ы а-ля SVN<br /> | |
− | + | {{red|☹}} Не умеет ASCII-графы рисовать :-D<br /> | |
− | + | {{green|☺}} Зато успешно хавает жирные текстовые файлы. | |
− | + | ||
− | + | === Rebase @@ === | |
− | + | ||
+ | Когда не хочется или невозможно мержить. | ||
+ | |||
+ | [[File:Rebase.svg]] | ||
+ | |||
+ | === Очередь патчей (Patch Queue) @@ === | ||
+ | |||
+ | Стандартная тема: приём сторонних патчей в свободный проект. | ||
+ | |||
+ | * Вася пофиксил баг в Mercurial и ещё добавил фичу | ||
+ | * Сказал {{mag|hg commit}} всего вместе | ||
+ | * Отправляет Мэтту по почте результат {{mag|hg export}} | ||
+ | * А Мэтт говорит: | ||
+ | *# поправь {{green|вот тут}} и {{green|вот там}} | ||
+ | *# а ещё {{red|раздели патч}} на багфикс и фичу! | ||
+ | * {{blue|''…и что делать Васе — клонировать заново?''}} | ||
+ | |||
+ | ==== На помощь идёт MQ! @@ ==== | ||
+ | |||
+ | [http://mercurial.selenic.com/wiki/MqExtension/ Mercurial Queues], аналоги — [http://procode.org/stgit/ StGIT], [https://launchpad.net/bzr-loom/ bzr-loom]. Все по мотивам [http://savannah.nongnu.org/projects/quilt quilt]. | ||
+ | |||
+ | Разделение патчей: | ||
+ | |||
+ | {{mag|$ hg qimport -n feature -r .}} {{brown|# превратить текущую правку в патч}} | ||
+ | {{blue|<...выделяем и удаляем багфикс...>}} | ||
+ | {{mag|$ hg diff --reverse > P2}} | ||
+ | {{mag|$ hg qrefresh}} {{brown|# из feature убран багфикс}} | ||
+ | {{mag|$ hg qimport -n bugfix -r P2 -P}} {{brown|# создаём патч-багфикс}} | ||
+ | |||
+ | ==== Правка патчей @@ ==== | ||
+ | |||
+ | Для работы над одним из патчей: | ||
+ | {{mag|$ hg qpop}} {{brown|# временно убираем багфикс для работы над фичей}} | ||
+ | {{blue|<...вносим правки Мэтта...>}} | ||
+ | {{mag|$ hg qrefresh}} {{brown|# сохраняем правки}} | ||
+ | {{mag|$ hg qpush}} {{brown|# возвращаем багфикс}} | ||
+ | |||
+ | Если проект по пути обновится: | ||
+ | {{mag|$ hg qpop -a; hg up; hg qpush -a}} | ||
+ | |||
+ | Мэтт тем же MQ импортирует (qimport) и принимает (qfinish) патчи. | ||
+ | |||
+ | == Заметки для себя == | ||
+ | |||
+ | * Интерфейсы | ||
+ | ** Commandline | ||
+ | ** GUI: tortoise{cvs, svn, hg, git}, msysgit | ||
+ | ** Web: viewvc, hgweb, gitweb, gerrit | ||
+ | ** Хостинги: google code, bitbucket, github, launchpad | ||
+ | * MQ, патчи | ||
+ | * Практика | ||
+ | ** Feature Branch | ||
+ | ** SVN | ||
+ | ** Mercurial | ||
+ | ** Git | ||
+ | * {{mag|Commit Early Commit Often}}! Хотя бы каждый день :-) |
Текущая версия на 17:17, 1 ноября 2013
- Автор
- Виталий Филиппов
- Дополнительный нижний колонтитул
- Системы контроля версий
Содержание
- 1 @@
- 2 Локальные VCS @@
- 3 Централизованные VCS %% @@
- 4 Распределённые VCS @@
- 5 Заметки для себя
@@
Виталий Филиппов, CUSTIS
Контроль версий: Зачем? @@
- Бэкап на случай утери кода
спонсоры: rm -rf /, Джамшуты, школоло с вирусами - Неблокирующие совместные правки, синхронизация
- Поиск виновного (annotate/blame)
- Code review
- Поддержка старых версий
История VCS @@
…по большей части свободных.
Терминология @@
Метка | tag | именованная версия проекта |
---|---|---|
Ветка | branch | «метка, имеющая историю развития» |
Репозиторий | repository | хранилище версий |
Рабочая копия | work copy | копия проекта, связанная с репозиторием |
Коммит, фиксация | commit, checkin | сохранение изменений в репозитории |
Чекаут, извлечение | checkout | получение рабочей копии (без истории) |
Push, pull | отправка/получение изменений в/из другого репозитория | |
cvs HEAD svn trunk git master | Основная ветка |
На заметку: интерфейсы @@
- $ командная строка
- Web-интерфейсы (для просмотра и поиска).
- GUI, обычные и встроенные в IDE.
Локальные VCS @@
Простейший вариант — архивы или папочки со старыми версиями.
(не надо так делать)
SCCS (1972), RCS (1985).
Diff, patch, merge @@
- diff (1970) — подсчёт разницы между текстовыми файлами (алгоритм)
- patch (1984) — применение этих разниц — патчей
- Автор — Лэрри Уолл (создатель Perl’а)
- rcsmerge (1982), diff3 (поновее) — слияние изменений
Как это было в RCS @@
Команды RCS называются просто co и ci.
«Репозиторий» для каждого файла «свой» — файл.txt,v является «репозиторием» для файла.txt. Лежит либо прямо рядом, либо в подпапке RCS.
<создали файл.txt> $ ci -t-'В этом файле содержится мудрость Господня' файл.txt файл.txt,v <-- файл.txt initial revision: 1.1 done $ co файл.txt # на посмотреть файл.txt,v --> файл.txt revision 1.1 done $ co -l файл.txt # блокируем файл (хотим править) файл.txt,v --> файл.txt revision 1.1 (locked) done <...правим...> $ ci -m'Мудрость исправлена' файл.txt файл.txt,v <-- файл.txt new revision: 1.2; previous revision: 1.1 done
Централизованные VCS %% @@
- История версий хранится на центральном сервере
- Рабочие копии создаются на компьютерах разработчиков
CVS (1990), Subversion (2000).
CVS: прикрученный к RCS сервер @@
Справедливо решили, что файлы и репозиторий вперемешку — не дело!
Репозиторий теперь хранится отдельно, а то и удалённо. Однако, всё равно пофайлово.
$ export CVSROOT=/path/to/new/repo # задаём путь к репозиторию $ cvs init # создаём репозиторий cvs init: Repository /path/to/new/repo initialised $ cvs import module custis # импорт текущей папки N module/file ... No conflicts created by this import $ cvs co module # извлекаем cvs checkout: Updating module U module/file <...правим файлы...> cd module $ cvs ci -m 'Сообщение об исправлении' cvs commit: Examining . Checking in file; /path/to/repo/mod/file,v <-- file new revision: 1.2; previous revision: 1.1 done
CVS: и даже… @@
- …умеет annotate (blame).
- …умеет ветвиться и сливаться, хоть и криво.
- …умеет хуки.
- …имеет ГУИ — например, TortoiseCVS.
Однако…
- Репозиторий пофайловый на основе RCS
☹ версии у файлов отдельные (и дурацкие типа 1.128.2.5)
☹ коммиты неатомарны - Протокол сервера неудобен
- Устарел в целом (различные мелкие недостатки)
- Маразм: порядок аргументов в командной строке влияет на результат
Subversion: «CVS Done Right» @@
☺ Всё поновее, пошустрее, поудобнее (форматы, протоколы…)
☺ Общий номер ревизии, атомарные коммиты
☺ Права доступа**
☺ UTF-8, mime типы, свойства файлов
? Копирование вместо веток/меток; ☺ mergeinfo
ГУИ: RabbitVCS, TortoiseSVN
(для конченых виндузятников) VisualSVN, AnkhSVN
** Благодаря оным — горячо любим компаниями, в том числе и Этой.
Subversion: однако… @@
☹ Нет контроля целостности
☹ Не очень удобные ветвления/слияния
☹ Нет родного Web-интерфейса
☹ (?) Централизованная
☹ Торвальдс: «There is no way to do CVS right»
Распределённые VCS @@
- Каждая копия содержит всю историю ревизий
- Возможен обмен между любыми участниками
- Лёгкость ветвления и слияния
TLA / GNU Arch (2001); Monotone, Darcs (2003); Git, Mercurial (2005); Bazaar (2007).
* Ещё были выкидыши типа SVK
Пример ветвления — Feature Branches %% @@
Смысл: каждая доработка в отдельной ветке.
Создаются → правятся → сливаются обратно в trunk.
Нюанс @@
Слияние отменить невозможно!
⇒ разрешайте конфликты в ветке «фичи», а не в «мастере».
Как можно обмениваться: дерево доверия %% @@
(Репозитории или ветки)
Эмуляция централизации %% @@
Можно работать с DVCS, почти* как с централизованной!
* Вынеся за скобки отсутствие пофайловости.
Минусы DVCS @@
- Репозиторий пухнет
- Хочешь Андроид? Слей 6 гигов!
- Отсутствие пофайловости (и ☺, и ☹)
- Бывает нужно переписывать историю всех репозиториев в Москве
Откуда ноги растут? %% @@
Из разработки ядра Linux!
Linux @@
- 1992—2002: тарболлы и патчи
- «и это была лучшая система контроля версий, чем CVS»
- 2002—2005 — BitKeeper
- проприетарщики такие проприетарщики
- обиделись на «реверс-инжиниринг» — команду help на сервере
- Monotone и Darcs уже тоже были
- но первый O(n3), второй O(en)
Из идей Monotone и BitKeeper родились Git (Linus Torvalds) и Mercurial (Matt Mackall).
Git и Mercurial @@
- Git: Tracking Branches (и ☺, и ☹)
- Mercurial: Гораздо интиутивнее система команд (см. сюда)
- Git: В целом быстрее, но не всегда, плюс имеет задержки GC
- Git: Хранит эффективнее в 1.5-2 раза (в нём граф объектов)
- Мощность функционала ≈
- Mercurial: Python, вместо Gitовского микса C+Bash+Perl
- Git: Есть Gerrit!
Bazaar @@
Bazaar — творение Ubuntu (с БДж и Ш)
☹ 1 клон = 1 ветка ☹☹☹
☹ Принудительные слияния, один HEAD, пляски ревизий ☹☹☹
☺ Есть легковесные Checkout’ы а-ля SVN
☹ Не умеет ASCII-графы рисовать :-D
☺ Зато успешно хавает жирные текстовые файлы.
Rebase @@
Когда не хочется или невозможно мержить.
Очередь патчей (Patch Queue) @@
Стандартная тема: приём сторонних патчей в свободный проект.
- Вася пофиксил баг в Mercurial и ещё добавил фичу
- Сказал hg commit всего вместе
- Отправляет Мэтту по почте результат hg export
- А Мэтт говорит:
- поправь вот тут и вот там
- а ещё раздели патч на багфикс и фичу!
- …и что делать Васе — клонировать заново?
На помощь идёт MQ! @@
Mercurial Queues, аналоги — StGIT, bzr-loom. Все по мотивам quilt.
Разделение патчей:
$ hg qimport -n feature -r . # превратить текущую правку в патч <...выделяем и удаляем багфикс...> $ hg diff --reverse > P2 $ hg qrefresh # из feature убран багфикс $ hg qimport -n bugfix -r P2 -P # создаём патч-багфикс
Правка патчей @@
Для работы над одним из патчей:
$ hg qpop # временно убираем багфикс для работы над фичей <...вносим правки Мэтта...> $ hg qrefresh # сохраняем правки $ hg qpush # возвращаем багфикс
Если проект по пути обновится:
$ hg qpop -a; hg up; hg qpush -a
Мэтт тем же MQ импортирует (qimport) и принимает (qfinish) патчи.
Заметки для себя
- Интерфейсы
- Commandline
- GUI: tortoise{cvs, svn, hg, git}, msysgit
- Web: viewvc, hgweb, gitweb, gerrit
- Хостинги: google code, bitbucket, github, launchpad
- MQ, патчи
- Практика
- Feature Branch
- SVN
- Mercurial
- Git
- Commit Early Commit Often! Хотя бы каждый день :-)