asm32.info
Keep it simple — code in asm

Fossil - ускорен курс.

1. Кратко въведение.

Що е то "Фосил" и за какво ни трябва? Краткият отговор гласи, че Фосил е разпределена система за контрол на версиите, съдържаща допълнителни възможности.

Разширеният отговор ще трябва да включи кратък обзор на това какво е система за контрол на версиите и за какво се използва.

Системата за контрол на версиите е програма, които позволяват да се запазват различни версии на един и същ документ и след това дават възможност с тези различни версии да бъдат извършвани различни операции. Работа с различните версии едновременно, сливане и разклоняване, сравнение и т.н. Като правило версиите могат да се развиват дървовидно, тоест от една версия на документа да възникнат няколко следващи версии. Различните разклонения на дървото на версиите могат да се разклоняват, сливат или прекратяват според желанието на потребителя.

В частност, това позволява няколко човека да работят едновременно върху един и същ документ и след това в този документ автоматично да бъдат комбинирани всички промени правени от различните потребители.

Системите за контрол на версиите могат да се използват за всякакви текстови документи, но те се използват главно създаване и управление на софтуерни проекти.

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

А когато върху един и същ проект работят повече от един човек, използването на такава система е абсолютно задължително.

Най-общо има два вида системи за контрол на версиите - системи от вида "клиент-сървър" и т.н. "разпределени системи за контрол на версиите"

Сравнението на тези две системи е встрани от темата на тази статия, затова ще кажа само, че разпределените системи са по-нова концепция, която в момента може да се каже, че е най-разпространена. Фосил има именно такава архитектура.

2. Кратко наблюдение.

Според моя опит, начинаещите програмисти банално си нямат никаква представа от системи за контрол на версиите. Никой не ги учи да използват такива, а и самите те мислят (ако въобще са чували), че това е нещо почти ненужно и си карат чрез просто създаване на копия на файловете в папки от рода на "MyProject2", "MyProjectPrev", "MyProjectV2_1" и т.н. Аз самият дълги години карах така и си мислих, че ми е удобно.

Всеки програмист задължително трябва да използва система за контрол на версиите! Използването на която и да е такава система ускорява многократно скоростта за разработка и намалява грешките драстично!

А работата със системите за контрол на версиите всъщност е невероятно просто. Всеки може да го научи за нула време, което пък прави не знаенето и не моженето още по-непростимо.

Използването на система за контрол на версиите в известна степен е дори по-важно от знаенето на езика за програмиране! По простата причина, че всеки програмист така или иначе си знае, че трябва да учи езици за програмиране, а за системите за контрол на версиите просто не се сеща.

3. Терминология

Ще давам термините на български и английски, тъй като някои от термините и без това нямат български еквивалент и се използват английските термини.

хранилище (repository) - мястото, където се съхраняват различните версии на файловете. В различните системи, това може да е просто група файлове или база данни от някакъв тип.

Файловете в хранилището обикновено се съхраняват компресирани с високо ефективни алгоритми, което позволява да се постигнат много високи нива на компресия - тоест голямо количество версии могат да се съхраняват без да заемат твърде много място.

чекаут (checkout) - процеса при който някаква версия на файловете се изважда от хранилището и поставя във вид на файлове и директории на диска на потребителя. За да работим върху файловете, трябва да направим checkout.

чек-ин, комит, събмит (checkin, commit, submit) - процеса при който промените по работните файлове от диска на потребителя се запомнят в хранилището като нова версия.

клониране (clone) - Клониране на хранилището. Представлява копиране на цялото хранилище на компютъра на потребителя, обикновено от отдалечен компютър. При разпределените системи за контрол на версиите това е процедура, която всеки потребител трябва да направи преди да започне да работи със хранилището.

бранч (branch) - разклонение на проекта, което се развива самостоятелно. Всяко такова разклонение започва от някоя версия и може да съдържа няколко последователно подредени версии. Различните бранчове могат да се сливат, разделят на нови бранчове или въобще да бъдат прекратявани. Използват се за да се експериментира с някакъв код, който предварително не е ясно как ще се реализира или дали въобще ще работи. Могат да се използват и за да могат няколко човека да работят по различни варианти на програмата. Или въобще, когато програмата съществува в няколко варианта, например за различни платформи.

