Что такое VCS (система контроля версий)
Система контроля версий (от англ. Version Control System, VCS) — это место хранения кода. Как dropbox, только для разработчиков!
Она заточена именно на разработку продуктов. То есть на хранение кода, синхронизацию работы нескольких человек, создание релизов (бранчей). Но давайте я лучше расскажу на примере, чем она лучше дропбокса. Всё как всегда, история с кучей картиночек для наглядности ))
А потом я подробнее расскажу, как VCS работает — что значит «создать репозиторий», «закоммитить и смерджить изменения», и другие страшные слова. В конце мы пощупаем одну из систем VCS руками, скачаем код из открытого репозитория.
- Что это такое и зачем она нужна
- Как VCS работает
- Подготовительная работа
- Создать репозиторий
- Скачать проект из репозитория
- Ежедневная работа
- Обновить проект, забрать последнюю версию из репозитория
- Внести изменения в репозиторий
- Разрешить конфликты (merge)
- Создать бранч (ветку)
- Через консоль
- Через IDEA
- Через TortoiseGit
Что это такое и зачем она нужна
Допустим, что мы делаем калькулятор на Java (язык программирования). У нас есть несколько разработчиков — Вася, Петя и Иван. Через неделю нужно показывать результат заказчику, так что распределяем работу:
- Вася делает сложение;
- Петя — вычитание;
- Иван — начинает умножение, но оно сложное, поэтому переедет в следующий релиз.
Исходный код калькулятора хранится в обычной папке на сетевом диске, к которому все трое имеют доступ. Разработчик копирует этот код к себе на машину, вносит изменения и проверяет. Если всё хорошо — кладет обратно. Так что код в общей папке всегда рабочий!

Итак, все забрали себе файлы из общей папки. Пока их немного:
- Main.java — общая логика
- GUI.java — графический интерфейс программы
С ними каждый и будет работать!
Вася закончил работу первым, проверил на своей машине — все работает, отлично! Удовлетворенно вздохнув, он выкладывает свой код в общую папку. Вася сделал отдельный класс на сложение (Sum.java), добавил кнопку в графический интерфейс (внес изменения в GUI.java) и прописал работу кнопки в Main.java.

Петя химичил-химичил, ускорял работу, оптимизировал. Но вот и он удовлетворенно вздохнул — готово! Перепроверил ещё раз — работает! Он копирует файлы со своей машины в общую директорию. Он тоже сделал отдельный класс для новой функции (вычитание — Minus.java), внес изменения в Main.java и добавил кнопку в GUI.java.

Ваня пока химичит на своей машине, но ему некуда торопиться, его изменения попадут только в следующий цикл.
Все довольны, Вася с Петей обсуждают планы на следующий релиз. Но тут с показа продукта возвращается расстроенная Катя, менеджер продукта.
— Катя, что случилось??
— Вы же сказали, что всё сделали! А в графическом интерфейсе есть только вычитание. Сложения нет!
— Как это нет? Я же добавлял!
Стали разбираться. Оказалось, что Петин файл затер изменения Васи в файлах, которые меняли оба: Main.java и GUI.java. Ведь ребята одновременно взяли исходные файлы к себе на компьютеры — у обоих была версия БЕЗ новых функций.

Вася первым закончил работу и обновил все нужные файлы в общей папке. Да, на тот момент всё работало. Но ведь Петя работал в файле, в котором ещё не было Васиных правок.

Поэтому, когда он положил документы в хранилище, Васины правки были стерты. Остался только новый файл Sum.java, ведь его Петя не трогал.

Хорошо хоть логика распределена! Если бы всё лежало в одном классе, было бы намного сложнее совместить правки Васи и Пети. А так достаточно было немного подправить файлы Main.java и GUI.java, вернув туда обработку кнопки. Ребята быстро справились с этим, а потом убедились, что в общем папке теперь лежит правильная версия кода.
Собрали митинг (жаргон — собрание, чтобы обсудить что-то):
— Как нам не допустить таких косяков в дальнейшем?
— Давайте перед тем, как сохранять файлы в хранилище, забирать оттуда последние версии! А ещё можно брать свежую версию с утра. Например, в 9 часов. А перед сохранением проверять дату изменения. Если она позже 9 утра, значит, нужно забрать измененный файл.
— Да, давайте попробуем!

Вася с Петей были довольны, ведь решение проблемы найдено! И только Иван грустит. Ведь он целую неделю работал с кодом, а теперь ему надо было синхронизировать версии. То есть объединять свои правки с изменениями коллег.

Доделав задачу по умножению, Иван синхронизировал свои файлы с файлами из хранилища. Это заняло половину рабочего дня, но зато он наконец-то закончил работу! Довольный, Иван выключил компьютер и ушел домой.
Когда он пришел с утра, в офисе был переполох. Вася бегал по офису и причитал:
— Мои изменения пропали. А я их не сохранил!
Увидев Ваню, он подскочил к нему и затряс за грудки:
— Зачем ты стер мой код??

Стали разбираться. Оказалось что Вася вчера закончил свой кусок работы, проверил, что обновлений файлов не было, и просто переместил файлы со своего компьютера в общую папку. Не скопировал, а переместил. Копий никаких не осталось.
После этого изменения вносил Иван. Да, он внимательно вычитывал файлы с кодом и старался учесть и свои правки, и чужие. Но изменений слишком много, часть Васиных правок он потерял.
— Код теперь не работает! Ты вообще проверял приложение, закончив синхронизацию?
— Нет, я только свою часть посмотрел.

