Системи контролю версій: Fossil, частина II

    Продовжуємо розмову про Fossil.
 
В першій частині ми познайомилися з використанням Fossil в режимі одного на одному робочому місці. Наступний крок — перенесення репозитория на інший комп'ютер — з роботи на домашній, або на ноутбук, який ми беремо з собою в поїздку. Найпростіший варіант — це просто скопіювати репозиторій, благо це всього один файл, на нове робоче місце. Можна так і зробити, але найпростіше рішення не завжди найкраще, є ймовірність, що виникнуть невеликі проблеми.
 
 Однокористувацький режим роботи на кількох робочих місцях.
Справа в тому, що в репозиторії зберігається не тільки історія версій, але і деяка службова інформація, зокрема, ім'я адміністратора та пароль. Ім'я адміністратора генерується автоматично при створенні репозитория, звичайно це ім'я користувача, під яким ви увійшли в ОС — і цілком може статися, що це ім'я на комп'ютері, куди ви копіюєте репозиторій, відрізняється від того, з яким репозиторій був створений. В цьому випадку commit не пройде, і вам доведеться додати необхідного користувача за допомогою fossil ui , або кожен раз додавати в fossil commit параметр --user. Більш «чистий» спосіб — це клонування існуючого репозитория командою fossil clone . Як і в першій частині статті, ми будемо виходити з припущення, що у нас стоїть Windows, що всі наші репозиторії зберігаються в окремому каталозі c: \ fossil, що ми працюємо над проектом Castle, вихідні коди якого і на іншому комп'ютері хочемо розмістити в c: \ projects \ castle \ source \. Крім того, припустимо, що переносимо репозиторій на флешці, змонтованої як диск F. Отже, клонуємо:
 
 
fossil clone f:\castle.fossil c:\fossil\castle.fossil

І відкриваємо для подальшого використання:
 
 
c:
cd \projects\castle
fossil open c:\fossil\castle.fossil
При цьому файли, включені в репозиторій, розпакуються в поточний каталог.
 
Перш ніж йти далі, нам треба розібратися з параметром autosync . Якщо він включений (& quot; on & quot ;, або 1), то при виконанні команди fossil update буде зроблена спроба отримати спочатку оновлення з віддаленого репозиторію (pull ), а при виконанні fossil commit — спочатку pull і update , а відразу після commit push (передача змін в віддалений репозиторій), причому адресою віддаленого репозиторію буде вказаний в останньої виконаної команді clone , push , pull , sync , remote-url . В нашому випадку це буде f: \ castle.fossil, тобто, при кожному commit Fossil буде спочатку намагатися зв'язатися з файлом на флешці, і, якщо вона не вставлена, то commit не буде виконано — навряд чи це те, що ми хочемо. Включений autosync гарний у випадку, якщо наш віддалений репозиторій розташований на сервері в локальній мережі, тобто практично завжди доступний. У разі ж, коли віддаленим репозиторием фактично є файл на флешці, за допомогою якої ми переносимо напрацьовані зміни з одного місця на інше, це може бути не дуже зручно. Тому, перш ніж почати роботу з репозиторием, відключимо autosync :
 
 
fossil settings autosync off

Тепер можна продовжити роботу над проектом на новому робочому місці, в міру необхідності зберігаючи зміни в локальному репозиторії за допомогою commit . Для передачі змін на інші робочі місця використовуємо push (передача змін з локального в віддалений репозиторій), pull (одержання змін з віддаленого в локальний репозиторій). Можна використовувати sync — ця команда робить pull і push . Таким чином, наш робочий процес (workflow) приблизно такий:
 
Переписали оновлення з флешки:
fossil pull f:\castle.fossil
fossil update
Команда update модифікує робочі файли відповідно до вмісту локального репозиторія. При цьому зміни, які ми зробили в робочих файлах після останнього commit (взагалі-то, при режимі одного так робити не треба!), Не пропадуть — Fossil постарається здійснити злиття (merge).
Попрацювали над проектом, зберегли зміни (commit ) в локальний репозиторій і відправили їх на віддалений:
fossil push f:\castle.fossil
Приходимо на інше робоче місце — і знову: pull , update , робота ..., commit , push .
 
Можна, в принципі, замість push просто фізично копіювати файл репозитория на флешку — в разі ось такого однокористувацького режиму роботи це допустимо, але використання push — більш «чистий» варіант. Чого безумовно не слід робити — так це фізично копіювати репозиторій на місце локального, коли цей локальний відкритий — в цьому випадку може відбутися неузгодженість локального репозиторія зі службовим, який був створений в результаті його відкриття, що може привести до втрати інформації про зміни і, відповідно, до неприємних накладок.
 