(въобще, според правилата на българският език, правилният превод на "branch" е "разклонение", "дял на река", "бранш". Ама, професионален жаргон, какво можем да направим.)

трънк (trunk) - главният бранч на проекта. Обикновено се държи той да съдържа работоспособна версия на програмата. За официална версия на програмата обикновено се обявява някоя от версията на трънка.

сливане (merge) - Представлява сливане на две версии на даден файл при което резултата е файл, който съдържа промените от двата файла едновременно. Обикновено се сливат всички файлове от два бранча, но това не е задължително.

разлика (diff) - Намиране на разликите между две различни версии на един файл. Разликите могат да се състоят от информация, която се добавя и информация, която се изтрива от началният файл, така че да се получи крайния.

4. Fossil - миниатюрният великан.

Защо Fossil? Ами защото е изключително проста и богата на възможности система, която се изучава лесно, използва лесно и дава на потребителя всичко необходимо за нормална работа, плюс екстри, присъщи на много по-сложните системи.

Fossil е разработка на Д. Ричард Хип - човекът, повече известен с великолепната база данни SQLite. Fossil е изпълнен по същата схема - малък като размер, напълно интегриран продукт с огромни възможности. Цялата система се състои от един сравнително малък изпълним файл (около 1МБ), който съдържа всички компоненти.

Уеб базиран графичен интерфейс към хранилището - за целта във Фосил е вграден уеб сървър, който може да се използва локално и глобално. В режим на уеб сървър, Фосил по същество представлява уеб сайт на проекта, който може да се оформя лесно в различни дизайни, според желанията на потребителя.

Вградена wiki система, подходяща за писане на документация или просто статии, свързани с проекта.

Вграден бъг тракер в който потребителите могат да описват проблеми в проекта или да подават заявки за поддръжка и помощ.

Изключително надеждно съхраняване на информацията. Една от основните идеи на Фосил е, че хранилището не бива да се поврежда при никакви обстоятелства. Това се постига чрез използването на транзакционна, релационна база данни за хранилище на документите. (SQLite разбира се). При това всички операции в базата данни са атомарни. Загуба на информация е почти невъзможна, включително при спиране на захранването по време на запис в хранилището.

Не се нуждае от инсталация - просто копирате файла в директория фигурираща в PATH и можете да ползвате системата. Изтриването на файла е равнозначно на деинсталация. Обновяването се състои в копиране на новата версия на мястото на старата.

Всички мрежови операции стават през HTTP протокол, с поддръжка на прокси сървър, което позволява системата да работи дори във високо защитена среда зад прокси, защитна стена, маршрутизатори и т.н.

Фосил има малък брой команди почти без опции, които се ползват интуитивно. Освен това има вградена помощна система. Това я прави лесна за изучаване и използване, без да е нужно да се запомня почти нищо.

Допълнителна помощ за начинаещите е, че за всяка операция има възможност да бъде отменена, ако резултата не съвпада с очакваният.

5. Инсталиране на Фосил.

Инсталацията на Фосил е изключително проста и се състои от три стъпки:

Сваляме си някоя от версиите от сайта на Фосил. Има версии за Linux, MacOS, Open BSD и Windows.

Разархивираме архива - вътре има един файл "fossil.exe" или "fossil" в зависимост от операционната система.

Копираме този файл в директория която е спомената в променливата PATH на операционната система. Във Windows това може да е "C:Windows" или "C:Windowssystem32", а в Линукс примерно "/usr/local/bin".

6. Работа с Фосил.

6.1. Стартиране на Фосил.

Фосил е конзолна програма и като такава се стартира от конзолата. Във Windows това е cmd.exe, а в Linux има много варианти. При всички случаи можете да намерите конзола някъде в "Старт" менюто на операционната система. И въобще, ако не можете да стартирате конзолата, следва да се замислите дали програмирането е подходящо занимание за вас. :P

В повечето случаи, при стартирането на Фосил трябва да се намираме в директорията в която е работното копие на файловете, които искаме да управляваме.

6.2. Система за помощ.

По всяко време можем да покажем помощен текст за всяка от командите на Фосил:

fossil help или fossil help --all