Вася покачал головой:
— Но ведь при сохранении на общий диск можно допустить ошибку! По самым разным причинам:
- Разработчик начинающий, чаще допускает ошибки.
- Случайно что-то пропустил — если нужно «объединить» много файлов, что-то обязательно пропустишь.
- Посчитал, что этот код не нужен — что он устарел или что твоя новая логика делает то же самое, а на самом деле не совсем.
И тогда приложение вообще перестанет работать. Как у нас сейчас.
— Хм. Да, пожалуй, ты прав. Нужно тестировать итоговый вариант!
— И сохранять версии. Может, перенесем наш код в Dropbox, чтобы не терять изменения?

На том и порешили. Остаток дня все трое работали над тем, чтобы приложение снова заработало. После чего бережно перенесли код в дропбокс. Теперь по крайней мере сохранялись старые версии. И, если разработчик криво синхронизировал файлы или просто залил свои, затерев чужие изменения, можно было найти старую версию и восстановить ее.
Через пару дней ребята снова собрали митинг:
— Ну как вам в дропбоксе?
— Уже лучше. По крайней мере, не потеряем правки!
Петя расстроенно пожимает плечами:
— Да, только мы с Васей одновременно вносили изменения в Main.java, создалась конфликтующая версия. И пришлось вручную их объединять. А класс то уже подрос! И глазками сравнивать 100 строк очень невесело. Всегда есть шанс допустить ошибку.
— Ну, можно же подойти к тому, кто создал конфликт и уточнить у него, что он менял.
— Хорошая идея, давайте попробуем!

Попробовали. Через несколько дней снова митинг:
— Да всё зашибись, работаем!
— А почему код из дропбокса не работает?
— Как не работает. Мы вчера с Васей синхронизировались!
— А ты попробуй его запустить.
Посмотрели все вместе — и правда не работает. Какая-то ошибка в Main.java. Стали разбираться:
— Так, тут не хватает обработки исключения.
— Ой, подождите, я же её добавлял!
— Но ты мне не говорил о ней, когда мы объединяли правки.
— Да? Наверное, забыл.
— Может, еще что забыл? Ну уж давай лучше проверим глазами.

Посидели, выверили конфликтные версии. Потратили час времени всей команды из-за пустяка. Обидно!
— Слушайте, может, это можно как-то попроще делать, а? Чтобы человека не спрашивать «что ты менял»?
— Можно использовать программу сравнения файлов. Я вроде слышал о таких. AraxisMerge, например!
— Ой, точно! В IDEA же можно сравнивать твой код с клипбордом (сохраненным в Ctrl + C значении). Давайте использовать его!
Начали сравнивать файлы через программу — жизнь пошла веселее. Но через пару дней Иван снова собрал митинг:
— Ребята, тут такая тема! Оказывается, есть специальные программы для хранения кода! Они хранят все версии и показывают разницу между ними. Только делает это сама программа, а не человек!
— Да? И что за программы?
— Системы контроля версий называются. Вот SVN, например. Давайте попробуем его?

Попробовали. Работает! Еще и часть правок сама синхронизирует, даже если Вася с Петей снова не поделили один файл. Как она это делает? Давайте разбираться!
Как VCS работает
Подготовительная работа
Это те действия, которые нужно сделать один раз.
1. Создать репозиторий
Исходно нужно создать место, где будет лежать код. Оно называется репозиторий. Создается один раз администратором.
Ребята готовы переехать из дропбокса в SVN. Сначала они проверяют, что в дропбоксе хранится актуальная версия кода, ни у кого не осталось несохраненных исправлений на своей машине. Потом ребята проверяют, что «итоговый» код работает.
А потом Вася берет код из дропбокса, и кладет его в VCS специальной командой. В разных системах контроля версии разные названия у команды, но суть одна — создать репозиторий, в котором будет храниться код.

Всё! Теперь у нас есть общее хранилище данных! С ним дальше и будем работать.
2. Скачать проект из репозитория
Теперь команде нужно получить проект из репозитория. Можно, конечно, и из дропбокса скачать, пока там актуальная версия, но давайте уже жить по-правильному!
Поэтому Петя, Вася и Иван удаляют то, что было у них было на локальных компьютерах. И забирают данные из репозитория, клонируя его. В Mercurial (один из вариантов VCS) эта команда так и называется — clone. В других системах она зовется иначе, но смысл всё тот же — клонировать (копировать) то, что лежит в репозитории, к себе на компьютер!

Забрать код таким образом нужно ровно один раз, если у тебя его ещё не было. Дальше будут использоваться другие команды для передачи данных туда-сюда.
А когда на работу придет новый сотрудник, он сделает то же самое — скачает из репозитория актуальную версию кода.

Ежедневная работа
А это те действия, которые вы будете использовать часто.
1. Обновить проект, забрать последнюю версию из репозитория
Приходя утром на работу, нужно обновить проект на своем компьютере. Вдруг после твоего ухода кто-то вносил изменения?
Так, Вася обновил проект утром и увидел, что Ваня изменил файлы Main.java и GUI.java. Отлично, теперь у Васи актуальная версия на машине. Можно приступать к работе!

В SVN команда обновления называется «update», в Mercurial — «pull». Она сверяет код на твоем компьютере с кодом в репозитории. Если в репозитории появились новые файлы, она их скачает. Если какие-то файлы были удалены — удалит и с твоей машины тоже. А если что-то менялось, обновит код на локальном компьютере.

Тут может возникнуть вопрос — в чем отличие от clone? Можно же просто клонировать проект каждый раз, да и всё! Зачем отдельная команда?
Клонирование репозитория производится с нуля. А когда разработчики работают с кодом, у них обычно есть какие-то локальные изменения. Когда начал работу, но ещё не закончил. Но при этом хочешь обновить проект, чтобы конфликтов было меньше.
Если бы использовалось клонирование, то пришлось бы переносить все свои изменения в «новый» репозиторий вручную. А это совсем не то, что нам нужно. Обновление не затронет новые файлы, которые есть только у вас на компьютере.
А еще обновление — это быстрее. Обновиться могли 5 файликов из 1000, зачем выкачивать всё?
2. Внести изменения в репозиторий
Вася работает над улучшением сложения. Он придумал, как ускорить его работу. А заодно, раз уж взялся за рефакторинг (жаргон — улучшение системы, от англ. refactor), обновил и основной класс Main.java.
Перед началом работы он обновил проект на локальном (своём) компьютере, забрав из репозитория актуальные версии. А теперь готов сохранить в репозиторий свои изменения. Это делается одной или двумя командами — зависит от той VCS, которую вы используете в работе.
1 команда — commit
Пример системы — SVN.
Сделав изменения, Вася коммитит их. Вводит команду «commit» — и все изменения улетают на сервер. Всё просто и удобно.

2 команды — commit + push
Примеры системы — Mercurial, Git.
Сделав изменения, Вася коммитит их. Вводит команду «commit» — изменения сохранены как коммит. Но на сервер они НЕ уходят!

Чтобы изменения пошли на сервер, их надо «запушить». То есть ввести команду «push».
Это удобно, потому что можно сделать несколько разных коммитов, но не отправлять их в репозиторий. Например, потому что уже code freeze и тестировщики занимаются регрессией. Или если задача большая и может много всего сломать. Поэтому её надо сначала довести до ума, а потом уже пушить в общий репозиторий, иначе у всей команды развалится сборка!
При этом держать изменения локально тоже не слишком удобно. Поэтому можно спокойно делать коммиты, а потом уже пушить, когда готов. Или когда интернет появился =) Для коммитов он не нужен.

Итого
Когда разработчик сохраняет код в общем хранилище, он говорит:
Смотря в какой системе он работает. После этих слов вы уверены — код изменен, можно обновить его на своей машине и тестировать!
3. Разрешить конфликты (merge)
Вася добавил вычисление процентов, а Петя — деление. Перед работой они обновили свои локальные сборки, получив с сервера версию 3 файлов Main.java и Gui.java.
Для простоты восприятия нарисуем в репозитории только эти файлы и Minus.java, чтобы показать тот код, который ребята трогать не будут.

Вася закончил первым. Проверив свой код, он отправил изменения на сервер. Он:
- Добавил новый файл Percent.java
- Обновил Main.java (версию 3)
- Обновил Gui.java (версию 3)
При отправке на сервер были созданы версии:

- Percent.java — версия 1
- Main.java — версия 4
- Gui.java — версия 4
Петя закончил чуть позже. Он:
- Добавил новый файл Division.java
- Обновил Main.java (версию 3, ведь они с Васей скачивали файлы одновременно)
- Обновил Gui.java (версию 3)
Готово, можно коммитить! При отправке на сервер были созданы версии:
- Division.java — версия 1
- Main.java — версия 4
- Gui.java — версия 4
Но стойте, Петя обновляет файлы, которые были изменены с момента обновления кода на локальной машине! Конфликт!

Часть конфликтов система может решить сама, ей достаточно лишь сказать «merge». И в данном случае этого будет достаточно, ведь ребята писали совершенно разный код, а в Main.java и Gui.java добавляли новые строчки, не трогая старые. Они никак не пересекаются по своим правкам. Поэтому система «сливает» изменения — добавляет в версию 4 Петины строчки.

Но что делать, если они изменяли один и тот же код? Такой конфликт может решить только человек. Система контроля версий подсвечивает Пете Васины правки и он должен принять решение, что делать дальше. Система предлагает несколько вариантов:

- Оставить Васин код, затерев Петины правки — если Петя посмотрит Васины изменения и поймет, что те лучше
- Затереть Васины правки, взяв версию Петра — если он посчитает, что сам все учел
- Самому разобраться — в таком случае в файл кода добавляются обе версии и надо вручную слепить из них итоговый кусок кода
Разрешение конфликтов — самая сложная часть управления кодом. Разработчики стараются не допускать их, обновляя код перед тем, как трогать файл. Также помогают небольшие коммиты после каждого завершенного действия — так другие разработчики могут обновиться и получить эти изменения.
Но, разумеется, конфликты все равно бывают. Разработчики делают сложные задачи, на которые уходит день-два. Они затрагивают одни и те же файлы. В итоге, вливая свои изменения в репозиторий, они получают кучу конфликтов, и нужно просмотреть каждый — правильно ли система объединила файлы? Не нужно ли ручное вмешательство?
Особая боль — глобальный рефакторинг, когда затрагивается МНОГО файлов. Обновление версии библиотеки, переезд с ant на gradle, или просто выкашивание легаси кода. Нельзя коммитить его по кусочкам, иначе у всей команды развалится сборка.
Поэтому разработчик сначала несколько дней занимается своей задачей, а потом у него 200 локальных изменений, среди которых явно будут конфликты.

А что делать? Обновляет проект и решает конфликты. Иногда в работе над большой задачей разработчик каждый день обновляется и мерджит изменения, а иногда только через несколько дней.
Тестировщик будет сильно реже попадать в конфликтные ситуации, просто потому, что пишет меньше кода. Иногда вообще не пишет, иногда пополняет автотесты. Но с разработкой при этом почти не пересекается. Однако выучить merge все равно придется, пригодится!
4. Создать бранч (ветку)
На следующей неделе нужно показывать проект заказчику. Сейчас он отлично работает, но разработчики уже работают над новыми изменениями. Как быть? Ребята собираются на митинг:
— Что делать будем? Не коммитить до показа?
— У меня уже готовы новые изменения. Давайте закоммичу, я точно ничего не сломал.
Катя хватается за голову:
— Ой, давайте без этого, а? Мне потом опять краснеть перед заказчиками!
Тут вмешивается Иван:
— А давайте бранчеваться!

Все оглянулись на него:
Иван стал рисовать на доске:
— Бранч — это отдельная ветка в коде. Вот смотрите, мы сейчас работаем в trunk-е, основной ветке.

Когда мы только-только добавили наш код на сервер, у нас появилась «точка возврата» — сохраненная версия кода, к которой мы можем обратиться в любой момент.

Потом Вася закоммитил изменения по улучшению классов — появилась версия 1 кода.

Потом он добавил проценты — появилась версия кода 2.

При этом в самой VCS сохранены все версии, и мы всегда можем:

- Посмотреть изменения в версии 1
- Сравнить файлы из версии 1 и версии 2 — система наглядно покажет, где они совпадают, а где отличаются
- Откатиться на прошлую версию, если версия 2 была ошибкой.
Потом Петя добавил деление — появилась версия 3.

И так далее — сколько сделаем коммитов, столько версий кода в репозитории и будет лежать. А если мы хотим сделать бранч, то система копирует актуальный код и кладет отдельно. На нашем стволе появляется новая ветка (branch по англ. — ветка). А основной ствол обычно зовут trunk-ом.

Теперь, если я захочу закоммитить изменения, они по-прежнему пойдут в основную ветку. Бранч при этом трогать НЕ будут (изменения идут в ту ветку, в которой я сейчас нахожусь. В этом примере мы создали branch, но работать продолжаем с trunk, основной веткой)
Так что мы можем смело коммитить новый код в trunk. А для показа использовать branch, который будет оставаться стабильным даже тогда, когда в основной ветке всё падает из-за кучи ошибок.
С бранчами мы всегда будем иметь работающий код!

— Подожди, подожди! А зачем эти сложности? Мы ведь всегда может просто откатиться на нужную версию! Например, на версию 2. И никаких бранчей делать не надо!
— Это верно. Но тогда тебе нужно будет всегда помнить, в какой точке у тебя «всё работает и тут есть все нужные функции». А если делать говорящие названия бранчей, обратиться к ним намного проще. К тому же иногда надо вносить изменения именно в тот код, который на продакшене (то есть у заказчика).
Вот смотри, допустим, мы выпустили сборку 3, идеально работающую. Спустя неделю Заказчик ее установил, а спустя месяц нашел баг. У нас за эти недели уже 30 новых коммитов есть и куча изменений.

Заказчику нужно исправление ошибки, но он не готов ставить новую версию — ведь ее надо тестировать, а цикл тестирования занимает неделю. А баг то нужно исправить здесь и сейчас! Получается, нам надо:
- Обновиться на версию 3
- Исправить баг локально (на своей машине, а не в репозитории)
- Никуда это не коммитить = потерять эти исправления
- Собрать сборку локально и отдать заказчику
- Не забыть скопипастить эти исправления в актуальную версию кода 33 и закоммитить (сохранить)
Что-то не очень весело. А если нужно будет снова дорабатывать код? Искать разработчика, у которого на компьютере сохранены изменения? Или скопировать их и выложить на дропбокс? А зачем тогда использовать систему контроля версий?

Именно для этого мы и бранчуемся! Чтобы всегда иметь возможность не просто вернуться к какому-то коду, но и вносить в него изменения. Вот смотрите, когда Заказчик нашел баг, мы исправили его в бранче, а потом смерджили в транк.
Смерджили — так называют слияние веток. Это когда мы внесли изменения в branch и хотим продублировать их в основной ветке кода (trunk). Мы ведь объединяем разные версии кода, там наверняка есть конфликты, а разрешение конфликтов это merge, отсюда и название!

Если Заказчик захочет добавить новую кнопочку или как-то еще изменить свою версию кода — без проблем. Снова вносим изменения в нужный бранч + в основную ветку.
Веток может быть много. И обычно чем старше продукт, тем больше веток — релиз 1, релиз 2. релиз 52.
Есть программы, которые позволяют взглянуть на дерево изменений, отрисовывая все ветки, номера коммитов и их описание. Именно в таком стиле, как показано выше =) В реальности дерево будет выглядеть примерно вот так (картинка из интернета):

А иногда и ещё сложнее!
— А как посмотреть, в какой ветке ты находишься?
— О, для этого есть специальная команда. Например, в Mercurial это «hg sum»: она показывает информацию о том, где ты находишься. Вот пример ее вызова:
D:\vcs_project\test>hg sum parent: 3:66a91205d385 tip Try to fix bug with device branch: defaultВ данном примере «parent» — это номер коммита. Мы ведь можем вернуться на любой коммит в коде. Вдруг мы сейчас не на последнем, не на актуальном? Можно проверить. Тут мы находимся на версии 3. После двоеточия идет уникальный номер ревизии, ID кода.

Потом мы видим сообщение, с которым был сделан коммит. В данном случае разработчик написал «Try to fix bug with device».
И, наконец, параметр «branch»! Если там значение default — мы находимся в основной ветке. То есть мы сейчас в trunk-е. Если бы были не в нём, тут было бы название бранча. При создании бранча разработчик даёт ему имя. Оно и отображается в этом пункте.

— Круто! Давайте тогда делать ветку!
Для Git создали интерактивную «игрушку», чтобы посмотреть на то, как происходит ветвление — https://learngitbranching.js.org
Отдельно хочу заметить, что бранчевание на релиз — не единственный вариант работы с VCS. Есть и другой подход к разработке — когда транк поддерживают в актуальном и готовом к поставкам состоянии, а все задачи делают в отдельных ветках. Но его мы в этой статье рассматривать не будем.
Итого
Система контроля версий (от англ. Version Control System, VCS) — это dropbox для кода.
Популярные VCS и отличия между ними
Наиболее популярные — это:
- SVN — простая, но там очень сложно мерджиться
- Mercurial (он же HG), Git — намного больше возможностей (эти системы похожи по функционалу)
SVN — очень простая система, одна из первых. Сделал — закоммитил. Всё! Для небольшого проекта её вполне достаточно. Вы можете делать разные ветки и мерджить хоть туда, хоть сюда. Но у неё так себе работает автоматический мердж, на моей практике приходилось каждый файлик брать и копипастить изменения в основную ветку, это было проще, чем смерджить.
@lizardus в комментариях добавил о преимуществах системы:
Главные трудности в svn — всегда нужна сеть, и он может быть очень мммееееддддленный. Ну и с ветками работать не так удобно, в svn это просто директории. Хотя для новичков «папки» svn обычно интуитивнее.
А в целом, svn просто другая система (он работает просто как файловая система) со своими преимуществами и недостатками. Его легко поставить на windows (не тянет за собой треть линукса), он безопасен (все что закоммичено — сохранено навеки, удалить нельзя ничего, никакого rebase), легко сделать checkout одной маленькой части проекта и работать только с ней (а это позволяет модный монорепо без костылей), можно мешать ревизии отдельных файлов в папке проекта и мерджить отдельные файлы произвольным образом. Права доступа к отдельным частям проекта — легко. svn работает с бинарными данными и даже (теоретически) как-то мерджит. Легко аутентификацию по сертификату. Встроенный WebDAV с минимальными усилиями: можно смонтировать как диск в Windows для тех, кому нужен доступ только для чтения, или просто бросить ссылку для браузера (какие-нибудь дизайнеры так могут любоваться картинками из svn или скрипт может получать последние бинарные данные для управления коллайдером).
Mercurial и Git — распределенная система контроля версий. Внесение изменений двухступенчатое — сначала коммит, потом push. Это удобно, если вы работаете без интернета, или делаете мелкие коммиты, но не хотите ломать основной код пока не доделаете большую задачу. Тут есть и автоматическое слияние разных бранчей. Больше возможностей дают системы.
У любой системы контроля версий есть «консольный интерфейс». То есть общаться с ними можно напрямую через консоль, вводя туда команды. Склонировать репозиторий, обновить его, добавить новый файл, удалить старый, смерджить изменения, создать бранч. Всё это делается с помощью команд.
Но есть и графический интерфейс. Устанавливаете отдельную программу и выполняете действия мышкой. Обычно в моей практике это делается через «черепашку» — программа называется Tortoise. TortoiseSVN, TortoiseHG, TortoiseGit. Часть команд можно сделать через среду разработки — IDEA, Eclipse, etc. Плюс есть еще куча других инструментов, часть из них можно найти в комментариях =)
Но любой графический интерфейс как работает? Вы потыкали мышкой, а система Tortoise составила консольную команду из вашего «тык-тык», её и применила.
См также:
Что такое API — подробнее о том, что скрывается за интерфейсом.
Вот некоторые базовые команды и форма их записи в разных VCS:
Действие
Что такое система контроля версий и как ей пользоваться
В арсенале веб-разработчика много полезных инструментов, которые позволяют автоматизировать решение разных задач. Без них время работы сильно увеличивается. А продуктивность падает, потому что приходится вручную делать то, что можно решить с помощью десктопных программ или браузерных расширений.
В статье поговорим о системе контроля версий. Разберёмся, зачем она нужна, как пользоваться инструментом и расскажем о популярных ошибках, которые допускают новички и опытные программисты.
Что такое система контроля версий
Система контроля версий — программное обеспечение, которое обеспечивает командную работу в рамках одного или нескольких проектов. Команда разработчиков взаимодействует с консольным или браузерным инструментом для выгрузки кода на сервер, скачивания его на рабочий компьютер и изменения структуры.
Новичкам обычно сложно вникнуть в технические подробности работы системы контроля версий, поэтому мы постараемся объяснить суть простым языком. Не старайтесь сразу погружаться в термины, пользы от этого будет мало.
Представьте, что играете в компьютерную игру. По мере прохождения миссий происходит сохранение контрольных точек. Даже если выключить компьютер и зайти в приложение через несколько дней или месяцев, прогресс не потеряется. В любой момент можно выбрать контрольную точку и пройти миссию заново.

Система контроля версий работает по аналогичной схеме. Она хранит все версии проекта и обеспечивает к ним доступ. Любой член команды может взаимодействовать с основной «веткой» проекта или создавать новые.
Самой популярной системой контроля версий является Git, поэтому мы не будем подробно останавливаться на альтернативных решениях и расскажем об этом инструменте.
Собрали основные понятия, которые будут полезны всем, кто захочет освоить работу в Git:
- Репозиторий. Каталог, в котором хранится файловая система проекта. Для каждого проекта создаётся отдельный репозиторий. Существуют локальные и удалённые репозитории. В первом осуществляется работа над проектом на компьютере, а второй выступает в роли хранилища.
- Ветка. Дочерняя версия основного репозитория. Она входит в его состав, но не влияет на работу. После того, как разработчики закончат работу над новой функцией или исправят все баги, можно совместить дочерний и родительский репозитории.
- Коммит. Операция позволяет зафиксировать текущее состояние проекта. После выполнения команды через консоль или использования браузерной версии Git, новая версия добавляется в репозиторий.
- Форк. Копия репозитория, которую можно использовать для изменения исходного кода без отправки изменений в основной репозиторий. Форки часто применяют для open-source проектов, когда любой разработчик может собрать свой проект на основе готового ядра.
- Пул и пуш. Первая операция позволяет выкачивать содержимое репозитория на компьютер, а вторая отправляет измененные файлы на сервер.
- Мастер. Основная ветка репозитория, в которой хранится ядро проекта. В неё добавляют изменения только после тщательного тестирования.
- Кодревью. Процесс проверки кода на соответствие техническому заданию или требованиям внутри команды. Когда один разработчик хочет добавить свой код в ядро, остальные члены команды проверяют его и если проблем нет, происходит обновление главной ветки.
Система контроля версий — полезный инструмент, который нужен не только программистам, работающим в команде. Он пригодится и самостоятельным разработчикам для удобного хранения данных проекта. Если что-то пойдёт не так, в любой момент можно вернуться к контрольной точке и начать заново.
Зачем она нужна
Мы уже частично ответили на этот вопрос, но чтобы новички лучше поняли принцип работы, остановимся на нём ещё раз. Если представить работу над проектом в виде прохождения игры, то контрольные точки — промежуточные версии проекта.
Допустим, программист в одиночку работает над плагином для WordPress. Заказчик добавил в техническое задание обязательное условие — использование Git или аналогов. У него большие планы по разработке продукта, поэтому он хочет, чтобы данные находились в свободном доступе.
Программист создаёт репозиторий и начинает работать над плагином. В основной ветке у него хранится первая рабочая версия продукта. После каждого изменения разработчик добавляет новый коммит, а для внедрения масштабных изменений создаёт параллельные ветки.

Дело близится к релизу, но заказчик внезапно обнаруживает серьёзный баг, который нужно срочно исправить. Разработчик возвращается к контрольной точке (коммиту), в которой он допустил ошибку, исправляет её и обновляет основную ветку.
Теперь представьте, что разработка плагина велась на компьютере программиста. Он не использовал систему контроля версий и не хранил промежуточные копии плагина. Ему придётся либо переписывать проект почти с нуля, либо сильно постараться, чтобы исправить баг без изменения основной логики.
Если над сайтом, плагином или сервисом работает команда разработчиков, без системы контроля версий не обойтись. Каждый из них отделится от master-ветки и будет работать над своими задачами. После завершения работы, коллеги проведут кодревью и проект можно собрать воедино.
Git не только позволяет сохранять контрольные точки проекта, но и помогает устранять конфликты. Часто бывает так, что программисты одновременно работают над одной функцией и заливают изменения в репозиторий. В этом случае система обнаруживает конфликт и пытается исправить его автоматически.
Если Git не решит проблему самостоятельно, программисты увидят её и смогут устранить вручную. Окончательное решение всегда остаётся за разработчиком. Он контролирует процесс и решает, как будет происходить дальнейшая работа.
Какие задачи решает система контроля версий:
- Защищает исходный код от потери. Данные хранятся на удалённом сервере, даже если разработчики удалят файлы с локального компьютера, они останутся в репозитории.
- Обеспечивает командную работу. Программисту не надо использовать инструменты для командной работы и платить за них. Каждый может работать на своём компьютере и обновлять файлы по мере необходимости.
- Помогает отменить изменения. В любой момент можно вернуться к контрольной точке, сравнить исходный код с текущим и обновить главную ветку после ревью.
- Распределённая работа. Необязательно работать с проектом «наживую». Плагин может функционировать на сайте, а программисты будут спокойно создавать новую версию.

Git или другая система контроля версий также важна в работе программиста, как и сохранение бэкапов. В любой момент могут понадобиться исходники. И если их не будет, появятся дополнительные проблемы.
Как пользоваться системой контроля версий
Уже давно появился стереотип, что программисты очень любят работать с консолью. Новички представляют, что опытные разработчики вводят 20 команд в минуту и не используют веб-версии с user-friendly интерфейсами.
Git в стандартном варианте устанавливается на компьютер и представляет собой командную строку с минималистичным интерфейсом. Разработчики обычно разделяются на два лагеря: одни пользуются консольной версией, а вторые предпочитают вариант с графической оболочкой.
Если не хотите осваивать консоль и тратите много времени на ввод простых команд, лучше выбрать GitHub. Это крупнейший веб-сервис, на котором размещены тысячи проектов для совместной разработки. Платформа основана на системе контроля версий Git и обеспечивает удобную командную работу.

Любой пользователь может зарегистрироваться на сайте GitHub, чтобы создавать репозитории для своих проектов. Платформа отлично подходит для новичков и даёт полезный опыт. В системе много проектов с открытым исходным кодом, которые можно дорабатывать по своему усмотрению.
По данным GitHub в системе 56 млн разработчиков, больше 100 млн репозиториев и 3 млн организаций. Клиенты, которые обращаются к программистам за разработкой сайта, сервиса или приложения часто добавляют в список требований использование GitHub.
Git и GitHub не получится освоить за несколько часов, если раньше не было опыта работы с системами контроля версий. Новичкам не надо пытаться сразу выучить все термины. Лучше разобраться с основными понятиями, изучить несколько полезных статей и протестировать Git самостоятельно.
Популярные ошибки при работе с Git
Собрали распространённые ошибки, которые мешают начинающим разработчикам полностью использовать возможности системы контроля версий и создают дополнительные проблемы. Некоторые ошибки актуальны и для опытных программистов:
- Отказ от использования Git. Многие новички отказываются от системы контроля версий, когда запускают консоль и не понимают, как с ней работать. Можно заменить десктопную версию на GitHub и вообще не взаимодействовать с консолью.
- Поверхностное изучение документации. В официальной справке много полезной информации, которая экономит время при работе с репозиториями. Её надо обязательно прочитать и запомнить важные особенности.
- Игнорирование правил работы с Git. Идти против системы нельзя, потому что проект окажется под угрозой. Например, не стоит добавлять непроверенные изменения в основную ветку.
- Неправильное использование команд. При работе с консольной версией нельзя запускать команду, если до конца не уверены, какую операцию она выполняет.
- Ошибочные комментарии к коммитам. После нескольких часов активной работы с кодом лучше не отправлять файлы на сервер, а отложить задачу на потом. Разработчики часто оставляют неправильные комментарии к версиям проекта, а коллеги используют их наработки, чтобы продолжить работу.
- Добавление лишних файлов. Если залили файлы, которые не относятся к проекту, их можно удалить или исключить из структуры.

Система контроля версий — must have инструмент для разработчиков с разным опытом. Новичкам лучше сразу освоить его, чтобы использовать для своих проектов и получить дополнительное преимущество перед конкурентами, которые не знают Git или аналоги.
Что такое система контроля версий?
Система контроля версий, также называемая системой управления исходным кодом, позволяет отслеживать изменения исходного кода с течением времени. Эта система обеспечивает быстрое и эффективное сотрудничество разработчиков, сохраняя целостность кода. Это позволяет команде работать, не опасаясь конфликтов в коде.
- Сведения о системе контроля версий
- Почему важна система контроля версий?
- Как работает система контроля версий?
- Сведения о распределенных системах контроля версий
- Сведения о централизованных системах контроля версий
- Сведения о локальных системах контроля версий
Сведения о системе контроля версий
Системы контроля версий (СКВ) позволяют командам создавать резервные копии исходного кода своих проектов и архивировать его. Это упрощает проверку и внесение изменений в репозиторий или восстановление предыдущих версий в случае ошибок, нарушающих работу сборки.
Контроль версий — это системный процесс отслеживания и контроля обновлений исходного кода и ассетов. Системы контроля версий — это базовый компонент эффективных рабочих процессов, который служит единым источником достоверной информации для программистов, художников и других сотрудников и позволяет всем вносить свой вклад в кодовую базу независимо от других. Эти системы также выполняют защитную функцию, давая возможность отменить обновление кода, если во время разработки в код была внесена критическая ошибка.
Такие факторы, как численность сотрудников и их географическое положение, могут повлиять на выбор системы контроля версий для разработки игр. Независимым разработчикам может подойти локальное решение, в то время как большим командам нужна более надежная и масштабируемая система, которая помогает работать совместно в разных часовых поясах и регионах.
Система контроля версий также позволяет создавать ветви. Ветвь — это отдельная копия кода, управляемая СКВ. С помощью ветвей разработчики и другие члены команды могут работать независимо друг от друга в рамках отдельных потоков. Система контроля версий помогает разработчикам совместно работать в общей кодовой базе и синхронизировать изменения.
Почему важна система контроля версий?
Системы контроля версий — это основа методологии DevOps, позволяющая командам вести быструю и эффективную совместную разработку и развивать исходный код проекта.
При использовании СКВ у вас всегда будет резервная копия кода. Отдельные обновления проекта периодически добавляются в группу, которую называют «коммитом», перед объединением с основным исходным кодом. Системы контроля версий также позволяют отслеживать изменения, внесенные в каждый файл проекта. В случае ошибки или регрессии пользователи могут почти мгновенно восстановить более раннюю версию этого файла. СКВ также регистрирует все изменения, их авторов и каждую итерацию. Эта система позволяет всем заинтересованным лицам и участникам команды удобно одновременно работать над многими файлами, а также объединять все изменения кода в одном централизованном репозитории.
Благодаря доступу к полной истории проекта и возможности отменять изменения, вызывающие ошибки, системы контроля версий упрощают отслеживание ошибок и упрощают восстановление ранее удаленных функций.

Как работает система контроля версий?
Если создать в системе контроля версий новый репозиторий, открывается основная ветвь. Она называется главной или стволовой ветвью. Стволовая ветвь — это место, где основная база кода входит в конвейер, где она затем компилируется и развертывается для конечного пользователя.
Рассмотрим, что представляют собой ветви. Ветвление — это процесс создания веток кода из главной ветви. Это позволяет разработчикам вносить свои изменения в код, не отправляя их основную базу. Используя ветви, разработчикам не нужно хранить полную историю файлов на одном сервере. Вместо этого они могут вести полную историю изменений кода с течением времени. Затем система контроля версий может объединить эти отдельные ветви обратно в главную ветвь. Если разработчик не готов к объединению, он может передавать свои изменения в отдельную ветвь, а затем по мере готовности объединить ее с главной ветвью.
Продуманная стратегия ветвления важна для предотвращения конфликтов в коде и ошибок в сборках. К счастью, эффективные системы контроля версий позволяют командам легко синхронизироваться с главной ветвью и устранять любые потенциальные конфликты в коде — даже после его отправки в главную ветвь интеграции.
Сведения о распределенных системах контроля версий
Распределенные системы контроля версий позволяют добавлять код, создавать ветвления и объединять код без подключения к главному серверу. Каждый участник команды работает с клонированным репозиторием, который хранится в облаке. Основное преимущество таких систем состоит в том, что участники команды могут быстро работать независимо, не волнуясь о медленном сетевом подключении или VPN. Можно даже работать с проектом в автономном режиме, хотя для отправки или извлечения обновлений все же требуется подключение к Интернету.
Если вам потребуется скачать всю историю проекта (в частности, крупного проекта с большой историей изменений), в распределенных системах контроля версий это может занять много времени. Студиям, работающим с большими двоичными файлами, следует тщательно отслеживать использование хранилища, так как эти ресурсы могут быстро занять все доступное место.
Студиям, которым необходимы гибкость и возможность повышения производительности, следует рассмотреть использование распределенной системы контроля версий.

Сведения о централизованных системах контроля версий
Централизованные системы контроля версий используют рабочий процесс на основе чекина/выгрузки для подключения к главному серверу. Все изменения или обновления исходного кода автоматически сохраняются в репозитории как новая версия. Централизованные системы контроля версий поддерживают мощные возможности ветвления и слияния, не требующие клонирования репозитория на несколько компьютеров. В этом смысле она более безопасна. Для работы централизованным системам контроля версий требуется подключение к сети. Так как команды привязаны к одной версии проекта, которая хранится на одном сервере, сбой сервиса может существенно замедлить работу. Другой недостаток централизованных систем контроля версий — их плохая масштабируемость. Чем больше разработчиков работают над проектом, тем меньше возможностей выгружать изменения в стабильную среду, что может вызвать такие проблемы, как конфликты при слиянии. Если вам нужна система контроля версий, которую легко настроить и использовать, то вы можете выбрать централизованную систему.
Сведения о локальных системах контроля версий
Локальные системы контроля версий — это самый простой вид подобных систем. Они используются в основном индивидуальными разработчиками, а не командами. В локальной системе контроля версий все данные проекта хранятся на одном компьютере, а изменения файлов проекта хранятся в виде патчей. Каждый патч содержит только обновления, реализованные с момента выпуска предыдущего патча. Если с определенной версией проекта возникает проблема, необходимо изучить весь набор патчей, чтобы понять, как файлы проекта выглядели в определенный момент времени, чтобы выявить и устранить ошибку. Так как локальные системы контроля версий привязаны к одному компьютеру, они по своей природе менее гибкие, чем распределенные и централизованные системы. Совместная работа в таких системах затруднена. При нарушении целостности базы данных будет сложно (если вообще возможно) восстановить утерянную информацию. В целом можно начать с локальной системы контроля версий, но по мере расширения команды, даже до двух человек, лучше перейти на распределенную или централизованную систему.
Что такое Git: объясняем на схемах
Команды разработчиков пользуются системой контроля версий. Чаще всего это Git. Разбираемся, что это значит, зачем нужно и как устроено.



Александр Бабаскин
Автор статей о программировании. Изучает Python, разбирает сложные термины и объясняет их на пальцах новичкам. Если что-то непонятно — возможно, вы ещё не прочли его следующую публикацию.
Git — это система для управления версиями исходного кода программ. В статье мы познакомимся с её основными возможностями, покажем отличие от GitHub и объясним, зачем Git новичку. Ещё вы узнаете, с чего начать обучение и почему не стоит тратить время на альтернативные программы.
Git — это система коммитов
Представьте ситуацию: геймер доходит до финала, проигрывает и возвращается к началу уровня — попадает в ближайшую контрольную точку игры, где разработчики разрешили сохраниться. Если мы уберём контрольные точки, после каждого проигрыша придётся начинать игру заново.
В программировании за сохранение кода в контрольных точках отвечает система контроля версий — специальная технология, которую можно подключить к любому проекту. Система контроля версий страхует от ошибок и возвращает код в то состояние, когда всё работало.
Контрольные точки называются коммитами . Один коммит — это пакет изменений, хранящий информацию с добавленными, отредактированными или удалёнными файлами кода. В один коммит принято добавлять не более десяти изменений — так получается длинная история версий, которая позволяет в случае ошибки откатиться с минимальной потерей работоспособного кода.

Git — это комплекс связанных веток
Коммиты располагаются на master-ветке — основной версии проекта, которая после завершения работы превратится в продукт.
Система контроля версий позволяет создавать ответвления от master-ветки и экспериментировать с проектом, не мешая другим участника команды.
Возьмём предыдущую схему, где мы обнаружили ошибку и откатились на один коммит назад. Чтобы поправить код, создадим несколько дополнительных веток и в каждой протестируем разные варианты решения проблемы. Когда решение найдено, ветку с правильным кодом переносим в master-ветку и сохраняем коммит. Лишние ветки оставляем или удаляем, поскольку они не влияют на проект и скрыты от других разработчиков — это ваш личный черновик.

Git — это инструмент совместного создания кода
Часто бывает так: разработчики отделяются от master-ветки и работают над частью проекта самостоятельно — например, чтобы протестировать дополнительные функции. Но не могут продолжить, пока кто-то из команды не допишет код.
Система контроля версий позволяет не ждать обновления master-ветки и разрешает всем участникам команды свободно перемещаться между ветками других разработчиков для копирования нужных фрагментов кода.
Бывают и обратные ситуации, когда несколько разработчиков одновременно дописывают код, заливают его в master-ветку и сталкиваются с конфликтом — один файл получает несколько несогласованных изменений. В этом случае Git попробует автоматически исправить ошибки. Если не получится, разработчики это увидят и смогут поправить код вручную.

Git — это распределённая система версий
Системы контроля версий бывают локальными, централизованными или распределёнными.
- Локальная система хранит файлы на одном устройстве, централизованная использует общий сервер, а распределённая — общее облачное хранилище и локальные устройства участников команды. В локальной системе удобно работать с большими проектами, но сложно взаимодействовать с удалённой командой.
- В централизованной системе налажена удалённая работа, но всё привязано к одному серверу. Любой сбой или взлом может повредить файлы проекта.
- В распределённой системе налажена удалённая работа. Если с файлами основного репозитория что-то случится — проект легко восстановить из копии любого участника команды.
Из-за удобства и гибкости распределённая система версий Git считается современным форматом. Это стандарт для большинства ИТ-команд.
- Подготовительная работа