Зручніше, звичайно, не носити репозиторій на флешці або іншому переносному фізичному носії, а тримати його на сервері. Можна використовувати сторонній сервіс типу dropbox, а можна, при наявності такої можливості, розмістити репозиторій на сервері, доступному вам для адміністрування. Саме цей варіант ми і розглянемо далі, тим більше, що саме він нам знадобиться для організації мнопользовательской роботи (можна ще скористатися послугами сайтів, що надають можливості хостингу для Fossil — репозиторіїв, наприклад, http://chiselapp.com/ або Sourceforge , але я не буду зупинятися тут на цьому).
 
 Установка репозитория на сервері.
Власне, установка проводиться так само, як ми це робили з флешки — переписуємо наш локальний репозиторій на флешку або в доступне місце на сервері і робимо fossil clone . Питання в тому, як забезпечити доступ до цього новоствореному віддаленого репозиторию, який URL використовувати в командах Fossil.
Можливі три варіанти підключення до віддаленого репозиторию:
 
 
     
Найпростіший, коли репозиторій знаходиться в розшарений каталозі,
 Через ssh-з'єднання,
 Використовуючи http — сервер.
 
Перший варіант, дійсно, найпростіший, для його реалізації взагалі нічого не треба робити, окрім як клонувати репозиторій в потрібний каталог. Звернення до нього нічим не відрізняється від варіанту з флешкою, просто використовуйте шлях до того каталогу, як він змонтований на вашому комп'ютері. Але цей спосіб обмежує вас межами вашої локальної мережі. Є й інший недолік: оскільки в цьому випадку ми працюємо не в режимі клієнт-сервер, а як з даними на файловому сервері, при збої (відключення живлення вашого комп'ютера, наприклад, або щось зі зв'язком) в процесі запису в файл віддаленого репозиторію можуть бути проблеми.
 
Для використання ssh-з'єднання у вас повинен бути, відповідно, ssh-сервер і на цей сервер повинен бути скопійований виконуваний файл fossil. В цьому випадку URL репозитория в команді Fossil буде виглядати так:
 
 
ssh://[userid[:password]@]host[:port]/path/repo.fossil 
Якщо використовується абсолютний шлях, то перед path треба поставити ще один слеш. Якщо виконуваний файл fossil знаходиться в каталозі, невідомому системі (тобто, недоступному по SET PATH), то до URL слід додати? Fossil = path_to_fossil / fossil.
Припустимо, що ми розмістили наш репозиторій castle.fossil на Linux-сервері в / usr / local / fossil, а login на цьому сервері — alex. Тоді команда push , наприклад, може виглядати так (наш сервер — 192.168.0.2):
 
fossil push ssh://alex@192.168.0.2//usr/local/fossil/castle.fossil 
Ще раз зазначу, що в якості логіна в даному випадку використовується саме логін до сервера, а не ім'я користувача репозитория.
 
Тепер про третій варіант — використання http — сервера. Найпростіше — виконати на сервері команду fossil server — в результаті там буде запущений http — сервер, такий же, як і по вже знайомій нам команді fossil ui , відмінність тільки в тому, що тепер доступ до нього можливий не тільки з локального, а й з будь-якого іншого комп'ютера в мережі і що тепер при web — доступі нам доведеться залогінитися для отримання повного доступу до сховища. URL в цьому випадку буде виглядати так:
 
http://[userid[:password]@]host[:port]/path 

Нагадаю, що порт за замовчуванням — 8080, його можна змінити опцією --port команди fossil server .
Якщо на сервері вже піднято http — сервер, що підтримує CGI, можна використовувати виконуваний файл Fossil як CGI — програму (саме так, згідно документації, працює офіційний сайт Fossil). Для цього треба в CGI — каталог на сервері (зазвичай це cgi-bin) помістити ось такий простенький скрипт:
 
 
#!/usr/bin/fossil
repository: /usr/local/fossil/castle.fossil

Ми тут виходимо з припущення, що виконуваний файл fossil поміщений в / usr / bin. Не забудьте, звичайно, встановити потрібні права на файли репозитория, скрипта і відповідних каталогів. Якщо ми назвали файл скрипта castle, то URL може виглядати так:
 
 
http://[userid[:password]@]host/cgi-bin/castle
тут userid — ім'я користувача репозитория. І команда push набуде такого вигляду:
 
 
fossil push http://alex@192.168.0.2/cgi-bin/castle

Якщо http — сервер не підтримує CGI, можна налаштувати виклик Fossil через SCGI. Можна підняти http — сервіс, використовуючи inetd, xinetd або stunnel. Детальніше про це можна почитати в документації Fossil , тут я описую тільки те, що пробував своїми руками.
Варіант з використанням http, крім зручності використання з будь-якого комп'ютера, пов'язаного з сервером по локальній мережі або через Інтернет, хороший ще й тим, що забезпечує web — сервіс, ми отримуємо, по суті, web — сервер проекту. Безумовно, перше, що треба буде зробити, це налаштувати права доступу — зокрема, для anonymous — всіх тих, хто не зареєстрований як користувач в репозиторії.
 
Якщо ми продовжуємо користуватися репозиторием монопольно, то workflow залишається тим же, що і при використанні флешки як носій для віддаленого репозиторію (змінюється тільки URL): pull , update , робота ..., commit , push . Хоча, якщо ми використовуємо в якості віддаленого репозиторію постійно підключений по одному і тому ж адресою ресурс, можна переглянути ставлення до параметру autosync і встановити його в & quot; on & quot ;. В цьому випадку робочий цикл скорочується до update , робота ..., commit pull і push будуть виконані автоматично. Не забудьте тільки перевірити, яку адресу віддаленого репозиторію використовуватиметься (зазвичай таким є останній використаний в командах clone , pull , push або sync ). Це можна зробити командою fossil remote-url . Цією ж командою можна встановити потрібний URL, передавши його в якості параметра: fossil remote-url URL .
 
І ще одне важливе зауваження, що стосується як однокористувацького, так і розрахованого на багато режимів. Слідкуйте за правильністю установки часу на комп'ютерах! При спробі зробити commit , коли поточна версія в локальному репозиторії має більш пізню дату / час, ніж встановлені зараз на комп'ютері, операція не сповниться і буде видано відповідне повідомлення. Якщо у вас на комп'ютері час правильне і вам треба все-таки зробити цей commit , виконайте його з параметром --allow-older . Але краще, звичайно, не доводити до такої ситуації.
 
 багато режим роботи.
Віддалений репозиторій на сервері у нас вже встановлений. Створюємо клонуванням з віддаленого локальний репозиторій (який використовувати URL ми розбирали в попередньому розділі), додаємо цього користувача на віддаленому, прописуємо його права і — вперед. Робочий цикл приблизно такий же, як і в режимі одного, тільки тепер pull і update необхідно робити і перед кожним commit (це якщо autosync відключений, якщо включений — це робиться автоматично), оскільки за час, що минув з попереднього pull віддалений репозиторій міг бути змінений іншим користувачем.
 
Тут може виникнути нова, раніше не зустрічалися нам ситуація. Ви оновили свої робочі файли (pull , update ) і почали їх редагувати. Тим часом ваш колега теж щось відредагував і відправив на сервер (commit , push ). Ви закінчили свою роботу і хочете відправити зміни на сервер. Тут можливі такі варіанти:
 
1) Autosync включений або він вимкнений, але ви робите pull , update перед commit , як і належить. Update спробує виконати злиття (merge) і якщо воно пройде нормально, то… все нормально. Якщо ж злиття виробити не вдасться (наприклад, зміни були в одній і тій же рядку одного і того ж файлу), то update видасть відповідне повідомлення, у вас з'являться по 3 нових файлу на кожен «несли» з розширеннями, що закінчуються на -baseline, -merge і -original, а в «несли» файлах з'являться в кожному спірному місці нові рядки, починаючи з & quot; & lt; & lt; & lt; & lt; & lt; & lt; & lt; BEGIN MERGE CONFLICT:… & quot; і закінчуючи & quot; & gt; & gt; & gt; & gt; & gt; & gt; & gt; END MERGE CONFLICT… & quot ;, там буде і попередня версія (COMMON ANCESTOR content), і ваша версія (local copy content), і версія вашого колеги (MERGED IN content). Вам доведеться зробити необхідні зміни самостійно, відредагувавши файл, ну і потім зробити commit .
 
2) Autosync вимкнений і ви забули зробити pull , update перед commit . Все пройде без додаткових повідомлень, без ексцесів, але при цьому в результаті commit в репозиторії буде створений fork (вилка) — по суті, нова гілка проекту. Як сказано в документації, в Fossil fork — це небажаний, ненавмисний branch . Погано те, що ні ви, ні ваш колега можете це навіть не помітити, якщо не заглянете в Timeline — там роздвоєння відразу кинеться в очі. Щоб виправити становище, що склалося вам треба об'єднати утворилися гілки командою fossil merge . Якщо злиття не вдасться, то, як і в попередньому випадку, його треба буде провести самостійно і зробити commit .
Ця друга ситуація може виникнути не тільки в результаті забудькуватості, але і якщо ви якийсь час працюєте offline і змушені зберігати зміни в локальний репозиторій commit , чи не синхронізуючи його з сервером. В такому випадку майте на увазі, що у вас може вийти fork і перевіряйте Timeline після відправки змін на сервер. І ще: якщо Autosync у вас включений, але ви чомусь хочете отримати fork замість об'єднання ваших змін зі змінами інших розробників, ви можете запустити commit з параметром --allow-fork .
 
 Гілки (branches).
Я не буду тут говорити про те, навіщо потрібно розгалуження проекту, для чого і в яких випадках їм користуватися, просто розповім коротенько, як це реалізовано в Fossil. Припустимо, ми хочемо створити нову гілку ver_2_0:
 
 
fossil branch new ver_2_0 trunk
trunk — це та гілка, від якої ми виробляємо відгалуження, trunk — це назва головного «ствола» будь-якого проекту. Якщо ми тепер виконаємо команду fossil branch list , то побачимо, що у нас тепер 2 гілки — trunk і ver_2_0, причому знаком & quot; * & quot; позначена гілка trunk — це значить, що саме вона — поточна. Створення нової гілки не змінює статус робочих файлів — ми все ще в старій гілці trunk, це можна перевірити і командою fossil status . Щоб перейти в нову гілку, виконуємо
 
 
fossil checkout ver_2_0
або fossil co ver_2_0 , це одне і те ж. Команда checkout замінює робочі файли на ті, що знаходяться в локальному репозиторії ну і встановлює вказану гілку (якщо вона вказана), як поточну. Тепер всі наші подальші зміни будуть ставитися до гілки ver_2_0. Якщо нам знадобиться провести в гілці trunk ті зміни, які ми напрацювали в ver_2_0, переходимо в trunk і виробляємо об'єднання:
 
 
fossil co trunk
fossil merge ver_2_0

При об'єднанні можуть виникнути конфлікти — як з ними розбиратися я розповідав вище.
 
Існують ще так звані особисті гілки, вони залишаються в локальному репозиторії і не передаються на сервер, такі гілки утворюються, якщо до команди branch додати параметр --private .
 
 Висновок.
Ну от, начебто і все, що я планував розповісти. Звичайно, тут були висвітлені не всі питання, не всі команди і не всі параметри (думаю, навіть менша частина) тих команд, про які йшла мова. Але на це є документація. Є ще цікава тема, про яку варто було згадати — це можливість створення своїх скриптів на вбудованому Tcl — подібному мовою TH, але я і сам з цим ще не розбирався.
 
Наостанок хотілося б відповісти на питання, який найчастіше задавали в коментарях до першої частини статті: чим Fossil краще Git або Mercurial.
Я нікого не намагаюся вмовити перейти на Fossil з іншого VCS, більш того, я вважаю непродуктивним заняттям міняти VCS, якою ви користуєтеся, на іншу, якщо вас все в ній влаштовує і немає серйозних причин для міграції. Система контролю версій — всього лише інструмент і він не повинен бути на першому плані у вашій роботі. Інша справа, якщо ви тільки підбираєте VCS для себе — в цьому випадку варто розглянути Fossil як цілком гідний варіант, який забезпечує всі необхідні можливості.
А краще чи гірше? Це, багато в чому, питання особистих переваг. Мені подобається мінімалізм Fossil. Подобається, що для установки що клієнта, що сервера треба просто скопіювати один файл, що немає потреби піднімати окрему службу для сервера, що я можу носити на флешці два невеликих виконуваних файлу (для Windows і для Linux) і кілька файлів — репозиторіїв — і цього достатньо, щоб використовувати його в будь-якому місці. Мені здається зручним його web — інтерфейс і видається важливим, що його можна використовувати і локально. Мені подобається, що bug-tracking і wiki вбудовані в систему, їхні дані зберігаються в тому ж репозиторії і тісно інтегровані з рештою вмістом репозитория, що з ними можна працювати offline, що не треба використовувати послуги сторонніх web — сервісів і турбуватися про свої дані в разі закриття цих сервісів або зміни їхньої політики. Напевно є люди, яким це теж сподобається.

Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.