Горните команди ще изведат списък съответно от най-важните или всичките команди на Фосил. Подробна помощ можем да поискаме:

fossil help КОМАНДА

Допълнителна информация за използването на системата можете да намерите на сайта на Фосил:

Главна страница

Fossil Quick Start

Fossil FAQ

How To Configure A Fossil Server

Fossil Versus Git

6.3. Създаване и отваряне на хранилище.

Има два начина да бъде създадено хранилище. Създаване на празно хранилище и клониране на вече съществуващо хранилище.

6.3.1. Създаване на празно хранилище:

fossil new ИМЕ_НА_ФАЙЛ

Командата има опции, но те не са много важни. Ако на някой му се наложи да ги използва, значи е достатъчно напреднал, за да си намери сам информация за тях.

Реален пример. Втората команда ще отвори браузъра и ще ви покаже какво точно сте създали:

fossil new MyFirstRepo.fossil fossil ui MyFirstRepo.fossil

6.3.2. Клониране на хранилище:

fossil clone URL ИМЕ_НА_ФАИЛ

За да клонирате някакво хранилище, ще ви е нужен адреса на хранилището. Това е всъщност URL-то на сайта на хранилището. Аз ще използвам като пример едно от моите хранилища. Втората команда е отново за да видите какъв е резултата.

fossil clone http://chiselapp.com/user/johnfound/repository/FreshIDE/index FreshIDE.fossil fossil ui FreshIDE.fossil

6.4. Настройка на прокси

Ако връзката ви с web минава през прокси сървър, ще трябва да кажете на fossil какъв е адреса на проксито. Това става с командата:

fossil settings proxy http://ПРОКСИ_АДРЕС_ИЛИ_IP:ПОРТ

6.5. Отваряне на хранилище

За да може да се работи с хранилище, то трябва да се отвори. Това става с командата:

fossil open ИМЕ_НА_ФАЙЛ ?ВЕРСИЯ? ?ОПЦИИ?

Тази команда отваря хранилището и създава работно копие на някоя от версиите. Ако не е зададена версия се създава работно копие на разклонението trunk. Ако не желаем да създаваме работно копие, трябва да зададем опцията --keep.

Ако за име на версия се зададе име на бранч, то работното копие ще съответства на най-новата версия от дадения бранч.

За име на версия може да се зададе и номер на версия, което във Фосил представлява дълъг низ от шестнайсетични цифри - SHA-1 на дадената версия - например: 42e2c3e35f4925416dd4f747decc142738646206. За щастие не е нужно да задаваме цялото число, а само първите няколко цифри, достатъчен брой за да може Фосил да разбере коя версия имаме предвид.

За версия може да се зададе и етикет (tag) присвоен на версията от потребителя. Примерно v2.0.8 в горното хранилище уникално характерезира версия 2.0.8 на Fresh IDE в момента на излизането и.

Всички тези идентификатори на версии могат да се видят от графичният интерфейс на хранилището: fossil ui.

Обикновенно отвореното хранилище не се затваря или се затваря много рядко - примерно за да може да се направи директен бакъп на файла на хранилището.

Едно и също хранилище може да се отвори от различни директории, така че да може едновременно да се работи по няколко работни копия. Удобно е всички хранилища да се събират в една и съща папка, а за работните копия да се създават отделни папки.

Конкретен пример с по-рано клонираното хранилище FreshIDE.fossil и отварянето на няколко работни копия. Приемаме, че се намираме в папката където се намира хранилището.

md FreshLibDev cd FreshLibDev fossil open ..\FreshIDE.fossil FreshLibDev cd .. md trunk cd trunk fossil open ..\FreshIDE.fossil cd .. md uConfig cd uConfig fossil open ..\FreshIDE.fossil uConfig

Тези команди ще създадат три отделни работни копия, съответно за бранчовете FreshLibDev, trunk и uConfig.

6.6. Работно копие при отворено хранилище.

Ако искаме при вече отворено хранилище да създадем работно копие на друга версия можем да го направим с командата:

fossil checkout ?ВЕРСИЯ?

Всички файлове от текущият чекаут ще бъдат изтрити, а на тяхно място ще бъдат създадени файловете от зададената версия. Ако обаче в текущото работно копие има незаписани промени, Фосил ще пита дали искаме да продължим с тази команда.

