Зарегистрируйтесь для доступа к 15+ бесплатным курсам по программированию с тренажером

Введение в Git Основы Git

Видео может быть заблокировано из-за расширений браузера. В статье вы найдете решение этой проблемы.

Рекомендуем перейти в курс Введение в Git

Мы обновили этот курс — добавили новые темы, самостоятельные задания и практические упражнения. Посмотрите этот урок по ссылке: https://ru.hexlet.io/courses/intro_to_git/lessons/setup/theory_unit


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

Перед тем, как мы попробуем поработать с Git, стоит обратить внимание на один очень важный факт: несмотря на то, что интерфейс взаимодействия с этой СКВ очень схож с интерфейсом других систем, внутри Git все может очень сильно отличаться. И если вы уже были знакомы с такими системами, как, например, subversion, вам стоит абстрагироваться от имеющихся знаний. Это позволит вам быстрее проникнуться философией Git и не допускать ошибок в работе с ним.

Как только вы установите Git, вам захочется попробовать поработать с ним. Но лучше, в самом начале, выполнить несколько шагов, чтобы настроить среду для работы с Git'ом под себя. Это нужно сделать только один раз — при обновлении версии Git'а настройки сохранятся. Но вы можете поменять их в любой момент, выполнив те же команды снова. Большинству операций не потребуются эти настройки, однако вы не сможете сделать коммит без них.

В состав Git'а входит утилита git config, которая позволяет просматривать и устанавливать параметры, контролирующие все аспекты работы Git'а и его внешний вид.

Эти параметры могут быть сохранены в трёх местах:

  • Уровень системы: файл /etc/gitconfig содержит значения, общие для всех пользователей системы и для всех их репозиториев. Если при запуске git config указать параметр --system, то параметры будут читаться и сохраняться именно в этот файл.
  • Уровень пользователя: файл ~/.gitconfig хранит настройки конкретного пользователя. Этот файл используется при указании параметра --global.
  • Уровень проекта: конфигурационный файл в каталоге Git'а (.git/config) в том репозитории, где вы находитесь в данный момент. Эти параметры действуют только для данного конкретного репозитория. Настройки на каждом следующем уровне подменяют настройки из предыдущих уровней, то есть значения в .git/config перекрывают соответствующие значения в /etc/gitconfig.

В системах семейства Windows Git ищет файл .gitconfig в каталоге $HOME (C:\Documents and Settings\$USER или C:\Users\$USER для большинства пользователей). Кроме того Git ищет файл /etc/gitconfig, но уже относительно корневого каталога MSys, который находится там, куда вы решили установить Git, когда запускали инсталлятор.

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

git config --global user.name "Andrew Kumanyaev"
git config --global user.email me@zzet.org

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

Вы указали своё имя, и теперь можно выбрать текстовый редактор, который будет использоваться, если будет нужно набрать сообщение в Git'е. По умолчанию Git использует стандартный редактор вашей системы, обычно это Vi или Vim. Если вы хотите использовать другой текстовый редактор, например, Emacs, можно сделать следующее:

git config --global core.editor emacs

Я в своей работе использую Vim, поэтому верну обратно этот редактор

git config --global core.editor vim

Другая полезная настройка, которая может понадобиться — встроенная diff-утилита, которая будет использоваться для разрешения конфликтов слияния. Например, если вы хотите использовать vimdiff:

git config --global merge.tool vimdiff

Git умеет делать слияния при помощи kdiff3, tkdiff, meld, xxdiff, emerge, vimdiff, gvimdiff, ecmerge и opendiff, но вы можете настроить и другую утилиту.

Если вы хотите проверить используемые настройки, можете использовать команду git config --list, чтобы показать все, которые Git найдёт:

git config --list

user.name=Andrew Kumanyaev
user.email=me@zzet.org
color.status=auto
color.branch=auto
color.interactive=auto
color.diff=auto
...

Некоторые ключи (названия) настроек могут появиться несколько раз, потому что Git читает один и тот же ключ из разных файлов (например из /etc/gitconfig и ~/.gitconfig). В этом случае Git использует последнее значение для каждого ключа.

Также вы можете проверить значение конкретного ключа, выполнив git config {ключ}:

git config user.name

Andrew Kumanyaev

Для создания Git-репозитория существуют два основных подхода. Первый подход — импорт в Git уже существующего проекта или каталога. Второй — клонирование уже существующего репозитория с сервера.

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

git init

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

git status

В моем случае вывод команды такой:

On branch master

Initial commit

Untracked files:
  README.md

  nothing added to commit but untracked files present

Это означает, что я нахожуть в ветке, под названием master (ветка по-умолчанию), был выполнен автоматический коммит пустой директории (об этом говорит фраза “Initial commit”), и перечислен спискок файлов и директорий, которые сейчас не находятся под контролем Git. А также, сказано, что мы еще не подготовили данные для коммита.

К тому же, если выпонить комманду

git diff

результат ее выполнения будет пустым, то есть изменений нет. Это потому, что Git говорит об изменениях только тех файлов, которые находятся под его контролем.

Теперь внимание. Это самое важное, что нужно помнить про Git, если вы хотите, чтобы дальше изучение шло гладко. В Git'е файлы могут находиться в одном из трёх состояний: зафиксированном, изменённом и подготовленном.

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

Таким образом, в проектах, использующих Git, есть три части:

  • каталог Git'а (Git directory),
  • рабочий каталог (working directory),
  • область подготовленных файлов (staging area).

Каталог Git'а — это место, где Git хранит метаданные и базу данных объектов вашего проекта. Это наиболее важная часть Git'а, и именно она копируется, когда вы клонируете репозиторий с другого компьютера.

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

Область подготовленных файлов — это обычный файл, обычно хранящийся в каталоге Git'а, который содержит информацию о том, что должно войти в следующий коммит. Иногда его называют индексом (index), но в последнее время становится стандартом называть его областью подготовленных файлов (staging area).

Стандартный рабочий процесс с использованием Git'а выглядит примерно так:

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

Если рабочая версия файла совпадает с версией в каталоге Git'а, файл считается зафиксированным. Если файл изменён, но добавлен в область подготовленных данных, он подготовлен. Если же файл изменился после выгрузки из БД, но не был подготовлен, то он считается изменённым.

Если вы хотите добавить под версионный контроль существующие файлы (в отличие от пустого каталога), вам стоит проиндексировать эти файлы и осуществить первую фиксацию изменений. Осуществить это вы можете с помощью команды git add {индексируемый файл}, а затем git commit:

git add README
git commit -m 'initial project version'

В результате выполнения этих комманд я получил следующий вывод:

[master (root-commit) f234b65] Initial project version
  1 file changed, 6 insertions(+)
  create mode 100644 README.md

Вывод результатов выполнения команд в Git крайне лаконичен и информативен. В данном случае было сказано что мы выполнили коммит в ветку “master”, этот коммит является первым (root-commit), хеш коммит (его краткая запись) - “f234b65”, commit-message - “Initial project version”, статистика о добавленной информации: суммарное количество измененных файлов, добавленных и удаленных строк в них, а также перечень созданных файлов.

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

Механизм, используемый Git'ом для вычисления контрольных сумм, называется SHA-1 хешем. Это строка из 40 шестнадцатеричных символов (0-9 и a-f), вычисляемая в Git'е на основе содержимого файла или структуры каталога. SHA-1 хеш выглядит примерно так:

24b9da6552252987aa493b52f8696cd6d3b00373

Работая с Git'ом, вы будете встречать эти хеши повсюду, поскольку он их очень широко использует. Фактически, в своей базе данных Git сохраняет всё не по именам файлов, а по хешам их содержимого.

Основной инструмент, используемый для определения, какие файлы в каком состоянии находятся — это команда git status. Если вы выполните эту команду сразу после клонирования, вы увидите что-то вроде этого:

git status

On branch master
nothing to commit (working directory clean)

Это означает, что у вас чистый рабочий каталог, другими словами — в нём нет отслеживаемых изменённых файлов. Git также не обнаружил неотслеживаемых файлов, в противном случае они бы были перечислены здесь. И наконец, команда сообщает вам на какой ветке (branch) вы сейчас находитесь. Пока что это всегда ветка master — это ветка по умолчанию. Предположим, вы добавили в свой проект новый файл, простой файл CHANGELOG. Если этого файла раньше не было, и вы выполните git status, вы увидите свой неотслеживаемый файл вот так:

touch CHANGELOG
git status

On branch master
Untracked files:
  (use "git add <file>..." to include in what will be committed)

  CHANGELOG
nothing added to commit but untracked files present (use "git add" to track)

Понять, что новый файл CHANGELOG неотслеживаемый можно по тому, что он находится в секции "Untracked files" в выводе команды status. Статус "неотслеживаемый файл", по сути, означает, что Git видит файл, отсутствующий в предыдущем снимке состояния (коммите); Git не станет добавлять его в ваши коммиты, пока вы его явно об этом не попросите. Это предохранит вас от случайного добавления в репозиторий сгенерированных бинарных файлов или каких-либо других, которые вы и не думали добавлять. Мы хотели добавить CHANGELOG, так давайте сделаем это. Для того чтобы начать отслеживать (добавить под версионный контроль) новый файл, используется команда git add. Чтобы начать отслеживание файла CHANGELOG, вы можете выполнить следующее:

git add CHANGELOG

Если вы снова выполните команду status, то увидите, что файл CHANGELOG теперь отслеживаемый и индексированный:

git status

On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

  new file:   CHANGELOG

Вы можете видеть, что файл проиндексирован по тому, что он находится в секции “Changes to be committed”. Если вы выполните коммит в этот момент, то версия файла, существовавшая на момент выполнения вами команды git add, будет добавлена в историю снимков состояния. Как вы помните, когда вы ранее выполнили git init, вы затем выполнили git add (файлы) — это было сделано для того, чтобы добавить файлы в вашем каталоге под версионный контроль. Команда git add принимает параметром путь к файлу или каталогу, если это каталог, команда рекурсивно добавляет (индексирует) все файлы в данном каталоге.

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

git status

On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

  new file:   CHANGELOG

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)

  modified:   README

Файл README находится в секции “Changes not staged for commit” — это означает, что отслеживаемый файл был изменён в рабочем каталоге, но пока не проиндексирован. Чтобы проиндексировать его, необходимо выполнить команду git add (это многофункциональная команда, она используется для добавления под версионный контроль новых файлов, для индексации изменений, а также для других целей, например для указания файлов с исправленным конфликтом слияния). Выполним git add, чтобы проиндексировать README, а затем снова выполним git status:

git add README
git status

On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

  new file:   CHANGELOG
  modified:   README

Теперь оба файла проиндексированы и войдут в следующий коммит. В этот момент вы, предположим, вспомнили одно небольшое изменение, которое вы хотите сделать в README до фиксации. Вы открываете файл, вносите и сохраняете необходимые изменения и вроде бы готовы к коммиту. Но давайте-ка ещё раз выполним git status:

vim README
git status

On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

  new file:   CHANGELOG
  modified:   README

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)

  modified:   README

Теперь README отображается как проиндексированный и непроиндексированный одновременно. Как такое возможно? Такая ситуация наглядно демонстрирует, что Git индексирует файл в точности в том состоянии, в котором он находился, когда вы выполнили команду git add. Если вы выполните коммит сейчас, то файл README попадёт в коммит в том состоянии, в котором он находился, когда вы последний раз выполняли команду git add, а не в том, в котором он находится в вашем рабочем каталоге в момент выполнения git commit. Если вы изменили файл после выполнения git add, вам придётся снова выполнить git add, чтобы проиндексировать последнюю версию файла:

git add README
git status

On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

  new file:   CHANGELOG
  modified:   README

Зачастую, у вас имеется группа файлов, которые вы не только не хотите автоматически добавлять в репозиторий, но и видеть в списках неотслеживаемых. К таким файлам обычно относятся автоматически генерируемые файлы (различные логи, результаты сборки программ и т.п.). В таком случае, вы можете создать файл .gitignore с перечислением шаблонов соответствующих таким файлам. Вот пример файла .gitignore:

cat .gitignore

*.[oa]
*~

Первая строка предписывает Git'у игнорировать любые файлы заканчивающиеся на .o или .a — объектные и архивные файлы, которые могут появиться во время сборки кода. Вторая строка предписывает игнорировать все файлы заканчивающиеся на тильду (~), которая используется во многих текстовых редакторах, например Emacs, для обозначения временных файлов. Вы можете также включить каталоги log, tmp или pid; автоматически создаваемую документацию; и т.д. и т.п. Хорошая практика заключается в настройке файла .gitignore до того, как начать серьёзно работать, это защитит вас от случайного добавления в репозиторий файлов, которых вы там видеть не хотите.

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

Одно из ключевых отличий Git от других систем - в приоритете хранение не разницы между двумя состояниями, которые при движении по истории применяются или отменяются, а использование конечных результатов, или, в терминологии Git - снепшотов. За счет выбора подобного подхода git работает очень быстро. Возвращение к какой-то конкретной версии файла происходит моментально и не доставляет вам неудобств.

Если вам нужна помощь при использовании Git'а, есть три способа открыть страницу руководства по любой команде Git'а:

git help <команда>
git <команда> --help
man git-<команда>

Например, так можно открыть руководство по команде config:

git help config

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


Аватары экспертов Хекслета

Остались вопросы? Задайте их в разделе «Обсуждение»

Вам ответят команда поддержки Хекслета или другие студенты.

Открыть доступ

Курсы программирования для новичков и опытных разработчиков. Начните обучение бесплатно.

  • 130 курсов, 2000+ часов теории
  • 900 практических заданий в браузере
  • 360 000 студентов
Даю согласие на обработку персональных данных, соглашаюсь с «Политикой конфиденциальности» и «Условиями оказания услуг»

Наши выпускники работают в компаниях:

Логотип компании Альфа Банк
Логотип компании Aviasales
Логотип компании Yandex
Логотип компании Tinkoff

Используйте Хекслет по максимуму!

  • Задавайте вопросы по уроку
  • Проверяйте знания в квизах
  • Проходите практику прямо в браузере
  • Отслеживайте свой прогресс

Зарегистрируйтесь или войдите в свой аккаунт

Даю согласие на обработку персональных данных, соглашаюсь с «Политикой конфиденциальности» и «Условиями оказания услуг»