Система контроля версий GIT

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

Особенности системы Git

Главной особенностью Git, заметно отличающей её от многих других СКВ является то, что она позволяет скопировать хранилище проекта со всей историей изменений и информацией об этих изменениях и работать с проектом отдельно. Git не имеет единого централизованного хранилища, но при этом эффективно отслеживает и контролирует и облегчает работу над проектом.

Благодаря возможностям Git можно, скопировав проект к себе на локальную машину, сколько угодно и как угодно вносить в него изменения в процессе работы над ним. В итоге, когда нужно будет объединить результаты работы (в том числе и от других разработчиков) в независимый общий проект, Git легко с этим справится. В случае сложных коллизий всегда можно вернуть предшествующее состояние проекта вне зависимости от того, сколько и каких было сделано изменений и итераций разработки. Хотя такие ситуации довольно редки в силу продуманной логики работы Git.

Ещё одним достоинством Git является интеллектуальная система сжатия данных, позволяющая существенно экономить на затратах для хранения истории изменений. Поскольку Git очень эффективно отслеживает и объединяет изменения даже из локальных хранилищ, это даёт возможность использовать эту систему не только для разработки (для чего она изначально была разработана), но и для задач по системному администрированию.

Установка и настройка

Для установки Git достаточно выполнить в командной консоли команду (для Ubuntu):

$ sudo apt-get install git

Для RPM-ориентированных систем, таких как Red Hat или CentOS:

$ sudo yum install git

Установка не должна вызывать проблем, поскольку практически для всех дистрибутивов Linux имеются поддерживаемые готовые пакеты в репозиториях дистрибутива.

Если же предоставляемый пакетным менеджером дистрибутива соответствующий пакет Git не соответствует требуемой версии или нужно использовать самую свежую на данный момент версию Git, которой пока нет для данного дистрибутива, то с официального сайта можно скачать архивы с исходным кодом Git и собрать пакет из них. Для этого случая в архиве с исходниками имеется файл INSTALL, содержащий подробные инструкции по сборке и установке Git.

Настройка Git начинается с указания некоторых данных о пользователе, который желает использовать эту СКВ — имя пользователя и электронный адрес:

$ git config --global user.name "John Silver"

$ git config --global user.email "jsilver@somedomain.org"

Изменения вносятся всегда от имени одного пользователя — root, поэтому так важно указывать идентификационную информацию, которая используется Git для связывания изменений с конкретным пользователем, несмотря на то, что фактически изменения делаются от root. Это сделано для простого использования Git без клонирования хранилищ для разных пользователей.

Указанные данные о пользователе Git хранятся в домашнем каталоге в файле .gitconfig, содержимое которого можно просмотреть либо текстовым редактором (nano, vi), либо специальной командой Git:

$ git config --list
user.name=John Silver
user.email=jsilver@somedomain.org

Теперь можно создать хранилище, которое будет включать в себя, к примеру, каталог /etc:

$ cd /etc
$ sudo git init
Initialized empty Git repository in /etc/.git/
$ sudo git add .
$ sudo git commit -m "Initial commit"
Created initial commit st34c48: Initial commit
2538 files changed, 259122 insertions(+), 0 deletions(-)
create mode 100644 .java/.systemPrefs/.system.lock
create mode 100644 .java/.systemPrefs/.systemRootModFile

Инфраструктура нового хранилища создаётся командой git init в каталоге /etc/.git, далее всё содержимое каталога /etc добавляется в список отслеживания изменений Git командой git add . — этот список будет использоваться для выполнения последующих коммитов (синхронизаций). Команда git commit проведёт начальную синхронизацию хранилища и с помощью ключа -m добавит к этому действию сопровождающее сообщение. Если опускать опцию -m, то Git автоматически запустит текстовый редактор для добавления комментария.

Использование Git

Для того, чтобы внести изменения в хранилище проекта, нужно сообщить об этом системе Git уже известной командой git commit, например:

$ sudo touch readme.txt
$ sudo git add readme.txt
[master 825d300] Added readme.txt file
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 readme.txt
$ sudo git commit -m "Added readme.txt file"
Created commit 901bd39:  Added readme.txt file
1 files changed, 1 insertions(+), 0 deletions(-)

В данном случает коммит сделает только то, что в нём указано — обновит хранилище новым файлом readme.txt, даже если имеются другие изменённые файлы, потому как в команде git commit явно указано имя конкретного файла. Для указания нескольких файлов для коммита можно их просто перечислить.

Если точно неизвестно, какие файлы были изменены, можно выполнить команду git commit -a, которая обновит хранилище только теми файлами, которые были изменены. Но тут нужно помнить о двух вещах:

  • Во-первых, если имеется какой-либо файл, стоящий «на учёте» у Git и в то же время этот же файл может модифицироваться самой системой (не Git), т. е. являться служебным, то во время исполнения коммита с ключом -a, этот файл, естественно будет обработан и соответствующая информация также будет обновлена в хранилище. Если в будущем придётся проводить «откат» предыдущего состояния, то будет возвращена и соответствующая предыдущая версия этого служебного файла, что может привести к сбою конфигурации, ведь этот файл является служебным, поддерживается системой и изменения в нём она (система) делает не просто так.
  • Во-вторых, коммит с ключом -a проверяет изменения только тех файлов, которые имеются на учёте, т. е. в так называемом списке «стадийности» Git. Любые другие новые или изменённые файлы учитываться ключом -a не будут.