6.7. Добавяне на файлове.

Ако искаме Фосил да следи и управлява даден файл, трябва да му го кажем. Това става с командата add:

fossil add ?ОПЦИИ? ИМЕ_НА_ФАЙЛ ?ИМЕ_НА_ФАЙЛ? ....

Може да се използва * или ? за задаване на група от файлове. При такова задаване, под-директориите в работната директория се претърсват рекурсивно и всички файлове се добавят към списъка със управлявани файлове. Следващата команда ще добави към Фосил всички файлове с разширение asm:

fossil add *.asm

Списък с всички файлове управлявани от Фосил можем да видим с:

fossil ls

Списък на всички файлове, които не се следят от Фосил можем да видим с:

fossil extra

6.8. Прекратяване управлението на файлове.

Това става с командата:

fossil delete ИМЕ_НА_ФАЙЛ ?ИМЕ_НА_ФАЙЛ? ....

Тази команда не изтрива файла от диска, а казва на Фосил, че не трябва да го управлява повече.

6.9. Запис на версия.

След като разполагаме с работно копие на файловете, можем да си работим по проекта както винаги. По време на работата можем да проверяваме кои файлове са били променени от последната версия с командата:

fossil changes

Можем да проверим и какво точно е променено със командата diff:

fossil diff

Когато промените станат достатъчни за нова версия (което трябва да прецени потребителя) се записва нова версия:

fossil commit ?ОПЦИИ?

При тази команда, Фосил ще се опита да отвори текстовия редактор по подразбиране или ако не е зададен такъв ще използва прост редактор в конзолата за да въведем коментар за дадената версия: какво точно е променено и защо.

Този коментар може да се зададе директно в командата с опцията --comment ТЕКСТ_НА_КОМЕНТАРА.

Новата версия може да се запише като ново разклонение с опцията --branch ИМЕ_НА_БРАНЧА.

Докато записва новата версия, Фосил ще се опита да се синхронизира с хранилището от където е клонирано текущото хранилище. Ако това е невъзможно ще пита дали да направи записа или не.

6.10. Отказ от промените.

Понякога се случва, че някакви промени са направени погрешно. Или даден файл сме го замазали без да искаме. В този случай, промененият файл може да се възстанови от хранилището с командата:

fossil revert ?-r ВЕРСИЯ? ?ИМЕ_НА_ФАЙЛ?

Ако не е зададена версия се използва текущата. Ако не е зададено име на файл се възстановяват всички файлове от работното копие.

6.11. Синхронизиране с друго хранилище.

Това се налага не само, когато няколко човека работят по един проект, но и когато един човек работи на няколко компютъра - примерно на работа, в къщи и на мобилен компютър.

Има няколко вида синхронизация:

Издърпване на промените ще издърпа от другото хранилище промените направени междувременно, но няма на изпрати промените, които са правени в локалното копие на хранилището:

fossil pull ?URL?

Обратно, за да изпратим промените от локалното хранилище към другото използваме командата push:

fossil push ?URL?

Най-често обаче се използва командата, която прави и двете операции едновременно:

fossil sync ?URL?

Ако за хранилището е необходима парола, то тя се включва в URL адреса на другото хранилище: http://ПОТРЕБИТЕЛ:ПАРОЛА@URL. Паролата не се съхранява в чист вид и по-късно няма да бъде показвана.

За да обновим текущото работно копие може да се използва командата:

fossil update

Тя ще направи sync и след това ако някой от файловете в текущото работно копие е променен ще се опита да направи сливане на промените. При това е възможно в редки случаи да се получи конфликт, ако някой е променял същите файлове, които и ние редактираме в момента и ако промените са такива, че Фосил не може да ги слее без проблеми. Тези редки случаи излизат обаче извън темата на настоящата статия.


Продължение: Част II

7. Улеснения

Както вече споменах, Фосил има много интуитивна система от команди - учудващо удобна за конзолна програма. Командите имат синоними - тоест една и съща команда може да се зададе с две и повече ключови думи. Допълнително, командите могат въобще да се съкращават до първите си няколко символа, стига да няма две команди с еднакво начало. Например fossil delete ФАЙЛ може да се напише и fossil del и fossil rm. Ако съкращението съответства на повече от една команда, Фосил ще изведе съобщение за грешка. Например fossil de ще даде като резултат: `

fossil: ambiguous command prefix: de fossil: could be any of: deconstruct delete descendants fossil: use "help" for more information

Както вече споменахме, поради разпределения си характер, Фосил не може да номерира версиите с последователни номера. Вместо това, на всяка версия се присвоява уникален идентификатор, базиран на SHA-1 хеш алгоритъм. Този идентификатор представлява дълга поредица от шестнадесетични цифри, съвършено нечетлива за хора.

За някои от командите на Фосил, трябва да се задава номер на версия. Под номер на версия, във Фосил се разбира всичко, което може да идентифицира коя версия от хранилището имаме предвид. Могат да се използват имена на етикети присвоени от потребителите, имена на бранчове или споменатата хеш стойност.

Ако се зададе идентификатор, който сочи към няколко версии (примерно името на бранча винаги сочи към всички версии от този бранч) то се използва най-новата версия, която притежава този идентификатор.

Ако искаме да обработим някоя от предишните версии и тя няма специален етикет, трябва да зададем като идентификатор споменатият хеш. В този случай могат да се зададат само първите няколко цифри - стига да не се повтарят в друга версия, Фосил ще определи правилно какво имаме предвид. Например, ако имаме версията с идентификатор: de78a4148caec862d68f3438111805bf7ccb4eaf (това е реална версия от бранча trunk на клонираното по-горе хранилище), можем да направим работно копие с командата: fossil checkout de78 (или fossil co de78).

Поради голямата неустойчивост на SHA-1 функцията (т.нар. лавинен ефект) идентификаторите са силно различни и 4..5 символа сигурно идентифицират конкретна версия.

8. Създаване на бранчове

Както вече споменахме, работата в различни бранчове при разпределените системи за контрол на версиите е нещо обичайно. Примерно иска ми се на реализирам някаква нова функция в програмата, която пиша. Ако тази функция не е тривиална, тя ще изисква някакъв брой версии, докато тръгне както трябва. Разбира се, това може да се направи и директно в главния бранч, но по-правилно би било, ако работим в отделен бранч. Такъв може да се създаде по два начина:

fossil branch new ИМЕ_НА_БРАНЧА БАЗА_ЗА_РАЗКЛ ?--bgcolor ЦВЯТ_НА_ФОНА? ?--private?

Тази команда ще създаде в хранилището бранч с име "ИМЕ_НА_БРАНЧА", който ще съдържа всички файлове от базовата версия "БАЗА_ЗА_РАЗКЛ". Опцията "--bgcolor" ще зададе цвят на фона с който ще се извежда този бранч, когато се показва в графичният интерфейс на системата ( fossil ui ). Опцията "--private" ще създаде "частен" бранч, който няма да се изпраща към централното хранилище при синхронизация.

След създаването на бранч по този начин, трябва да си направим и работно копие със fossil checkout ИМЕ_НА_БРАНЧА за да можем да работим в него.

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

fossil commit --branch ИМЕ_НА_БРАНЧА

В този случай, разбира се няма нужда да правим ново работно копие, защото имаме текущото в което и продължаваме да си работим, но със сменен бранч.

9. Сливане на бранчове

Когато нужните изменения са направени и тествани, то те трябва да се слеят със главния бранч на проекта. Това става с командата merge. Тя има синтаксис:

fossil merge ?ОПЦИИ? ИМЕ_НА_ВЕРСИЯ

Сливат се винаги текущото работно копие, със зададената версия. Тъй като сливането не винаги е лесна операция и конфликти са възможни, то резултата се създава в работното копие, което, ако всичко е наред (или след като го направим да е наред) се записва като нова версия.

Поради потенциалните проблеми, командата има опция "-n" (или "--nochange") която прави сливането на сухо, без да записва промените, но извежда всички конфликти и съобщения за промени. Ако всичко е наред можем да повторим командата без тази опция. Допълнително има и fossil undo ако нещо все пак се обърка.

10. Проверка на текущия статус

След известна работа по работното копие, обикновено искаме да разберем какво точно е променено и дали си струва да правим поредния комит.

Можем да поискаме от Фосил да изведе текущите промени по проекта. Това се прави с няколко команди:

fossil status ще изведе кратък доклад за състоянието на работното копие - коя е текущата версия, какъв коментар и е сложен, кои файлове са променени.

fossil changes ще изведе само списък на променените файлове.

fossil extra ще изведе файловете, които присъстват в директориите на работното копие, но не се следят от Фосил. (обикновено това са примерно компилирани бинарни и обектни файлове, но може да са файлове, които сме въвели в проекта, но сме забравили да добавим към хранилището с fossil add.

fossil diff извежда всички разлики на работното копие спрямо последната версия записана в хранилището.

Аз лично, преди комит правя следната процедура: fossil extra за да видя дали не съм създал нови файлове, които не съм вкарал в проекта. После fossil changes за да видя кои файлове са променени. След това fossil diff и fossil commit. При последната команда, докато пиша коментара си прелиствам разликите (които е извел fossil diff) за да мога точно да напиша какво е променено и защо.

11. Използване на графичният интерфейс.

На няколко пъти споменахме командата fossil ui, но самата тя е ключова и заслужава да се разгледа по-подробно.

Тази команда стартира Фосил в режим на уеб сървър, който обаче работи само на 127.0.0.1 (localhost), и стартира браузъра на системата на този адрес. В резултат, се зарежда графичният интерфейс на Фосил.

Графичният интерфейс представлява по същество уеб сайт на проекта, в който се съдържа огромно количество информация за хранилището. Възможностите на този интерфейс са тема за съвсем отделна (и не малка) статия. Затова само ще изброя какво можете да правите от него, а как - ще трябва да откриете сами. :)

Разглеждане на дървото с версиите (т.нар. timeline) където е показано развитието на проекта във времето. Пак от там можете да разгледате параметрите на всяка отделна версия, както и да я изтеглите под формата на ZIP или TAR архив.

Разглеждане на отделните файлове от проекта, както и разликите между различните версии. Фосил има два начина на представяне на разликите, които могат да се сменят интерактивно.

Можете да пишете статии във вграденото wiki, които да бъдат видими за посетителите на хранилището. Началната страница на хранилището също е wiki статия, която можете да напишете за пояснение на посетителите.

Можете да редактирате и четете докладите от потребителите (т.нар. ticket-и на бъг тракера.)

Можете да администрирате хранилището - редактиране на различните параметри, HTML шаблоните и дизайна на сайта (има няколко вградени дизайна, но можете да си направите и собствен), опциите на хранилището, да задавате правата на регистрираните потребители и др.под. Навсякъде където има параметри има и подробно описание какво представляват и за какво служат.

Същият графичен интерфейс е достъпен и дистанционно на отдалечено хостваните хранилища. Единствената разлика е, че за да се правят промени, потребителят трябва да има нужните права и трябва да се логне предварително.

И една последна подробност за логването - по подразбиране, Фосил не дава пълен достъп до хранилището. Когато браузва отдалечени хранилища, човек трябва да се логне поне като анонимен потребител. (На страничката за лог-ин има подробни обяснения). Това се прави, за да се спре достъпа на търсещите машини (от рода на google) до цялото съдържание на хранилището, което съдържа огромно количество връзки, които няма никакъв смисъл да се индексират. (разбира се, това поведение може да се промени от опциите на проекта).

12. Заключение

Тази статия разглежда само една страна на Фосил - управлението на версии. Останалите възможности са много, но всички те се използват много интуитивно и след известно време всеки ще навлезе по-дълбоко в тази чудесна програма.

Last modified on: 17.01.2013 11:16:07

Preview

Comments

:)John Found ( 03.03.2016 08:30:06 UTC ):

GigaByte

Твои колеги ползват Git за система на версиите. Ти желаеш fossil. ИМа ли как ти да ползваш fossil, те Git ?

Има. fossil export --git и fossil import git + набор от скриптове. Но никой няма да е щастлив от такава комбинация. ;)

:)GigaByte ( 03.03.2016 03:37:12 UTC ):

Исках да питам нещо. Имаш някакъв проект. Твои колеги ползват Git за система на версиите. Ти желаеш fossil. ИМа ли как ти да ползваш fossil, те Git ?

Title: Filename: