Сістэма кіравання версіямі

**Сістэма кіравання версіямі** (ад  ці ) — праграмнае забеспячэнне для палягчэння работы са зменлівай інфармацыяй. Сістэма кіравання версіямі дазваляе захоўваць некалькі версій аднаго і таго ж дакумента, пры неабходнасці вяртацца да больш ранніх версій, вызначаць, хто і калі зрабіў тую ці іншую змену, і шмат іншага.

Такія сістэмы найбольш шырока ўжываюцца пры распрацоўцы праграмнага забеспячэння для захоўвання зыходных кодаў праграмы, якая распрацоўваецца. Аднак яны могуць з поспехам выкарыстоўвацца і ў іншых праектах, дзе вядзецца работа з вялікай колькасцю няспынна зменлівых электронных дакументаў. У прыватнасці, сістэмы кіравання версіямі выкарыстоўваюцца ў САПР, звычайна ў складзе сістэм кіравання данымі аб вырабах (PDM). Кіраванне версіямі ўжываецца ў інструментах канфігурацыйнага кіравання (*Software Configuration Management Tools*).

Праграмнае забеспячэнне Вікіпедыі захоўвае гісторыю змен для ўсіх яе артыкулаў, ужываючы метады, аналагічныя тым, якімі карыстаюцца ў сістэмах кіравання версіямі.

## Агульныя звесткі 
Сітуацыя, у якой электронны дакумент за час свайго існавання зведвае шэраг змен, з'яўляецца даволі тыповай. Пры гэтым часта бывае важна мець не толькі апошнюю версію, але і некалькі папярэдніх. У найпрасцейшым выпадку можна проста захоўваць некалькі варыянтаў дакумента, нумаруючы іх адпаведным чынам. Такі спосаб неэфектыўны (даводзіцца захоўваць некалькі амаль ідэнтычных копій), патрабуе больш увагі і дысцыпліны і часта вядзе да памылак, таму былі распрацаваны сродкі для аўтаматызацыі гэтай работы.

Традыцыйныя сістэмы кіравання версіямі ўжываюць цэнтралізаваную мадэль, калі маецца адзінае сховішча дакументаў, якое кіруецца спецыяльным серверам, які і выконвае большую частку функцый кіравання версіямі. Карыстальнік, які працуе з дакументамі, павінен спачатку атрымаць патрэбную яму версію дакумента са сховішча; звычайна ствараецца лакальная копія дакумента, т. зв. «рабочая копія». Можа быць атрымана апошняя версія ці любая з папярэдніх, якая можа быць абрана па нумару версіі ці даце стварэння, альбо па іншых прызнаках. Пасля таго, як у дакумент унесены патрэбныя змены, новая версія змяшчаецца ў сховішча. У адрозненне ад простага захоўвання файла, папярэдняя версія не знішчаецца, а таксама застаецца ў сховішчы і можа быць атрымана адтуль у любы час. Сервер можа ўжываць т. зв. дэльта-кампрэсію — гэта такі спосаб захоўвання дакументаў, пры якім захоўваюцца толькі змены паміж паслядоўнымі версіямі, што дазваляе паменшыць аб'ём даных у сховішчы. Улічваючы, што звычайна найбольш запатрабаванай з'яўляецца апошняя версія файла, сістэма можа пры захоўванні новай версіі захоўваць яе цалкам, замяняючы ў сховішчы апошнюю раней захаваную версію на розніцу паміж гэтай і свежай версіяй. Некаторыя сістэмы (напрыклад, ClearCase) падтрымліваюць захоўванне версій абодвух відаў: большасць версій захоўваецца ў выглядзе дэльта, але перыядычна (па спецыяльнай камандзе адміністратара) выконваецца захоўванне версій усіх файлаў у поўным выглядзе; такі падыход забяспечвае максімальна поўнае аднаўленне гісторыі ў выпадку пашкоджання рэпазіторыя.

Часам стварэнне новай версіі выконваецца незаўважна для карыстальніка (празрыста), альбо прыкладной праграмай, якая мае ўбудаваную падтрымку такой функцыі, альбо за кошт ужывання спецыяльнай файлавай сістэмы. У гэтым выпадку карыстальнік проста працуе з файлам, як звычайна, і падчас захоўвання файла аўтаматычна ствараецца новая версія.

Звычайнай з'яўляецца сітуацыя, калі над адным праектам працуюць адначасова некалькі чалавек. Калі два чалавекі змяняюць адзін і той жа файл, то адзін з іх можа выпадкова адмяніць змены, зробленыя другім. Сістэмы кіравання версіямі адсочваюць такія канфлікты і прапаноўваюць сродкі іх вырашэння. Большасць сістэм можа аўтаматычна аб'ядноўваць (зліваць) змены, зробленыя рознымі распрацоўшчыкамі. Аднак такое аўтаматычнае аб'яднанне змен звычайна магчыма толькі для тэкставых файлаў і пры ўмове, што змяняліся розныя часткі (якія не перасякаюцца) гэтага файла. Такое абмежаванне звязана з тым, што большасць сістэм кіравання версіямі арыентавана на падтрымку працэсу распрацоўкі праграмнага забеспячэння, а зыходныя коды праграм захоўваюцца ў тэкставых файлах. Калі аўтаматычнае аб'яднанне выканаць не ўдалося, сістэма можа прапанаваць вырашыць праблему ўручную.

Часта выканаць зліццё немагчыма ні ў аўтаматычным, ні ў ручным рэжыме, напрыклад, калі фармат файла невядомы ці занадта складаны. Некаторыя сістэмы кіравання версіямі даюць магчымасць заблакіраваць файл у сховішчы. Блакіроўка не дазваляе іншым карыстальнікам атрымаць рабочую копію або забараняе змены рабочай копіі файла (напрыклад, сродкамі файлавай сістэмы) і забяспечвае такім чынам выключны доступ толькі таму карыстальніку, які працуе з дакументам.

Многія сістэмы кіравання версіямі даюць шэраг іншых магчымасцей:
* Дазваляюць ствараць розныя варыянты аднаго дакумента, г. зн. *галіны*, з агульнай гісторыяй змен да пункта разгалінавання і з рознымі — пасля яе.
* Даюць магчымасць даведацца, хто і калі дадаў або змяніў пэўны набор радкоў у файле.
* Вядуць журнал змен, у якім карыстальнікі могуць запісваць тлумачэнні аб тым, што і чаму яны змянілі ў дадзенай версіі.
* Кантралююць правы доступу карыстальнікаў, дазваляючы ці забараняючы чытанне ці змены даных, у залежнасці ад таго, хто запытвае гэтае дзеянне.

## Тыповы парадак работы з сістэмай 
Кожная сістэма кіравання версіямі мае свае спецыфічныя асаблівасці ў наборы каманд, парадку работы карыстальнікаў і адміністраванні. Між тым, агульны парадак работы для большасці VCS цалкам стэрэатыпны. Дапусцім, што праект, якім бы ён ні быў, ужо існуе і на серверы размешчаны яго рэпазіторый, да якога распрацоўшчык атрымлівае доступ.

### Пачатак работы з праектам 
Першым дзеяннем, якое павінен выканаць распрацоўшчык, з'яўляецца атрыманне рабочай копіі праекта ці той яго часткі, з якой належыць працаваць. Гэтае дзеянне выконваюць з дапамогай стандартнай каманды атрымання версіі (**checkout** або **clone**) альбо спецыяльнай каманды, якая фактычна выконвае тое ж самае дзеянне. Распрацоўшчык задае версію, якая павінна быць скапіравана, звычайна капіруецца апошняя (або абраная адміністратарам у якасці асноўнай) версія.

Па камандзе атрымання ўсталёўваецца злучэнне з серверам і праект (ці яго частка — адзін з каталогаў з падкаталогамі) у выглядзе дрэва каталогаў і файлаў капіруецца на камп'ютар распрацоўшчыка. Звычайнай практыкай з'яўляецца дубліраванне рабочай копіі: апроч асноўнага каталога з праектам на лакальны дыск (альбо ў асобны, спецыяльна абраны каталог, альбо ў сістэмныя падкаталогі асноўнага дрэва праекта) дадаткова запісваецца яшчэ адна яго копія. Працуючы з праектам, распрацоўшчык змяняе толькі файлы асноўнай рабочай копіі. Другая лакальная копія захоўваецца ў якасці эталона, дазваляючы ў любы момант без звяртання да сервера вызначыць, якія змены былі ўнесены ў пэўны файл або праект у цэлым і ад якой версіі была «адгалінавана» рабочая копія; як правіла, любая спроба ручной змены гэтай копіі вядзе да памылак у рабоце праграмнага забеспячэння VCS.

### Штодзённы цыкл работы 
Пры некаторых варыяцыях, вызначаных асаблівасцямі сістэмы і дэталямі прынятага бізнес-працэсу, звычайны цыкл работы распрацоўшчыка на працягу дня выглядае наступным чынам.

; Абнаўленне рабочай копіі: Па меры ўнясення змен у праект рабочая копія на камп'ютары распрацоўшчыка старэе, разыходжанне яе з асноўнай версіяй праекта павялічваецца. Гэта павышае рызыку ўзнікнення канфліктных змен (гл. ніжэй). Таму зручна падтрымліваць рабочую копію ў стане, максімальна блізкім да бягучай асноўнай версіі, дзеля чаго распрацоўшчык выконвае аперацыю абнаўлення рабочай копіі (**update**) наколькі магчыма часта (рэальная частата абнаўленняў вызначаецца частатой унясення змен, якая залежыць ад актыўнасці распрацоўкі і колькасці распрацоўшчыкаў, а таксама ад часу, які затрачваецца на кожнае абнаўленне — калі ён вялікі, распрацоўшчык вымушаны абмяжоўваць частату абнаўленняў, каб не марнаваць час).
; Мадыфікацыя праекта: Распрацоўшчык мадыфікуе праект, змяняючы яго файлы ў рабочай копіі ў адпаведнасці з праектным заданнем. Гэтая работа выконваецца лакальна і не патрабуе звяртання да сервера VCS.
; Фіксацыя змен: Скончыўшы чарговы этап работы над заданнем, распрацоўшчык фіксуе (**commit**) свае змены, перадаючы іх на сервер (ці ў асноўную галіну, калі работа над заданнем поўнасцю скончана, альбо ў асобную галіну распрацоўкі задання). VCS можа патрабаваць ад распрацоўшчыка перад фіксацыяй абавязкова выканаць абнаўленне рабочай копіі. Пры наяўнасці ў сістэме падтрымкі адкладзеных змен (**shelving**), змены могуць быць перададзены на сервер без фіксацыі. Калі зацверджаная палітыка работы VCS гэта дазваляе, фіксацыя змен можа праводзіцца не штодзённа, а толькі па завяршэнні работы над заданнем; у гэтым выпадку да завяршэння работы ўсе звязаныя з заданнем змены захоўваюцца толькі ў лакальнай рабочай копіі распрацоўшчыка.

### Галінаванні 
Рабіць дробныя выпраўленні ў праекце можна шляхам непасрэднай праўкі рабочай копіі з паслядоўнай фіксацыяй змен прама ў галоўнай галіне (ствале) на серверы. Аднак пры выкананні колькі-небудзь значных па аб'ёме работ такі парадак становіцца нязручным: адсутнасць фіксацыі прамежкавых змен на серверы не дазваляе працаваць над чым-небудзь у групавым рэжыме, акрамя таго, павышаецца рызыка страты змен пры лакальных аварыях і губляецца магчымасць аналізу і вяртання да папярэдніх варыянтаў кода ў межах дадзенай работы. Таму для такіх змен звычайнай практыкай з'яўляецца стварэнне галіны (**branch**), распрацоўка ў якой вядзецца паралельна са зменамі ў асноўнай версіі. Галіна ствараецца спецыяльнай камандай. Рабочая копія галіны можа быць створана нанова звычайным чынам (камандай атрымання рабочай копіі, з указаннем адраса ці ідэнтыфікатара галіны), альбо шляхам пераключэння наяўнай рабочай копіі на заданую галіну.

Базавы рабочы цыкл пры выкарыстанні галін застаецца такім жа, як і ў агульным выпадку: распрацоўшчык перыядычна абнаўляе рабочую копію (калі з галінай працуе больш чым адзін чалавек) і фіксуе ў ёй сваю штодзённую працу. Часам галіна распрацоўкі так і застаецца самастойнай (калі змена нараджае новы варыянт праекта, які далей развіваецца асобна ад асноўнага), але часцей за ўсё, калі работа, для якой створана галіна, выканана, галіна ўключаецца ў ствол (асноўную галіну). Гэта можа рабіцца камандай зліцця (звычайна **merge**), альбо шляхам стварэння патча (**patch**), які змяшчае ўнесеныя падчас распрацоўкі галіны змены, і выкарыстання гэтага патча ў бягучай асноўнай версіі праекта.