Чтобы избежать вышеописанных подводных камней стоит оценивать ситуацию вручную используя команду git status. Эта команда выведет информацию о модифицированных и новых файлах. К примеру, если был отредактирован файл readme.txt, а также установлен новый демон, конфигурация для которого содержится в файле /etc/somedaemon/somedaemon.conf, то тогда вывод команды git status может быть следующим:

$ sudo git status
# On branch master
# Changed but not updated:
# (use "git add <file>..." to update what will be committed)
#
#  modified: readme.txt
#  modified: passwd
#Untracked files:
# (use "git add <file>..." to include in what will be committed)
#
#  somedaemon/
no changes added to commit (use "git add" and/or "git commit -a")

Новый файл somedaemon.conf не видим для Git  внутри поддиректории somedaemon. Файл readme.txt ожидаемо в списке изменённых, однако в этом же списке и файл passwd, который мог быть модифицирован скриптом установки нового демона somedaemon, либо изменения могли быть внесены одним из системных администраторов, который забыл внести соответствующие изменения в хранилище. Чтобы это выяснить, нужно выполнить команду git diff passwd, которая выведет информацию о реальных изменениях для интересующего файла passwd. Если, к примеру, файл passwd был изменён не в результате установки нового демона, т. е. недавних действий, а ещё как-то, то рекомендуется в данном случае выполнить отдельный для данного файла (passwd) коммит:

$ sudo git commit passwd -m "Checking in existing passwd changes"
Created commit 6f7853c: Checking in existing passwd changes
1 files changed, 1 insertions(+), 0 deletions(-)

Когда нужно исключить какие-либо файлы из списка «стадийности» Git, нужно сначала удалить файлы из хранилища:

$ sudo git rm --cached hosts
rm 'hosts'

и далее добавить файл в список игнорирования Git, содержащийся в файле .gitignore:

$ sudo sh -с "echo hosts >> .gitignore"

Опция —cached в первой команде не даёт Git удалить файл из файловой системы, но исключает его из своего образа хранилища. Не рекомендуется опускать эту опцию во избежание полного удаления файлов.

Далее нужно выполнить коммит со всеми сделанными изменениями с помощью команды git commit -a или же поступить по-другому — дать команду git add . — это оправдано в данном случае, поскольку будет создан новый образ хранилища, соответствующий текущему каталогу, а эффект будет тот же:

$ sudo git add .
$ sudo git commit -m "Installed somedaemon; added readme.txt file"
Created commit 32978e6: Installed foobard; added RAID spare
3 files changed, 2 insertions(+), 1 deletion(-)
create mode 100644 .gitignore
create mode 100644 somedaemon/somedaemon.conf
delete mode 100644 hosts

Следует обратить внимание на то, что файл .gitignore теперь сам учитывается в списке «стадийности» Git. Также важно знать и о том, что Git не отслеживает реальные режимы доступа к файлам, их владельцев и дату/время модификации. Хотя и печатает в выводах соответствующие коды. Не следует использовать Git для восстановления файловых систем со сложной структурой, в которых для корректного функционирования очень важно соблюдение определённых атрибутов файлов.

Откат и сброс изменений в GIT

Если вы запороли проект, но еще не сделали commit, то сбросить изменения можно командой

git reset --hard HEAD

например создадим файл bad.txt

$sudo touch bad.txt
$git add bad.txt

Теперь удалим изменения

git reset --hard HEAD
HEAD is now at 825d300 Added readme.txt file

git сообщил нам что мы вернулись к коммиту «Added readme.txt file». Если теперь проверить директорию с помощью команды

ll | grep bad.txt

Мы увидим что файла bad.txt нет.

Можно вернуться назад на несколько коммитов, например команда

git reset --hard HEAD~3

Отменит 3 последних коммита.

Если вы просто хотите восстановить только один единственный файл, предположим hello.rb, то выполните git checkout

$ git checkout -- hello.rb
$ git checkout HEAD hello.rb

Первая команда восстановит hello.rb до версии хранящейся в индексе, и команда «git diff hello.rb» не покажет отличий. Вторая команда восстановит hello.rb до версии в ревизии HEAD, таким образом обе команды «git diff hello.rb» и «git diff —cached hello.rb» не покажут отличий.

Если вы нашли ошибку, пожалуйста, выделите фрагмент текста и нажмите Ctrl+Enter.

Понравилась статья? Поделиться с друзьями:
Добавить комментарий

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!:

ИТ Проффи

Сообщить об опечатке

Текст, который будет отправлен нашим редакторам: