Name already in use
OAP / articles / skv.md
- Go to file T
- Go to line L
- Copy path
- Copy permalink
- Open with Desktop
- View raw
- Copy raw contents Copy raw contents
Copy raw contents
Copy raw contents
Системы контроля версий
Что такое контроль версий, и зачем он нужен?
Система контроля версий (СКВ) — это система, регистрирующая изменения в одном или нескольких файлах с тем, чтобы в дальнейшем была возможность вернуться к определённым старым версиям этих файлов (типичный пример: выложили версию в проду, начали работу над новыми фичами и вдруг обнаружились ошибки. Нужно не потеряв новых наработок вернуться к рабочей версии, исправить ошибки).
Можно просто копировать проект в другой каталог, такой подход часто применяется из-за своей простоты, но имеет множество недостатков:
- избыточность (дублируется весь код, а не только изменения)
- нет механизмов для распределения работы между несколькими разработчиками
- нет данных о том что именно изменилось (обычно пишут history файл с общей информацией об изменениях)
Локальные системы контроля версий (для самостоятельного ознакомления )
Для решения части из этих проблем были разработаны локальные СКВ.
Одной из первых и наиболее популярных СКВ такого типа являлась RCS, которая была разработана в 1985 году.
Для каждого файла, зарегистрированного в системе, она хранит полную историю изменений, причём для текстовых файлов используется эффективный алгоритм дельта-компрессии, когда хранится только последняя версия и все межверсионные изменения.
Такие СКВ решали только первую проблему — избыточность данных.
Современные СКВ можно разделить на две группы: централизованные и распределенные.
Централизованные системы контроля версий
Следующей основной проблемой оказалась необходимость сотрудничать с разработчиками за другими компьютерами. Чтобы решить её, были созданы централизованные системы контроля версий (ЦСКВ). В таких системах, например CVS, Subversion и Perforce, есть центральный сервер, на котором хранятся все файлы под версионным контролем, и ряд клиентов, которые получают копии файлов из него. Много лет это было стандартом для систем контроля версий.
Такой подход имеет множество преимуществ, особенно перед локальными СКВ. К примеру, все знают, кто и чем занимается в проекте. У администраторов есть чёткий контроль над тем, кто и что может делать, и, конечно, администрировать ЦСКВ намного легче, чем локальные базы на каждом клиенте.
Однако при таком подходе есть и несколько серьёзных недостатков. Наиболее очевидный — централизованный сервер является уязвимым местом всей системы. Если сервер выключается на час, то в течение часа разработчики не могут взаимодействовать, и никто не может сохранить новой версии своей работы. Если же повреждается диск с центральной базой данных и нет резервной копии, вы теряете абсолютно всё — всю историю проекта, разве что за исключением нескольких рабочих версий, сохранившихся на рабочих машинах пользователей. Локальные системы контроля версий подвержены той же проблеме: если вся история проекта хранится в одном месте, вы рискуете потерять всё.
Распределённые системы контроля версий
И в этой ситуации в игру вступают распределённые системы контроля версий. В таких системах как Git, Mercurial, Bazaar или Darcs клиенты не просто выгружают последние версии файлов, а полностью копируют весь репозиторий (репозиторий, в простонародье репа, это место, где хранятся и поддерживаются какие-либо данные). При этом можно выделить центральный репозиторий (условно), в который будут отправляться изменения из локальных и, с ним же эти локальные репозитории будут синхронизироваться. Поэтому в случае, когда «умирает» сервер, через который шла работа, любой клиентский репозиторий может быть скопирован обратно на сервер, чтобы восстановить базу данных. Каждый раз, когда клиент забирает свежую версию файлов, он создаёт себе полную копию всех данных.
Кроме того, в большей части этих систем можно работать с несколькими удалёнными репозиториями.
На сегодняшний день стандартом де-факто стала распределенная система контроля версий — GIT, но в старых больших проектах вполне могут встретиться устаревшие СКВ (например, популярная в свое время Subversion).
В дальнейшем, все изложение будет касаться только GIT.
Почти все операции — локальные
Для совершения большинства операций в Git’е необходимы только локальные файлы и ресурсы, т.е. обычно информация с других компьютеров в сети не нужна.
К примеру, чтобы показать историю проекта, Git’у не нужно скачивать её с сервера, он просто читает её прямо из вашего локального репозитория. Поэтому историю вы увидите практически мгновенно. Если вам нужно просмотреть изменения между текущей версией файла и версией, сделанной месяц назад, Git может взять файл месячной давности и вычислить разницу на месте, вместо того чтобы запрашивать разницу у СКВ-сервера или качать с него старую версию файла и делать локальное сравнение.
Кроме того, работа локально означает, что практически все можно сделать без доступа к Сети. Если вы в самолёте или в поезде и хотите немного поработать, можно спокойно делать коммиты, а отправить их, как только станет доступна сеть. Во многих других системах это невозможно или же крайне неудобно. Например, используя Perforce, вы мало что можете сделать без соединения с сервером. Работая с Subversion и CVS, вы можете редактировать файлы, но сохранить изменения в вашу базу данных нельзя (потому что она отключена от репозитория).
Git следит за целостностью данных
Перед сохранением любого файла Git вычисляет контрольную сумму, и она становится индексом этого файла. Поэтому невозможно изменить содержимое файла или каталога так,чтобы Git не узнал об этом. Эта функциональность встроена в сам фундамент Git’а и является важной составляющей его философии. Если информация потеряется при передаче или повредится на диске, Git всегда это выявит.
Чаще всего данные в Git только добавляются
Практически все действия, которые вы совершаете в Git’е, только добавляют данные в базу. Очень сложно заставить систему удалить данные или сделать что-то неотменяемое. Можно, как и в любой другой СКВ, потерять данные, которые вы ещё не сохранили, но как только они зафиксированы, их очень сложно потерять, особенно если вы регулярно отправляете изменения в другой репозиторий.
Три состояния файлов
Теперь внимание. Это самое важное, что нужно помнить про Git, если вы хотите, чтобы дальше изучение шло гладко. В Git’е файлы могут находиться в одном из трёх состояний: зафиксированном, изменённом и подготовленном. «Зафиксированный» значит, что файл уже сохранён в вашей локальной базе. К изменённым относятся файлы, которые поменялись, но ещё не были зафиксированы. Подготовленные файлы — это изменённые файлы, отмеченные для включения в следующий коммит.
Стандартный рабочий процесс с использованием Git’а выглядит примерно так:
- Вы вносите изменения в файлы в своём рабочем каталоге.
- Подготавливаете файлы, добавляя их слепки в область подготовленных файлов.
- Делаете коммит, который берёт подготовленные файлы и помещает их в каталог Git’а на постоянное хранение.
Установка GIT (Windows)
Установить Git в Windows очень просто. Просто скачайте дистрибутив и запустите его:
После установки у вас будет как консольная версия (включающая SSH-клиент, который пригодится позднее), так и стандартная графическая.
Первоначальная настройка Git
Теперь, когда Git установлен в Вашей системе, нужно настроить среду для работы с Git’ом под себя. Это необходимо сделать только один раз — при обновлении версии Git’а настройки сохранятся. Но вы можете поменять их в любой момент, выполнив те же команды снова.
В состав Git’а входит утилита git config, которая позволяет просматривать и устанавливать параметры, контролирующие все аспекты работы Git’а и его внешний вид.
Первое, что вам следует сделать после установки Git’а, — указать ваше имя и адрес электронной почты. Это важно, потому что каждый коммит в Git’е содержит эту информацию, и она включена в коммиты, передаваемые вами, и не может быть далее изменена (команды выполняются из командной строки):
Перейдите в каталог с проектом (создайте, если его еще нет).
Если добавить опцию —global , то эти настройки запишутся в настройки пользователя и будут действовать на все проекты. Мы выполняем эту команду без параметра —global , чтобы настройки касались только вашего проекта.
Перед началом работы с командами GIT определимся с сервером для центрального репозитория.
Выбор сервера для центрального репозитория
Есть два варианта:
- собственный сервер в локальной сети, обычно используется в крупных компаниях или из-за режима секретности (например, gitlab, mercurial-server)
- сервер в Сети, например github, bitbucket (atlassian), gitlab. На таких серверах обычно есть бесплатные аккаунты для публичных репозиториев (публичный репозиторий доступен всем), в последнее время в бесплатных аккаунтах появляется возможность создания и приватных репозиториев (с приватным репозиторием может работать только создатель (администратор) и пользователи, которых назначатет администратор. Администратор имеет полные права на репозторий, пользователи могут иметь права на запись или только на чтение). На сервере atlassian поддерживаются репозитории для git и mercurial, в бесплатном аккаунте есть возможность создавать приватные репозитории (количество не ограничено, но ограничено общее дисковое пространство под репозитории и количество разработчиков — не более 5). На гитхабе возможность создания бесплатных аккаунтов появилась совсем недавно (январь 2019 года), приватных репозиториев можно создать только 3.
Мы будем использовать локальный сервер GOGS, расположенный по адресу 192.168.0.153 Из-за коронавируса мы часто стали работать удаленно, поэтому заведите себе аккаунт на github.com (или другом, поддерживающем протокол GIT).
Базовые команды Git
Здесь рассмотрены базовые команды, необходимые вам для решения подавляющего большинства задач возникающих при работе с Git’ом. После изучения этой части вы научитесь настраивать и инициализировать репозиторий, начинать и прекращать версионный контроль файлов, а также подготавливать и фиксировать изменения. Мы также узнаем как настроить в Git’е игнорирование отдельных файлов или их групп, как быстро и просто отменить ошибочные изменения, как просмотреть историю вашего проекта и изменения между отдельными коммитами (commit), а также как отправлять (push) и получать (pull) изменения в/из удалённого (remote) репозитория.
Для создания Git-репозитория существуют два основных подхода. Первый подход — импорт в Git уже существующего проекта или каталога. Второй — клонирование уже существующего репозитория с сервера (этот вариант мы рассматривать не будем, т.к. некоторые программы не могут создать проект в существующем каталоге).
Создание репозитория в существующем каталоге
Если вы собираетесь начать использовать Git для существующего проекта, то вам необходимо перейти в каталог проекта и в командной строке ввести
Запоминать эти команды не нужно — они показываются в GIT-е при создании нового репозитория.
Эта команда создаёт в текущем каталоге новый подкаталог с именем .git содержащий все необходимые файлы репозитория — основу Git-репозитория. На этом этапе ваш проект ещё не находится под версионным контролем.
Если вы хотите добавить под версионный контроль существующие файлы (в отличие от пустого каталога), вам стоит проиндексировать эти файлы и осуществить первую фиксацию изменений. Осуществить это вы можете с помощью нескольких команд git add указывающих индексируемые файлы, а затем commit:
Мы разберём, что делают эти команды чуть позже. На данном этапе, у вас есть Git-репозиторий с добавленными файлами и начальным коммитом.
Клонирование существующего репозитория
Если вы хотите получить копию существующего репозитория Git, например, проекта, в котором вы хотите поучаствовать, то вам нужна команда git clone .
Клонирование репозитория осуществляется командой git clone [url]. Для примера склонируем репозиторий с этими лекциями:
Эта команда создаёт каталог с именем OAP, инициализирует в нём каталог .git, скачивает все данные для этого репозитория и создаёт (checks out) рабочую копию последней версии. Если вы зайдёте в новый каталог OAP, вы увидите в нём файлы, пригодные для работы и использования.
Если вы хотите клонировать репозиторий в каталог, отличный от OAP, то можно это указать в следующем параметре командной строки:
Эта команда делает всё то же самое, что и предыдущая, только результирующий каталог будет назван mydir .
Запись изменений в репозиторий
Итак, у вас имеется Git-репозиторий и рабочая копия файлов для некоторого проекта. Вам нужно делать некоторые изменения и фиксировать “снимки” состояния (snapshots) этих изменений в вашем репозитории каждый раз, когда проект достигает состояния, которое вам хотелось бы сохранить (обычно рекомендуют фиксировать каждое атомарное изменение, т.е. функцию, класс или законченный алгорим).
Каждый файл в вашем рабочем каталоге может находиться в одном из двух состояний: под версионным контролем (отслеживаемые) и нет (неотслеживаемые). Отслеживаемые файлы — это те файлы, которые были в последнем слепке состояния проекта; они могут быть неизменёнными, изменёнными или подготовленными к коммиту. Неотслеживаемые файлы — это всё остальное, любые файлы в вашем рабочем каталоге, которые не входили в ваш последний слепок состояния и не подготовлены к коммиту. Когда вы впервые клонируете репозиторий, все файлы будут отслеживаемыми и неизменёнными, потому что вы только взяли их из хранилища и ничего пока не редактировали.
Как только вы отредактируете файлы, Git будет рассматривать их как изменённые, т.к. вы изменили их с момента последнего коммита. Вы индексируете эти изменения и затем фиксируете все индексированные изменения, а затем цикл повторяется.
Определение состояния файлов
Основной инструмент, используемый для определения, какие файлы в каком состоянии находятся — это команда git status . Если вы выполните эту команду сразу после клонирования, вы увидите что-то вроде этого:
Это означает, что у вас чистый рабочий каталог, другими словами — в нём нет отслеживаемых изменённых файлов. Git также не обнаружил неотслеживаемых файлов, в противном случае они бы были перечислены здесь. И наконец, команда сообщает вам на какой ветке (branch) вы сейчас находитесь. Пока что это всегда ветка master — это ветка по умолчанию.
Предположим, вы добавили в свой проект новый файл, простой файл README. Если этого файла раньше не было, и вы выполните git status, вы увидите свой неотслеживаемый файл вот так:
Понять, что новый файл README неотслеживаемый можно по тому, что он находится в секции «Untracked files» в выводе команды status. Статус «неотслеживаемый файл», по сути, означает, что Git видит файл, отсутствующий в предыдущем снимке состояния (коммите); Git не станет добавлять его в ваши коммиты, пока вы его явно об этом не попросите. Это предохранит вас от случайного добавления в репозиторий сгенерированных бинарных файлов или каких-либо других, которые вы и не думали добавлять. Мы хотели добавить README, так давайте сделаем это.
Отслеживание новых файлов
Для того чтобы начать отслеживать (добавить под версионный контроль) новый файл, используется команда git add . Чтобы начать отслеживание файла README, вы можете выполнить следующее:
Если вы снова выполните команду git status , то увидите, что файл README теперь отслеживаемый и индексированный:
Вы можете видеть, что файл проиндексирован по тому, что он находится в секции “Changes to be committed”. Если вы выполните коммит в этот момент, то версия файла, существовавшая на момент выполнения вами команды git add, будет добавлена в историю снимков состояния. Как вы помните, когда вы ранее выполнили git init, вы затем выполнили git add (файлы) — это было сделано для того, чтобы добавить файлы в вашем каталоге под версионный контроль. Команда git add принимает параметром путь к файлу или каталогу, если это каталог, команда рекурсивно добавляет (индексирует) все файлы в данном каталоге.
Зачастую, имеется группа файлов, которые вы не только не хотите автоматически добавлять в репозиторий, но и видеть в списках неотслеживаемых. К таким файлам обычно относятся автоматически генерируемые файлы (различные логи, результаты сборки программ и т.п.). В таком случае, вы можете создать в корне проекта файл .gitignore с перечислением шаблонов соответствующих таким файлам. Вот пример файла .gitignore:
Первая строка предписывает Git’у игнорировать любые файлы заканчивающиеся на .log — файлы логов. Вторая строка предписывает игнорировать все файлы расширение которых начинается на тильду (
), такие расширения обычно используются для обозначения временных файлов. Вы можете также включить каталоги log, tmp. Хорошая практика заключается в настройке файла .gitignore до того, как начать серьёзно работать, это защитит вас от случайного добавления в репозиторий файлов, которых вы там видеть не хотите.
К шаблонам в файле .gitignore применяются следующие правила:
- Пустые строки, а также строки, начинающиеся с #, игнорируются.
- Можно использовать стандартные glob шаблоны.
- Можно заканчивать шаблон символом слэша (/) для указания каталога.
- Можно инвертировать шаблон, использовав восклицательный знак (!) в качестве первого символа.
Glob-шаблоны представляют собой упрощённые регулярные выражения используемые командными интерпретаторами. Символ * соответствует 0 или более символам; последовательность [abc] — любому символу из указанных в скобках (в данном примере a, b или c); знак вопроса (?) соответствует одному символу; [0-9] соответствует любому символу из интервала (в данном случае от 0 до 9).
Вот ещё один пример файла .gitignore:
Просмотр индексированных и неиндексированных изменений
Если результат работы команды git status недостаточно информативен для вас — вам хочется знать, что конкретно поменялось, а не только какие файлы были изменены — вы можете использовать команду git diff .
Подробно на этой команде останавливаться не будем, так как многие современные средства разработки (IDE — Интегрированная среда разработки) имеют встроенную поддержку команд GIT и изменения в файлах там наглядно отображаются.
Теперь, когда ваш индекс настроен так, как вам и хотелось, вы можете зафиксировать свои изменения. Запомните, всё, что до сих пор не проиндексировано — любые файлы, созданные или изменённые вами, и для которых вы не выполнили git add после момента редактирования — не войдут в этот коммит. Они останутся изменёнными файлами на вашем диске. В нашем случае,когда вы в последний раз выполняли git status , вы видели что всё проиндексировано, и вот, вы готовы к коммиту. Простейший способ зафиксировать изменения — это выполнить команду git commit . Так же можно воспользоваться встроенными в IDE средствами.
Эта команда откроет выбранный вами текстовый редактор. (Редактор устанавливается системной переменной $EDITOR, вы можете установить ваш любимый с помощью команды git config core.editor).
В редакторе будет отображён следующий текст (это пример окна Vim’а):
Вы можете видеть, что комментарий по умолчанию для коммита содержит закомментированный результат работы («выхлоп») команды git status и ещё одну пустую строку сверху. Вы можете удалить эти комментарии и набрать своё сообщение или же оставить их для напоминания о том, что вы фиксируете. (Для ещё более подробного напоминания, что же именно вы поменяли, можете передать аргумент -v в команду git commit . Это приведёт к тому, что в комментарий будет также помещена дельта/diff изменений, таким образом вы сможете точно увидеть всё, что сделано.) Когда вы выходите из редактора, Git создаёт для вас коммит с этим сообщением (удаляя комментарии и вывод diff’а).
Можно сразу набрать свой комментарий к коммиту в командной строке вместе с командой commit, указав его после параметра -m:
Итак, вы создали свой первый коммит! Вы можете видеть, что коммит вывел вам немного информации о себе: на какую ветку вы выполнили коммит (master), какая контрольная сумма SHA-1 у этого коммита (463dc4f), сколько файлов было изменено, а также статистику по добавленным/удалённым строкам в этом коммите.
Запомните, что коммит сохраняет снимок состояния вашего индекса. Всё, что вы не проиндексировали, так и торчит в рабочем каталоге как изменённое; вы можете сделать ещё один коммит, чтобы добавить эти изменения в репозиторий. Каждый раз, когда вы делаете коммит, вы сохраняете снимок состояния вашего проекта, который позже вы можете восстановить или с которым можно сравнить текущее состояние.
Для того чтобы удалить файл из Git’а, вам необходимо удалить его из отслеживаемых файлов (точнее, удалить его из вашего индекса) а затем выполнить коммит. Это позволяет сделать команда git rm, которая также удаляет файл из вашего рабочего каталога, так что вы в следующий раз не увидите его как “неотслеживаемый”.
Если вы просто удалите файл из своего рабочего каталога, он будет показан в секции “Changes not staged for commit” (“Изменённые но не обновлённые” — читай не проиндексированные) вывода команды git status :
Затем, если вы выполните команду git rm , удаление файла попадёт в индекс:
После следующего коммита файл исчезнет и больше не будет отслеживаться. Если вы изменили файл и уже проиндексировали его, вы должны использовать принудительное удаление с помощью параметра -f. Это сделано для повышения безопасности, чтобы предотвратить ошибочное удаление данных, которые ещё не были записаны в снимок состояния и которые нельзя восстановить из Git’а.
Другая полезная штука, которую вы можете захотеть сделать — это удалить файл из индекса, оставив его при этом в рабочем каталоге. Другими словами, вы можете захотеть оставить файл на винчестере, и убрать его из-под бдительного ока Git’а. Это особенно полезно, если вы забыли добавить что-то в файл .gitignore и по ошибке проиндексировали, например, большой файл с логами, или кучу промежуточных файлов компиляции. Чтобы сделать это, используйте опцию —cached:
В команду git rm можно передавать файлы, каталоги или glob-шаблоны. Это означает, что вы можете вытворять что-то вроде:
Обратите внимание на обратный слэш (\) перед *. Он необходим из-за того, что Git использует свой собственный обработчик имён файлов вдобавок к обработчику вашего командного интерпретатора. Эта команда удаляет все файлы, которые имеют расширение .log в каталоге log/. Или же вы можете сделать вот так:
Эта команда удаляет все файлы, чьи имена заканчиваются на
Просмотр истории коммитов
После того как вы создадите несколько коммитов, или же вы склонируете репозиторий с уже существующей историей коммитов, вы, при желании, можете узнать, что же происходило с этим репозиторием. Наиболее простой и в то же время мощный инструмент для этого — команда git log .
По умолчанию, git log выводит список коммитов созданных в данном репозитории в обратном хронологическом порядке. То есть самые последние коммиты показываются первыми.
Работа с удалёнными репозиториями
Чтобы иметь возможность совместной работы над каким-либо Git-проектом, необходимо знать, как управлять удалёнными репозиториями. Удалённые репозитории — это модификации проекта, которые хранятся в интернете или ещё где-то в сети. Их может быть несколько, каждый из которых, как правило, доступен для вас либо только на чтение, либо на чтение и запись. Совместная работа включает в себя управление удалёнными репозиториями и помещение (push) и получение (pull) данных в и из них тогда, когда нужно обменяться результатами работы.
Отображение удалённых репозиториев
Чтобы просмотреть, какие удалённые серверы у вас уже настроены, следует выполнить команду git remote . Она перечисляет список имён-сокращений (алиасов) для всех уже указанных удалённых репозиториев. Если вы склонировали ваш репозиторий, у вас должен отобразиться, по крайней мере, origin — это имя по умолчанию, которое Git присваивает серверу, с которого вы склонировали.
Добавление удалённых репозиториев
Чтобы добавить новый удалённый Git-репозиторий под алиасом, к которому будет проще обращаться, выполните git remote add [алиас] [url] :
Теперь вы можете использовать в командной строке имя pb вместо полного URL. Например, если вы хотите извлечь (fetch) всю информацию, которая есть в удаленном репозитории, но нет в вашем, вы можете выполнить git fetch pb .
Как вы только что узнали, для получения данных из удалённых проектов, следует выполнить:
Данная команда связывается с указанным удалённым проектом и забирает все те данные проекта, которых у вас ещё нет.
Когда вы клонируете репозиторий, команда clone автоматически добавляет этот удалённый репозиторий под именем origin. Таким образом, git fetch origin извлекает все наработки, отправленные (push) на этот сервер после того, как вы склонировали его (или получили изменения с помощью fetch). Важно отметить, что команда fetch забирает данные в ваш локальный репозиторий, но не сливает их с какими-либо вашими наработками и не модифицирует то, над чем вы работаете в данный момент. Вам необходимо вручную слить эти данные с вашими, когда вы будете готовы.
Если вы хотите слить новые данные с вашими, то вы можете использовать команду git pull . Она автоматически извлекает и затем сливает данные из удалённой ветки в вашу текущую ветку. Этот способ может для вас оказаться более простым или более удобным. К тому же по умолчанию команда git clone автоматически настраивает вашу локальную ветку master на отслеживание удалённой ветки master на сервере, с которого вы клонировали (подразумевается, что на удалённом сервере есть ветка master). Выполнение git pull , как правило, извлекает (fetch) данные с сервера, с которого вы изначально склонировали, и автоматически пытается слить (merge) их с кодом, над которым вы в данный момент работаете.
Когда вы хотите поделиться своими наработками, вам необходимо отправить (push) их в главный репозиторий. Команда для этого действия простая: git push [удал. сервер] [ветка] . Чтобы отправить вашу ветку master на сервер origin (повторимся, что клонирование, как правило, настраивает оба этих имени автоматически), вы можете выполнить следующую команду для отправки наработок на сервер:
Эта команда срабатывает только в случае, если вы клонировали с сервера, на котором у вас есть права на запись, и если никто другой с тех пор не выполнял команду push. Если вы и кто-то ещё одновременно клонируете, затем он выполняет команду push, а затем команду push выполняете вы, то ваш push точно будет отклонён. Вам придётся сначала вытянуть (pull) их изменения и объединить с вашими. Только после этого вам будет позволено выполнить push.
К этому моменту вы умеете выполнять все базовые локальные операции с Git’ом: создавать или клонировать репозиторий, вносить изменения, индексировать и фиксировать эти изменения, а также просматривать историю всех изменений в репозитории. Дальше мы рассмотрим самую убийственную особенность Git’а — его модель ветвления.
Ветвление в Git
Почти каждая СКВ имеет в какой-то форме поддержку ветвления. Ветвление означает, что вы отклоняетесь от основной линии разработки и продолжаете работу, не вмешиваясь в основную линию.
Пример ветвления из реального проекта:
Глубоко в теорию я не полезу, только опишу главные команды.
git checkout [название ветки]
Эта команда переключает ваш локальный репозитория на указанную ветку.
Тут нужно учитывать, что если в текущей ветке есть измененные файлы, то поменять ветку нельзя. Нужно либо зафиксировать изменения командами git add и git commit , либо отложить их командой git stash . Учитывая, что фиксировать нужно законченные действия, второй вариант бывает предпочтительнее.
git stash
Команда git stash сохраняет незафиксированные изменения (подготовленные и неподготовленные) в отдельном хранилище, чтобы вы могли вернуться к ним позже. Затем происходит откат до исходной рабочей копии.
Теперь вы можете вносить изменения, создавать новые коммиты, переключаться между ветками и выполнять другие операции Git. По необходимости отложенные изменения можно будет применить позже.
Отложенные изменения сохраняются в локальном репозитории Git и не передаются на сервер при выполнении команды push.
Чтобы вернуть отложенные изменения нужно выполнить команду git stash pop .
При извлечении отложенных изменений они удаляются из набора и применяются к рабочей копии.
Вы также можете применить изменения к рабочей копии без удаления из набора отложенных изменений. Для этого воспользуйтесь командой git stash apply
Это полезно, если вам нужно применить одни и те же отложенные изменения к нескольким веткам.
Вы можете создать несколько наборов отложенных изменений. Команду git stash можно выполнить несколько раз, после чего у вас будет возможность просмотреть список наборов с помощью команды git stash list .
Рекомендуем добавлять к отложенным изменениям описание в качестве подсказки. Для этого используется команда git stash save «сообщение»
По умолчанию команда git stash pop применяет последний набор отложенных изменений: stash@
Если вам нужно применить определенный набор ранее отложенных изменений, укажите его идентификатор в качестве последнего аргумента.
Создание новой ветки
Просто создать ветку можно командой git branch название_ветки .
После этого вы можете продолжить работу в текущей ветке или переключитсья на созданную командой git checkout название_ветки .
Можно сразу создать ветку и переключиться на неё командой git checkout -b название_ветки .
Завершение работы с веткой
Когда работа над новой фичей (в ветке) закончена, необходимо перенести изменния в основную ветку. Для этого используется команда git merge название_ветки . Т.е. Вы сначала переключаетесь на ту ветку, в которую хотите слить изменения, а затем объединяете их:
Если кто-то менял те же файлы что и Вы (возможно даже Вы сами что-то меняли в другой ветке) и GIT не может автоматически определить куда вставить изменения, то возникнет ошибка слияния.
Для разрешения конфликта слияния вы должны либо выбрать один из вариантов (старая ветка или новая) или объединить оба варианта.
В корне репозитория принято размещать файл readme.md, в котором описывается что это за репозиторий, для чего он нужен, инструкции по установке, если это необходимо.
Расширение *.md как раз и означает, что файл в формате MarkDown.
Markdown (произносится маркда́ун) — облегчённый язык разметки, созданный с целью обозначения форматирования в простом тексте, с максимальным сохранением его читаемости человеком, и пригодный для машинного преобразования (на GitHub-е как раз и отображается преобразованный текст)
Раз это простой текст, то редактировать его можно даже в блокноте.
Текст с выделением
*выделение* (например, курсив)
**сильное выделение** (например, полужирное начертание)
_**комбинация**_ курсива и полужирного начертания
Причем без разницы в каком порядке использовать символы * и _
Выделяется знаком апострофа «`», может быть как внутри строки
Так можно оформлять не только программный код, но и любой текст, в котором нужно сохранить оригинальное форматирование. Дело в том, что MarkDown, как и практически любой язык верстки обрезает пустые строки и пробелы
- 1. Нумерованные
- 2. Причем порядок цифр
- 9. На результат не влияет
- обычные списки
- с любым уровнем вложенности
- можно комбинировать нумерованные и не нумерованные списки
Создание заголовков производится путём помещения знака решетки перед текстом заголовка. Количество знаков «#» соответствует уровню заголовка. Поддерживается 6 уровней заголовков.
# Заголовок первого уровня
### Заголовок третьего уровня
###### Заголовок шестого уровня
Любой элемент разметки (текст, список, картинка) могут быть помечены как цитата, если добавить в начале строки знак «>»
Ссылки на внешние ресурсы
Ссылки внутри документа
В качестве «якоря» может выступать заголовок или html-тег <a> (но это уже нетривиальное использование разметки)
Ссылки внутри репозитория
столбец 1 столбец 2 1 sfbvstb 2 sbstbn Как это выглядит в разметке (обратите внимание, содержимое столбцов можно центрировать или выравнивать по правому краю):
Если нужно разместить фотографию, скриншот или сложную схему, то можно добавить изображение
Ссылка может быть и на изображение расположенное в репозитории

Такая система фиксирует изменения, что позволяет вам в случае чего откатиться к любой предыдущей версии файла. Кроме отката изменений, система контроля версий позволяет сравнивать версии одного и того же файла, чтобы найти в нем изменения, видеть, кто эти изменения внес, когда это было сделано и что могло вызвать проблему.
Чтобы сформировать у вас интуитивное понимание, приведу пример. Представьте себе, что вы разрабатываете голосового помощника для мобильных устройств. Ваше приложение уже выпущено в Play Market и в AppStore и пользуется успехом. Теперь вам захотелось добавить в него новую функцию: таймер. Вы пишите код, загружаете обновление в Play Market и AppStore, но внезапно вы узнаете от пользователей, что все сломалось. Теперь, чтобы исправить ошибку, вам нужно пересматривать весь код, чтобы вспомнить, что вы изменяли, и убирать это.
Такой процесс займет очень много сил и времени, а пользователей оставит недовольными. Вам бы очень помогла система контроля версий. Вы бы загрузили в нее файлы с кодом до внесения изменений, а после обнаружения ошибки, откатились бы к ним за считанные секунды. Функция отката изменений позволила бы вам оперативно загрузить в магазины старую версию приложения, которая работает без ошибок.
2 Зачем нужен контроль версий?
Понятно, что проект для команды — это бесценные знания, накопленные за все время его существования, и никому бы не хотелось, чтобы с ними что-то случилось. Система контроля версий защищает эти накопления от человеческого фактора, непредвиденных последствий и разных форс-мажоров.
Обычно, работая в команде, каждый разработчик трудится над какой-то своей частью проекта: создает новые функции, оптимизирует уже существующие, исправляет ошибки в уже написанном коде. Сам проект обычно организован в виде дерева файлов. Контроль версий помогает сотрудникам одновременно работать над проектом, отслеживать, кто какие изменения внес, и избегать при этом различных конфликтов (например, когда два человека изменят один и тот же файл по-разному).
Помимо этого, как уже было сказано выше, любое изменение кода может привести к непредвиденным последствиям и сломать весь проект вообще. Система контроля версий защищает и от этого.
3 Разновидности архитектур VCS
3.1. Локальная система контроля версий
Вы спросите: почему нельзя просто сохранять файл под разными именами, а затем открывать нужный? Да, так делать можно, но это вызовет массу проблем. Вы можете забыть, какой файл содержит итоговую версию, можете запутаться в миллионе одинаковых файлов, отличающихся парой строк кода. Вы не сможете быстро сравнить две версии, чтобы посмотреть, какие изменения были внесены.
Для решения этих проблем была придумана локальная система контроля версий. Схематически она представляет из себя следующее:

Из рисунка видно, что есть несколько версий одного и того же файла. А сам файл сейчас находится в состоянии третьей версии.
Одной из самых популярных локальных систем контроля версий на сегодняшний день (не считая Git) остается система RCS. Она работает по принципу сохранения изменений в ваших файлах. То есть она хранит не целую новую версию, а только указания к изменению первоначального файла. Например, «добавить к предыдущей версии строку import math «. Таким образом, последовательно изменяя файл, система воссоздает любую из его версий.
Подытожим:
Локальные VCS хранятся у вас на компьютере. Пример локальной VCS — RCS — одна из первых систем контроля версий, разработанная в 1985 году.Составим список преимуществ и недостатков локальных VCS.
Преимущества:
1. Позволяет хранить историю изменения файлов локально, без интернета.
2. Вы независимы от сторонних серверов.Недостатки:
1. Вы можете потерять все файлы, если с вашем компьютером что-то случится.
2. Вы не можете работать в команде, поскольку репозиторий доступен только вам.3.2. Централизованная система контроля версий
Как было сказано выше, одна из проблем, с которой вы столкнетесь, работая в команде разработчиков — это то, что вам нужно делиться файлами (и их версиями) с другими разработчиками.
Например, чтобы старший разработчик проверил ваш код на ошибки, перед тем, как дать вам разрешение на внесение изменений в рабочий файл. Для решения этой проблемы была придумана централизованная система контроля версий. Схематически она устроена так:

Из рисунка видно, что есть один сервер с сохраненными версиями всех файлов, а разработчики обращаются к нему за файлами.
Такими системами были очень популярные в свое время CVS, Subversion и Perforce. Долгое время такой тип системы контроля версий считался стандартом. Такая система довольно удобна с точки зрения руководства компании. Она позволяет им следить, кто и чем занимается в текущий момент, позволяет настроить: кому какие файлы можно редактировать, а кому — нельзя.
Тем не менее, централизованная система контроля версий имеет множество недостатков. Если сервер отключится на несколько часов, то работа целой компании будет парализована: никто не сможет сохранять версии файлов с кодом.
Если будет поврежден жесткий диск сервера, на котором хранятся данные, то восстановить их не удастся (если только не были сделаны копии), и вся работа будет потеряна.
В этом плане такая система мало чем отличается от локальной: если вы храните все данные проекта только на одной машине, вы рискуете потерять все из-за непредвиденного сбоя в работе этой машины.
Кроме того, поскольку вы не храните никаких данных локально, вам нужен бесперебойный высокоскоростной интернет на протяжении целого дня, чтобы скачивать и загружать данные с сервера. Это, конечно, не проблема, но однозначно минус.
Подытожим:
Централизованная VCS хранит все данные на сервере, а сотрудники получают к ним доступ.Примерами удаленных систем контроля версий являются CVS, Subversion и Perforce.
Преимущества централизованных VCS:
1. Вы можете работать в команде с другими разработчиками.
2. Ваше начальство видит, чем вы занимаетесь.
3. У администратора есть четкий контроль, кто и что может делать. Администрировать центральную VCS намного проще, чем локальные на каждой машине.Недостатки централизованных VCS:
1. Все данные хранятся только на одном сервере. Если он выключится, то работу всей компании парализует.
2. Если с сервером что-то случится, а копий данных нет, то весь проект может быть потерян.
3. Для работы необходим хороший интернет на протяжении целого дня.Что такое система контроля версий и как ей пользоваться
В арсенале веб-разработчика много полезных инструментов, которые позволяют автоматизировать решение разных задач. Без них время работы сильно увеличивается. А продуктивность падает, потому что приходится вручную делать то, что можно решить с помощью десктопных программ или браузерных расширений.
В статье поговорим о системе контроля версий. Разберёмся, зачем она нужна, как пользоваться инструментом и расскажем о популярных ошибках, которые допускают новички и опытные программисты.
Что такое система контроля версий
Система контроля версий — программное обеспечение, которое обеспечивает командную работу в рамках одного или нескольких проектов. Команда разработчиков взаимодействует с консольным или браузерным инструментом для выгрузки кода на сервер, скачивания его на рабочий компьютер и изменения структуры.
Новичкам обычно сложно вникнуть в технические подробности работы системы контроля версий, поэтому мы постараемся объяснить суть простым языком. Не старайтесь сразу погружаться в термины, пользы от этого будет мало.
Представьте, что играете в компьютерную игру. По мере прохождения миссий происходит сохранение контрольных точек. Даже если выключить компьютер и зайти в приложение через несколько дней или месяцев, прогресс не потеряется. В любой момент можно выбрать контрольную точку и пройти миссию заново.

Система контроля версий работает по аналогичной схеме. Она хранит все версии проекта и обеспечивает к ним доступ. Любой член команды может взаимодействовать с основной «веткой» проекта или создавать новые.
Самой популярной системой контроля версий является 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 или аналоги.
Как работать с сайтом и не поломать его, или Для чего нужен Git?
Сразу оговорюсь, что эта статья не техническая, и я попытался максимально просто объяснить необходимость использования системы контроля версий на сайте.
Что такое система контроля версий и зачем она вам нужна
Это система, регистрирующая изменения файлов на сайте, которая позволяет вести удобную совместную разработку и дает возможность вернуться к предыдущим или альтернативным версиям сайта. Увеличивает безопасность, т.к. нет необходимости давать доступ к рабочему сайту.
Зачем нужна система контроля версиями
- С помощью нее можно легко отследить ошибки.
- Все изменения сохраняются (когда, кем и что было сделано).
- Исключена поломка сайта.
- Возможность легко откатывать изменения до любой версии сайта.
- Возможность использовать как простой инструмент для переноса данных с сайта разработки на рабочий сайт.
Как происходят изменения на сайте без контроля версий
Как показывает практика, у большинства сайтов сейчас работа построена следующим образом: если нужно сделать какие-то правки на сайте, то они делаются сразу на нем, считается, что так быстрее. Некоторые, более продвинутые, делают эти же правки на тестовой версии, но в этом случае есть возникают сложности с актуализацией файлов. В случае ошибки – часто просто разворачивается старый, но рабочий бекап. Однако все изменения затрутся и работу придется выполнять снова.

Вернемся к сложностям использования тестовой версии. Безусловно, она дает некую безопасность, но приходится выполнять много ручной работы, а человеческий фактор всегда создает проблемы:
- Если изменений было много, программисту придется собрать список всех измененных файлов. Но человек никогда ничего не забывает, все в порядке.
- Программист работает в паре с другим программистом или верстальщиком и волей судьбы правят один файл? Не беда, тот, кто сохранился последний, тот и победил, а тем временем коллега мучается от осознания того, что всю его работу только что затерли.
- Разработчик молодец и закончили огромную работу на сайте. Теперь нужно просто заменить все файлы на боевом сайте на новые. Но внезапно ему сообщают, что на сайте только что закончили работу по настройке ЧПУ, и, скорее всего, код разработчика работать не будет.
- Даже если ошибка всплывет только в понедельник, программист без проблем вспомнит, в какой строчке кода сделал ошибку, их там всего-то несколько сотен тысяч.
В итоге простой перенос уже сделанной работы занимает чуть больше времени.
Самый простой и безопасный способ решения этих проблем – использование системы контроля версий, которую нужно настроить на сайте один раз.
Как же работает система контроля версий?
Каждое логически завершенное действие программиста или верстальщика фиксируется как новая версия сайта. В результате чего сохраняется история изменения файлов и можно с легкостью переключаться между версиями и возвращать сайт к нужному состоянию.
В качестве системы контроля версий используем git. Сначала необходимо установить его на сервере. Для этого обязательно нужно иметь SSH-доступ. Кроме того, потребуется удаленный репозиторий. Он точно такой же, как на вашем сайте, но находится в другом месте, это позволяет работать с ним и рабочему, и тестовому сайту на равных.
Существуют веб-сервисы для хостинга IT-проектов, например, github.com и bitbucket.org, оба имеют бесплатные версии, в которых есть ограничения на количество пользователей или приватных репозиториев. Но мы используем бесплатную альтернативу – GitLab.
Как работать с git?
Для каждой задачи создаем отдельную ветку разработки. Это позволит другим программистам работать с сайтом в своей ветке, выполняя свои задачи, не мешая вашей работе. Имя ветки обычно содержит номер задачи и краткое описание.

Выполнение логически завершенной задачи или части задачи фиксируется в системе контроля версий с коротким комментарием. Другие разработчики смогут быстро понять, что было сделано.
Для того чтобы перенести данные, нужно отправить их одной командой на удаленный репозиторий.
git push origin master
Далее вебхук подхватит команду, запустит скрипт на рабочем сайте и автоматически обновит файлы. Т.е. разработчикам даже не нужен доступ к сайту.
Вебхуки (WebHooks) – это уведомление сторонних приложений посредством отправки на них уведомлений о произошедших событиях.
В командной работе перед отправкой на рабочий сайт может понадобиться согласование с ведущим разработчиком проекта. Поэтому доступ к основной ветке следует запретить. А слияние с ней будет происходить с помощью запросов (merge request).
Ведущий разработчик проверяет код, может внести правки или отправить задачу на доработку. Если все в порядке, принимает код, который с помощью вебхука отправляется на рабочий сайт.
А вот схема работы процесса в одной картинке:

Автоматический деплой с помощью вебхука
После слияния ветки срабатывает вебхук, запускающий на рабочем сайте код, который в свою очередь автоматически обновляет содержимое сайта, выполняя две простые команды:
1. Забирает все изменения из удаленного репозитория
git fetch —all2. Обновляет файлы до состояния, зафиксированном на удаленном репозитории, при этом удаляя все изменения на сайте, которые не были зафиксированы.
git reset —hard origin/master
Почему нужно удалять незафиксированные изменения?
Если коротко – исключить возможность конфликтов.
Конфликты возникают, когда произошли изменения в одном и том же файле, и при слиянии (merge) git не может верно решить, как правильно объединить файлы. Если одновременно редактировалась одна строка, то возникает конфликт. Программно невозможно решить, какая из версий должна быть на сайте.
Вывод
Если на вашем сайте одновременно работают несколько программистов, и вы хотите исключить ошибки и ускорить работу, то нужно использовать в своей работе систему контроля версий.
- с любым уровнем вложенности