### Зліццё версій 
Тры віды аперацый, якія выконваюцца ў сістэме кіравання версіямі, могуць прыводзіць да неабходнасці аб'яднання змен. Гэта:

* Абнаўленне рабочай копіі (змены, якія зроблены ў асноўнай версіі, зліваюцца з лакальнымі).
* Фіксацыя змен (лакальныя змены зліваюцца са зменамі, якія ўжо зафіксаваны ў асноўнай версіі).
* Зліццё галін (змены, якія зроблены ў адной галіне распрацоўкі, зліваюцца са зменамі, якія зроблены ў іншай).

Ва ўсіх выпадках сітуацыя прынцыпова аднолькавая і мае наступныя характэрныя рысы:

# Раней была зроблена копія дрэва файлаў і каталогаў рэпазіторыя або яго часткі.
# У далейшым і ў арыгінальнае дрэва і ў копію былі незалежна ўнесены некаторыя змены.
# Патрабуецца аб'яднаць змены ў арыгінале і копіі такім чынам, каб не парушыць лагічную звязанасць праекта і не страціць даныя.

Цалкам відавочна, што пры невыкананні ўмовы (2) (гэта значыць калі змены былі ўнесены толькі ў арыгінал ці толькі ў копію) аб'яднанне элементарнае — дастаткова скапіраваць змененую частку туды, дзе змен не было. У адваротным выпадку зліццё змен ператвараецца ў нетрывіяльную задачу, у многіх выпадках патрабуе ўмяшання распрацоўшчыка. У цэлым механізм аўтаматычнага зліцця змен працуе, засноўваючыся на наступных прынцыпах:

* Змены могуць заключацца ў мадыфікацыі зместу файла, стварэнні новага файла або каталога, выдаленні ці перайменаванні файла або каталога, які існаваў раней у праекце.
* Калі дзве змены належаць да розных і не звязаным паміж сабой файлаў і/або каталогаў, яны заўсёды могуць быць аб'яднаны аўтаматычна. Іх з'яднанне палягае ў тым, што змены, якія зроблены ў кожнай версіі праекта, капіруюцца ў выніковую версію.
* Стварэнне, выдаленне і перайменаванне файлаў у каталогах праекта могуць быць аб'яднаны аўтаматычна, калі толькі яны не канфліктуюць паміж сабой. У гэтым выпадку змены, зробленыя ў кожнай версіі праекта, будуць скапіраваны ў выніковую версію. Канфліктнымі звычайна з'яўляюцца:
** Выдаленне і змяненне аднаго і таго ж файла або каталога.
** Выдаленне і перайменаванне аднаго і таго ж файла або каталога (у выпадку, калі сістэма падтрымлівае аперацыю перайменавання).
** Стварэнне ў розных версіях файла з адным і тым жа іменем і розным зместам.
* Змены ў межах аднаго тэкставага файла, зробленыя ў розных версіях, могуць быць аб'яднаны, калі яны знаходзяцца ў розных месцах гэтага файла і не перасякаюцца. У гэтым выпадку ў выніковую версію ўносяцца ўсе зробленыя змены.
* Змены ў межах аднаго файла, калі ён не з'яўляецца тэкставым, заўсёды з'яўляюцца канфліктнымі і не могуць быць аб'яднаны аўтаматычна.

Ва ўсіх выпадках базавай версіяй для зліцця з'яўляецца версія, ў якой было зроблена падзяленне зліваемых версій. Калі гэта аперацыя фіксацыі змен, то базавай версіяй будзе версія апошняга абнаўлення перад фіксацыяй, калі абнаўленне — то версія папярэдняга абнаўлення, калі зліянне галін — то версія, у якой была створана адпаведнай галіна. Адпаведна, супастаўнымі наборамі змен будуць наборы змен, зробленых ад базавай да бягучай версіі ва ўсіх аб'ядноўваемых варыянтах.

Абсалютная большасць сучасных сістэм кіравання версіямі арыентавана, у першую чаргу, на праекты распрацоўкі праграмнага забеспячэння, у якіх асноўным відам зместу файла з'яўляецца тэкст. Адпаведна, механізмы аўтаматычнага зліцця змен арыентуюцца на апрацоўку тэкставых файлаў, гэта значыць файлаў, якія змяшчаюць *тэкст*, які складаецца з *радкоў* літарна-лічбавых сімвалаў, прабелаў і табуляцый, падзеленых сімваламі пераводу радка.

Пры вызначэнні  дапушчальнасці зліцця змен у межах аднаго і таго ж тэкставага файла працуе тыповы механізм шторадковага параўнання тэкстаў (прыкладам яго рэалізацыі з'яўляецца сістэмная ўтыліта GNU diff), які параўноўвае аб'яднальныя версіі з базавай і стварае спіс змен, гэта значыць даданых, выдаленых і змененых набораў радкоў. Мінімальнай адзінкай даных для гэтага алгарытму з'яўляецца радок, нават самае дробнае адрозненне робіць радкі рознымі. З улікам таго, што сімвалы-падзяляльнікі, у большасці выпадкаў, не нясуць асэнсаванай нагрузкі, механізм зліцця можа ігнараваць гэтыя сімвалы пры параўнанні радкоў.

Тыя знойдзеныя наборы змененых радкоў, якія не перасякаюцца паміж сабой, лічацца сумеснымі і іх зліццё робіцца аўтаматычна. Калі ў файлах, якія зліваюцца, знаходзяцца змены, якія закранаюць адзін і той жа радок файла, гэта прыводзіць да канфлікту. Такія файлы могуць быць аб'яднаныя толькі ўручную. Любыя файлы, акрамя тэкставых, з пункту гледжання VCS з'яўляюцца бінарнымі і не дазваляюць аўтаматычнае зліццё.

### Канфлікты і іх вырашэнне 
Сітуацыя, калі пры зліцці некалькіх версій зробленыя ў іх змены перасякаюцца паміж сабой, завецца *канфліктам*. Пры канфлікце змен сістэма кіравання версіямі не можа аўтаматычна стварыць выніковы праект і вымушана звярнуцца да распрацоўшчыка. Як ужо абмяркоўвалася вышэй, канфлікты могуць узнікаць на этапах фіксацыі змен, абнаўлення ці зліцця галін. Ва ўсіх выпадках пры выяўленні канфлікту адпаведная аперацыя спыняецца да вырашэння. 

Для вырашэння канфлікту сістэма ў агульным выпадку прапануе распрацоўшчыку тры варыянты канфліктных файлаў: базавы, лакальны і серверны. Канфліктныя змены альбо паказваюцца распрацоўшчыку ў спецыяльным праграмным модулі аб'яднання змен (у гэтым выпадку там паказваюцца варыянты зліцця і дынамічна зменны ў залежнасці ад каманд карыстальніка аб'яднаны варыянт файла), альбо пазначаюцца спецыяльнай разметкай прама ў тэксце аб'яднанага файла (тады распрацоўшчык павінен сам сфарміраваць пажаданы тэкст у спрэчных месцах і захаваць яго). 

Канфлікты ў файлавай сістэме вырашаюцца прасцей: там можа канфліктаваць толькі выдаленне файла з адной з іншых аперацый, а парадак файлаў у каталогу не мае значэння, так што распрацоўшчыку застаецца толькі выбраць, якую аперацыю трэба захаваць ў выніковай версіі.

### Блакіроўкі 
Механізм блакіроўкі дазваляе аднаму з распрацоўшчыкаў захапіць у манапольнае карыстанне файл ці групу файлаў для ўнясення ў іх змен. На той час, пакуль файл заблакіраваны, ён застаецца даступным усім астатнім распрацоўшчыкам толькі для чытання, і любая спроба ўнесці ў яго змены адкідваецца серверам. Тэхнічна блакіроўка можа быць арганізавана па-рознаму. Тыповым для сучасных сістэм з'яўляецца наступны механізм.

* Файлы, для работы з якімі патрэбна блакіроўка, пазначаюцца спецыяльным флагам «блакіраваны». Такая пазнака можа ставіцца аўтаматычна падчас дадання файла ў праект, звычайна для гэтага папярэдне ствараецца спіс масак імён файлаў, якія пры даданні павінны станавіцца блакіраванымі.
* Калі файл пазначаны як блакіраваны, то падчас вымання рабочай копіі з сервера ён атрымлівае ў лакальнай файлавай сістэме атрыбут «толькі для чытання», што замінае яго выпадковаму рэдагаванню.
* Распрацоўчшык, які хоча змяніць блакіраваны файл, выклікае спецыяльную каманду блакіроўкі (**lock**) з указаннем імені гэтага файла. У выніку работы гэтай каманды адбываецца наступнае:
*# сервер правярае, ці не заблакіраваны ўжо файл іншым распрацоўшчыкам; калі гэта так, то каманда блакіравання завяршаецца з памылкай «файл заблакіраваны іншым карыстальнікам» і распрацоўшчык, які выклікаў яе, павінен чакаць, пакуль другі карыстальнік не зніме сваю блакіроўку;
*# файл на серверы пазначаецца як «блакіраваны», з захоўваннем ідэнтыфікатара распрацоўшчыка і часу блакіроўкі;
*# калі блакіроўка на серверы прайшла паспяхова, у лакальнай файлавай сістэме з файла рабочай копіі здымаецца атрыбут «толькі для чытання», што дазваляе пачаць яго рэдагаванне.
* распрацоўшчык працуе з заблакіраваным файлам. Калі падчас работы высвятляецца, што файл змяняць не трэба, ён можа выклікаць каманду зняцця блакіроўкі (**unlock, release lock**). Усе змены файла будуць адменены, лакальны файл вернецца ў стан «толькі для чытання», з файла на серверы будзе зняты атрыбут «заблакіраваны» і іншыя распрацоўшчыкі атрымаюць магчымасць змяняць гэты файл.
* Пры завяршэнні работы з блакіраваным файлам распрацоўшчык фіксуе змены. Звычайна блакіроўка пры гэтым знімаецца аўтаматычна, хоць у некаторых сістэмах блакіроўку патрабуецца здымаць уручную пасля фіксацыі, альбо ўказваць у камандзе фіксацыі змен адпаведны параметр. Так ці інакш, пры гэтым файл пасля змен страчвае флаг «заблакіраваны» і можа быць зменены іншымі распрацоўшчыкамі.

Масавае ужыванне блакіровак, калі ўсе ці большасць файлаў у праекце з'яўляюцца блакіраванымі і для любых змен неабходна заблакіраваць адпаведны набор файлаў, называецца стратэгіяй «блакіраванага вымання».  Раннія сістэмы кіравання версіямі падтрымлівалі выключна гэтую стратэгію, прадухіляючы такім чынам з'яўленне канфліктаў на корані. У сучасных VCS пераважным з'яўляецца ужыванне неблакіравальных выманняў, блакіроўкі ж лічацца хутчэй непазбежным злом, якое патрэбна па магчымасці абмяжоўваць. Недахопы ўжывання блакіровак відавочныя:

* Блакіроўкі проста замінаюць прадуктыўнай працы, бо вымушаюць чакаць вызвалення блакіраваных файлаў, хоць у большасці выпадкаў нават сумесныя змены адных і тых жа файлаў, якія робяцца падчас розных па сэнсу работ, не перасякаюцца і аб'ядноўваюцца пры зліцці аўтаматычна.
* Частата ўзнікнення канфліктаў і складанасць іх вырашэння ў большасці выпадкаў не настолькі вялікія, каб стварыць сур'ёзныя цяжкасці. Узнікненне ж сур'ёзнага канфлікту змен часцей усяго сігналізуе альбо аб існаванні разыходжанняў у меркаваннях розных распрацоўшчыкаў адносна дызайну аднаго і таго ж фрагмента, альбо аб няправільнай арганізацыі работы (калі два ці больш распрацоўшчыка робяць адно і тое ж).
* Блакіроўкі ствараюць адміністрацыйныя праблемы. Тыповы прыклад: распрацоўшчык можа забыцца зняць блакіроўку з занятых ім файлаў, сыходзячы на адпачынак. Дзеля вырашэння падобных праблем даводзіцца выкарыстоўваць адміністрацыйныя меры, у тым ліку ўключаць у сістэму тэхнічныя сродкі для зняцця непатрэбных блакіровак, але і пры іх наяўнасці на навядзенне парадку марнуецца час.

З другога боку, у некаторых выпадках выкарыстанне блакіровак цалкам апраўдана. Відавочным прыкладам з'яўляецца арганізацыя работы з бінарнымі файламі, для якіх няма інструментальных сродкаў зліцця змен альбо такое зліццё прынцыпова немагчыма (як, напрыклад, для файлаў выяў). Калі аўтаматычнае зліццё немагчыма, то пры звычайным парадку работы любая паралельная змена падобных файлаў будзе прыводзіць да канфлікту. У дадзеным выпадку зручней зрабіць такі файл блакіраваным, каб гарантаваць, што любыя змены ў яго будуць уносіцца толькі паслядоўна.

### Версіі праекта, тэгі 
Сістэма кіравання версіямі забяспечвае захоўванне ўсіх былых варыянтаў файлаў і, як вынік, усіх варыянтаў праекта ў цэлым, якія мелі месца з моманту пачатку яго распрацоўкі. Але само паняцце «версіі» ў розных сістэмах можа тлумачыцца двума рознымі спосабамі.

Адны сістэмы падтрымліваюць версійнасць *файлаў*. Гэта значыць, што любы файл, які існуе ў праекце, атрымлівае асабісты нумар версіі (звычайна — нумар 1, умоўнай «нулёвай» версіяй файла лічыцца пусты файл з тым жа імем). Пры кожнай фіксацыі змен распрацоўшчыкам, якія закранаюць файл, адпаведная частка фіксуемых змен прымяняецца да файла і ён атрымлівае новы, звычайна наступны па парадку, нумар версіі. Паколькі фіксацыі звычайна закранаюць толькі частку файлаў у рэпазіторыі, нумары версій файлаў, які існуюць на адзін і той жа момант часу, з цягам часу разыходзяцца, і праект у цэлым (гэта значыць увесь набор файлаў рэпазіторыя), фактычна, ніякага «нумара версіі» не мае, бо складаецца з мноства файлаў з рознымі нумарамі версій. Падобным чынам працуе, напрыклад, сістэма кіравання версіямі CVS.

Для іншых сістэм паняцце «версія» належыць не асобнаму файлу, а *рэпазіторыю* цалкам. Зноў створаны пусты рэпазіторый мае версію 1 ці 0, любая фіксацыя змен вядзе да павелічэння гэтага нумара (гэта значыць нават пры змяненні аднаго файла на адзін байт увесь рэпазіторый лічыцца змененым і атрымлівае новы нумар версіі). Такім чынам трактуе нумары версій сістэма Subversion. Нумара версіі асобнага файла тут фактычна не існуе, умоўна можна лічыць такім бягучы нумар версіі рэпазіторыя (калі лічыць, што пры кожнай змене, унесенай у рэпазітар, усе яго файлы мяняюць нумар версіі, нават тыя, якія не мяняліся). Часам, гаворачы аб «версіі файла» у такіх сістэмах, маюць на ўвазе тую версію рэпазіторый, у якой файл быў апошні раз (да патрэбнага моманту) зменены.

Для практычных мэтаў звычайна мае значэнне не асобны файл, а ўвесь праект цалкам. У сістэмах, якія падтрымліваюць версійнасць асобных файлаў, для ідэнтыфікацыі пэўнай версіі праекта можна ужываць дату і час — тады версія праекта будзе складацца з тых версій уваходзячых у яго файлаў, якія меліся ў рэпазітары на названы момант часу. Калі падтрымліваецца версійнасць рэпазітара ў цэлым, нумарам версіі праекта можа лічыцца нумар версіі рэпазітара. Аднак абодва варыянты не надта зручныя, таму што ні дата, ні нумар версіі рэпазітара звычайна не змяшчаюць інфармацыі аб значных зменах у праекце, аб тым, як доўга і інтэнсіўна над ім працавалі. Для больш зручнай паметкі версій праекта (ці яго частак) сістэмы кіравання версіямі падтрымліваюць паняцце **тэгаў**.

**Тэг (tag)** — гэта сімвалічная метка, якая можа быць звязана з пэўнай версіяй файла і/ці каталога ў рэпазітары. З дапамогай адпаведнай каманды ўсім ці частцы файлаў праекта, якія адпавядаюць пэўным умовам (напрыклад, уваходзяць у асноўную версію галоўнай галіны праекта на пэўны момант часу) можа быць прызначана зададзеная метка. Такім чынам можна ідэнтыфікаваць версію праекта (версія «XX.XXX.XXX» — гэта набор версій файлаў рэпазітара, якія маюць тэг «XX.XXX.XXX»), зафіксаваўшы такім чынам яго стан на некаторы пажаданы момант. Як правіла, сістэма тэгаў досыць гнуткая і дазваляе пазначыць адным тэгам і не адначасовыя версіі файлаў і каталогаў. Гэта дазваляе сабраць «версію праекта» любым адвольным чынам. З пункту гледжання карыстальніка сістэмы пазнака тэгамі можа выглядаць па-рознаму. У некаторых сістэмах яна выяўляецца менавіта як пазнака (тэг можна стварыць, ужыць да пэўных версій файлаў і каталогаў, зняць). У іншых сістэмах (напрыклад, Subversion) тэг уяўляе сабой наўпрост асобны каталог у файлавым дрэве рэпазітара, куды з ствала і галінаў праекта з дапамогай каманды капіявання робяцца копіі патрэбных версій файлаў. Візуальна тэг — гэта проста вынесеная ў асобны каталог копія пэўных версій файлаў рэпазітара. Па ўзгадненню ў дрэве каталогаў, якое адпавядае тэгу, забаронена фіксацыя змен (гэта значыць версія праекта, якая прадстаўляецца тэгам, з'яўляецца нязменнай).

### Базавыя прынцыпы распрацоўкі ПЗ у VCS 
Парадак ужывання сістэмы кіравання версіямі ў кожным пэўным выпадку вызначаецца тэхнічным рэгламентам і правіламі, прынятымі ў пэўнай фірме ці арганізацыі, дзе вядзецца распрацоўка праекта. Тым не менш, агульныя прынцыпы правільнага ўжывання VCS нешматлікія і адзіныя для любых распрацовак і сістэм кіравання версіямі.

# Любыя рабочыя, тэставыя ці дэманстрацыйныя версіі праекта будуюцца толькі з рэпазітара сістэмы. «Персанальныя» пабудовы, якія змяшчаюць пакуль незафіксаваныя змены, могуць рабіць толькі распрацоўшчыкі для мэтаў прамежкавага тэставання. Такім чынам гарантуецца, што рэпазітар змяшчае ўсё патрэбнае для стварэння рабочай версіі праекта.
# Бягучая версія галоўнай галіны заўсёды карэктная. Не дапушчальна фіксацыя ў галоўнай галіне няпоўных файлаў ці тых, якія не прайшлі хоць бы папярэдняе тэставанне змен. У любы момант пабудова праекта з бягучай версіі павінна быць паспяховай.
# Любая значная змена павінна афармляцца як асобная галіна. Прамежкавыя вынікі работы распрацоўшчыка фіксуюцца ў гэту галіну. Пасля завяршэння працы над зменай галіна аб'ядноўваецца з ствалом. Выключэнні дапускаюцца толькі для дробных змен, работа над якімі вядзецца адным распрацоўшчыкам на працягу не больш аднаго працоўнага дня.
# Версіі праекта пазначаюцца тэгамі. Вылучаная і пазначаная тэгам версія больш ніколі не змяняецца.

## Размеркаваныя сістэмы кіравання версіямі 
Таксама вядомы як , DVCS. Такія сістэмы ўжываюць размеркаваную мадэль замест традыцыйнай кліент-сервернай. Яны ў агульным выпадку не патрабуюць цэнтралізаванага сховішча: уся гісторыя змен дакументаў захоўваецца на кожным камп'ютары, у лакальным сховішчы, і пры патрэбе асобныя фрагменты гісторыі лакальнага сховішча сінхранізуюцца з аналагічным сховішчам на іншым камп'ютары. У некаторых такіх сістэмах лакальнае сховішча змяшчаецца непасрэдна ў каталогах рабочай копіі.

Калі карыстальнік такой сістэмы выконвае звычайныя дзеянні, такія як выманне пэўнай версіі дакумента, стварэнне новай версіі і таму падобнае, ён працуе са сваёй лакальнай копіяй сховішча. Па меры ўнясення змен, сховішчы, якія належаць розным распрацоўшчыкам, пачынаюць адрознівацца, і ўзнікае патрэба ў іх сінхранізацыі. Такая сінхранізацыя можа адбывацца з дапамогай абмену патчамі ці так званымі *наборамі змен* () паміж карыстальнікамі.

Апісаная мадэль лагічна блізкая да стварэння асобнай галіны для кожнага распрацоўшчыка ў класічнай сістэме кіравання версіямі (у некаторых размеркаваных сістэмах перад пачаткам работы з лакальным сховішчам патрэбна стварыць новую галіну). Адрозненне палягае ў тым, што да моманту сінхранізацыі іншыя распрацоўшчыкі гэтай галіны не бачаць. Пакуль распрацоўшчык змяняе толькі сваю галіну, яго праца не ўплывае на іншых удзельнікаў праекта і наадварот. Па сканчэнні адасобленай часткі працы, унесеныя ў галіны змены зліваюць з галоўнай (агульнай) галіной. Як пры зліцці галін, так і пры сінхранізацыі розных сховішчаў магчымы канфлікты версій. На гэты выпадак ва ўсіх сістэмах прадугледжаны тыя ці іншыя метады выяўлення і вырашэння канфліктаў зліцця.

З пункту гледжання карыстальніка размеркаваная сістэма адрозніваецца патрэбай ствараць лакальны рэпазітар і наяўнасцю ў каманднай мове дзвюх дадатковых каманд: каманды атрымання рэпазітара ад аддаленага камп'ютара (pull) і перадачы свайго рэпазітара на аддалены камп'ютар (push). Першая каманда выконвае зліццё змен аддаленага і лакальнага рэпазітара са змяшчэннем выніку ў лакальны рэпазітар; другая — наадварот, выконвае зліццё змен двух рэпазітараў са змяшчэннем выніку ў аддалены рэпазітар. Як правіла, каманды зліцця ў размеркаваных сістэмах дазваляюць абраць, якія наборы змен будуць перадавацца ў іншы рэпазітар ці вымацца з яго, выпраўляць канфлікты зліцця непасрэдна падчас аперацыі ці пасля яе няўдалага завяршэння, паўтараць ці ўзнаўляць няскончанае зліццё. Звычайна перадача сваіх змен у чужы рэпазітар (push) завяршаецца ўдала толькі пры ўмове адсутнасці канфліктаў. Калі канфлікты ўзнікаюць, карыстальнік павінен спачатку зліць версіі ў сваім рэпазітары (выканаць pull), і толькі потым перадаваць іх іншым.

Звычайна рэкамендуецца арганізаваць работу з сістэмай так, каб карыстальнікі заўсёды ці пераважна выконвалі зліццё ва ўласным рэпазітары. Гэта значыць, у адрозненні ад цэнтралізаваных сістэм, дзе карыстальнікі перадаюць свае змены на цэнтральны сервер, калі лічаць патрэбным, у размеркаваных сістэмах больш натуральным з'яўляецца парадак, калі зліццё версій распачынае той, каму патрэбна атрымаць яго вынік (напрыклад, распрацоўшчык, які кіруе будовым серверам).

Асноўная перавага размеркаваных сістэм — іх гнуткасць і значна большая (у параўнанні з цэнтралізаванымі сістэмамі) аўтаномія асобнага рабочага месца. Кожны камп'ютар распрацоўшчыка з'яўляецца фактычна самастойным і паўнавартасным серверам, з такіх камп'ютараў можна пабудаваць адвольную па структуры і ўзроўню складанасці сістэму, задаўшы (як тэхналагічна, так і адміністрацыйнымі мерамі) пажаданы парадак сінхранізацыі. Пры гэтым кожны распрацоўшчык можа весці работу незалежна, як яму зручна, змяняючы і захоўваючы прамежкавыя версіі дакументаў, карыстаючыся ўсімі магчымасцямі сістэмы (у тым ліку доступам да гісторыі змен) нават у адсутнасці сеткавага злучэння з серверам. Сувязь з серверам ці іншымі распрацоўшчыкамі патрабуецца выключна для выканання сінхранізацыі, пры гэтым абмен наборамі змен можа ажыццяўляцца па розных схемах.

Да недахопаў размеркаваных сістэм можна аднесці павелічэнне патрабаванага аб'ёму дыскавай памяці: на кожным камп'ютары даводзіцца трымаць поўную гісторыю версій, у той час як у цэнтралізаванай сістэме на камп'ютары распрацоўшчыка звычайна захоўваецца толькі рабочая копія, толькі зрэз рэпазітара на нейкі момант часу і ўнесеныя змены. Менш відавочным, але непрыемным недахопам з'яўляецца тое, што ў размеркаванай сістэме практычна немагчыма рэалізаваць некаторыя віды функцыянальнасці, якія падаюць цэнтралізаваныя сістэмы. Гэта:
* Блакіроўка файла ці групы файлаў (для захоўвання прыкметы блакіроўкі патрэбны агульнадаступны цэнтральны сервер, які няспынна знаходзіцца online). Гэта вымушае ўжыць спецыяльныя адміністрацыйныя меры, калі даводзіцца працаваць з бінарнымі файламі, непрыдатнымі для аўтаматычнага зліцця.
* Сачэнне за пэўным файлам ці групай файлаў (змены файлаў адбываюцца на розных серверах, зліццё і вылучэнне галін адбываецца лакальна, аб зменах становіцца вядома толькі падчас сінхранізацыі, прычым не ўсім распрацоўшчыкам, а толькі тым, хто ўдзельнічае ў гэтай сінхранізацыі).
* Адзіная скразная нумарацыя версій сістэмы і/ці файлаў, дзе нумар версіі аднастайна узрастае (такая нумарацыя таксама патрабуе наяўнасці галоўнага сервера, які задае нумары версій для ўсіх астатніх). У размеркаваных сістэмах даводзіцца абыходзіцца лакальнымі пазначэннямі версій і ўжываць тэгі, прызначэнне якіх вызначаецца дамовай паміж распрацоўшчыкамі ці карпаратыўнымі стандартамі фірмы.
* Лакальная праца карыстальніка з асобнай, невялікай па аб'ёму выбаркай са значнага па памеру і ўнутранай складанасці сховішча на аддаленым серверы.

Можна вызначыць наступныя тыповыя сітуацыі, у якіх ужыванне размеркаванай сістэмы дае заўважныя перавагі:

* Перыядычная сінхранізацыя некалькіх камп'ютараў пад кіраванне аднаго распрацоўшчыка (рабочага камп'ютара, хатняга камп'ютара, ноўтбука і інш.). Выкарыстанне размеркаванай сістэмы пазбаўляе ад неабходнасці вылучаць адзін з камп'ютараў у якасці сервера, а сінхранізацыя выконваецца па патрэбе, звычайна пры «перасадцы» распрацоўшчыка з адной прылады на іншую.
* Сумесная работа над праектам невялікай тэрытарыяльна размеркаванай групы распрацоўшчыкаў без вылучэння агульных рэсурсаў. Як і ў папярэднім выпадку, рэалізуецца схема працы без галоўнага сервера, а актуальнасць рэпазітараў падтрымліваецца перыядычнымі сінхранізацыямі па схеме «кожны з кожным».
* Буйны размеркаваны праект, удзельнікі якога могуць працяглы час працаваць кожны над сваёй часткай, пры гэтым не маюць сталага далучэння да сеціва. Такі праект можа ўжываць цэнтралізаваны сервер, з якім сінхранізуюцца копіі ўсіх яго ўдзельнікаў. Магчымы і больш складаныя варыянты — напрыклад са стварэннем груп для работы па асобных напрамках унутры больш буйнога праекта. Пры гэтым могуць быць вылучаны асобныя «групавыя» серверы для сінхранізацыі работы груп, тады працэс выніковага зліцця змен становіцца дрэвападобным: спачатку асобныя распрацоўшчыкі сінхранізуюць змены на групавых серверах, потым адноўленыя рэпазітары груп сінхранізуюцца з галоўным серверам. Магчыма работа і без «групавых» сервераў, тады распрацоўшчыкі адной групы сінхранізуюць змены паміж сабой, пасля чаго любы з іх (напрыклад, кіраўнік групы) перадае змены на цэнтральны сервер.
 
У традыцыйнай «офіснай» распрацоўцы праектаў, калі група распрацоўшчыкаў адносна невялікая і цалкам знаходзіцца на адной тэрыторыі, у межах адзінай лакальнай камп'ютарнай сеткі з увесь час даступнымі серверамі, цэнтралізаваная сістэма можа апынуцца лепшым выбарам з-за сваёй больш жорсткай структуры і наяўнасці функцыянальнасці, якая адсутнічае ў размеркаваных сістэмах. Магчымасць фіксаваць змены без іх зліцця ў цэнтральную галіну ў такіх умовах лёгка рэалізуецца шляхам вылучэння няскончаных работ у асобныя галіны распрацоўкі.

## Слоўнік 
Агульнапрынятай тэрміналогіі не існуе, у розных сістэмах могуць ужывацца розныя назвы для адных і тых жа дзеяў. Ніжэй прыведзены некаторыя з найбольш часта ўжывальных варыянтаў.

; **branch** : Галіна — кірунак распрацоўкі, незалежны ад іншых. Галіна ўяўляе сабой копію часткі (як правіла, аднаго каталога) сховішча, у якую можна ўносіць свае змены, якія не ўплываюць на іншыя галіны. Дакументы ў розных галінах маюць аднолькавую гісторыю да пункта галінавання і розныя — пасля яе.
; **changeset**, **activity** : Набор змен. Уяўляе сабой іменаваны шэраг правак, зробленых у лакальнай копіі дзеля нейкай агульнай мэты. У сістэмах, дзе падтрымліваюцца шэрагі правак, распрацоўшчык можа аб'ядноўваць лакальныя праўкі ў групы і выконваць фіксацыю лагічна звязаных змен адной камандай, указаўшы патрэбны шэраг правак у якасці параметра. Пры гэтым іншыя праўкі застануцца незафіксаванымі. Тыповы ўзор: вядзецца работа над даданнем новай функцыянальнасці, а ў гэты момант выяўляецца крытычная памылка, якую трэба неадкладна выправіць. распрацоўшчык стварае шэраг змен для ўжо зробленай працы і новы — для выпраўленняў. Па сканчэнні выпраўлення памылкі выконваецца каманда фіксацыі толькі другога шэрагу правак.
; **check-in**, **commit**, **submit** : Стварэнне новай версіі, фіксацыя змен. Распаўсюджванне змен, якія зроблены ў рабочай копіі, на сховішча дакументаў. Пры гэтым у сховішчы ствараецца новая версія змененых дакументаў.
; **check-out**, **clone** : Выманне дакумента са сховішча і стварэнне рабочай копіі.
; **conflict** : Канфлікт — сітуацыя, калі некалькі карыстальнікаў зрабілі змены аднаго і таго ж кавалка дакумента. Канфлікт выяўляецца, калі адзін карыстальнік зафіксаваў свае змены, а другі спрабуе зафіксаваць свае, і сістэма сама не здольна карэктна зліць канфліктныя змены. Паколькі праграма можа быць недастаткова разумнай для таго, каб вызначыць, якая змена з'яўляецца «карэктнай», другому карыстальніку патрэбна самому вырашыць канфлікт (**resolve**).
; **head** : Асноўная версія — самая свежая версія для галіны/ствала, якая знаходзіцца ў сховішчы. Колькі галін, столькі асноўных версій.
; **merge**, **integration** : Зліццё — аб'яднанне незалежных змен у адзіную версію дакумента. Ажыццяўляецца, калі дзве асобы змянілі адзін і той жа файл ці пры пераносе змен з адной галіны ў іншую.
; **rebase** : Перанос пункта галінавання (версіі, ад якой пачынаецца галіна) на больш познюю версію асноўнай галіны. Напрыклад, пасля выпуску версіі 1.0 праекта ў ствале працягваецца дапрацоўка (выпраўленне памылак, дапрацоўка наяўнага функцыяналу), адначасова пачынаецца работа над новай функцыянальнасцю ў новай галіне. Праз нейкі час у галоўнай галіне адбываецца выпуск версіі 1.1 (з выпраўленнямі); зараз пажадана, каб галіна распрацоўкі новага функцыяналу ўключала змены, які адбыліся ў ствале. Гэта можна зрабіць і базавымі сродкамі, з дапамогай зліцця (merge), выдзеліўшы набор змен паміж версіямі 1.0 і 1.1 і зліўшы яго ў галіну. Але пры наяўнасці ў сістэме падтрымкі перабазавання галіны гэтая аперацыя робіцца прасцей, адной камандай: па камандзе rebase (з параметрамі: галіной і новай базавай версіяй) сістэма самастойна вызначае патрэбныя наборы змен і робіць іх зліццё, пасля чаго для галіны базавай версіяй становіцца версія 1.1; пры наступным зліцці галіны са ствалом сістэма не разглядае паўторна змены, якія былі зроблены паміж версіямі 1.0 і 1.1, таму што галіна лагічна лічыцца вылучанай пасля версіі 1.1.
; **repository**, **depot** : Сховішча дакументаў — месца, дзе сістэма кіравання версіямі захоўвае ўсе дакументы разам з гісторыяй іх зменяў і іншай службовай інфармацыяй.
; **revision** : Версія дакумента. Сістэмы кіравання версіямі адрозніваюць версіі па нумарах, якія прызначаюцца аўтаматычна.
; **shelving** : Адкладанне змен. Магчымасці, якія падаюць некаторыя сістэмы  па стварэнні шэрагу змен (changeset) і захавання яго на серверы без фіксацыі (commit). Адкладзены набор змен даступны для чытання іншым удзельнікам праекта, але да спецыяльнай каманды не ўваходзіць у асноўную каліну. Падтрымка адкладання змен дае магчымасць карыстальнікам захоўваць незавершаныя работы на серверы, не ствараючы для гэтага асобных галін.
; **tag**, **label** : Метка, якую можна прызначыць пэўнай версіі дакумента. Метка ўяўляе сабой сімвалічнае імя для групы дакументаў, пры гэтым метка апісвае не толькі набор імён файлаў, але і версію кожнага файла. Версіі ўключаных у метку дакументаў могуць належыць розным момантам часу.
; **trunk**, **mainline**, **master** : Ствол — асноўная галіна распрацоўкі праекта. Палітыка работы са ствалом можа адрознівацца ў розных праектах, але ў цэлым яна такая: большасць змен уносіцца ў ствол; калі патрабуецца сур'ёзная змена, якая здольна прывесці да нестабільнасці, ствараецца галіна, якая зліваецца са ствалом, калі новаўвядзенне будзе ў дастатковай меры выпрабавана; перад выпускам чарговай версіі ствараецца «рэлізная» галіна, у якую ўносяцца толькі выпраўленні.
; **update**, **sync** : Сінхранізацыя рабочай копіі да некаторага зададзенага стану сховішча. Часцей за ўсё гэтае дзеянне значыць абнаўленне рабочай копіі да самага свежага стану сховішча. Аднак пры неабходнасці можна сінхранізаваць рабочую копію і да больш старога стану, чым бягучы.
; **working copy** : Рабочая (лакальная) копія дакументаў.

## Гл. таксама 
* Канфігурацыйнае кіраванне (Software Configuration Management), інструменты канфігурацыйнага кіравання (Software Configuration Management Tools)
* Сховішча зместу
* Праграмныя прадукты з празрыстым кіраваннем версіямі
** Некаторыя рэалізацыі WebDAV/DeltaV
** Аперацыйная сістэма OpenVMS
** MediaWiki (і большасць іншых вікі-рухавікоў)

## Спасылкі 
* Сістэмы кіравання версіямі для Linux. Агляд архітэктуры, мадэлей і прыкладаў. (Узровень складанасці: просты) developerWorks
* Distributed Version Control Systems: A Not-So-Quick Guide Through
* Subversion or CVS, Bazaar or Mercurial?  John Ferguson Smart, JavaWorld.com
* The Risks of Distributed Version Control Бэн Колінз-Сассман (стваральнік Subversion) аб размеркаваных сістэмах кіравання версіямі.
* A Maturity Model for Source Control (SCMM)  параўнанне сістэм кіравання версіямі з пункту гледжання завершанасці працэсу распрацоўкі ПЗ.

*