Что такое Git?

Что же такое Git, если говорить коротко? Эта часть очень важна для понимания.

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

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

Снимки, а не различия

Основное отличие Git от любой другой системы контроля версий (включая хранилище конфигурации и его «собратьев») — это подход Git к работе со своими данными. Концептуально, большинство других систем хранят информацию в виде списка изменений в файлах. Эти другие системы (хранилище конфигурации, CVS, Subversion, Perforce, Bazaar и т. д.) представляют информацию в виде набора файлов и изменений (дельт), сделанных в каждом файле в течение времени. Обычно это называют контролем версий, основанным на различиях.

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

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

Почти все операции выполняются локально

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

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

Это также означает, что существует лишь небольшое количество действий, которые вы не сможете выполнить, когда находитесь в офлайн-режиме или когда не подключены к сети. Если вы находитесь в самолете или в поезде и хотите немного поработать, то можете фиксировать изменения в вашу локальную копию без каких-либо проблем. Когда будет возможность подключиться к сети, вы загрузите все изменения на сервер. Другой пример: если вы ушли домой и не можете подключиться через VPN, вы все равно сможете работать.

Добиться такого же поведения во многих других системах либо очень сложно, либо вовсе невозможно. В Perforce, для примера, вы мало что сможете сделать, если вы не подключены к серверу. В Subversion и CVS вы сможете редактировать файлы, но не сможете сохранить изменения в базу данных, потому что не подключены к ней. Все эти трудности могут показаться не такими уж и значимыми, но вы удивитесь, какое большое значение они могут иметь.

Целостность Git

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

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

Обычно Git только добавляет данные

Когда вы производите в Git какие-либо действия, практически все они приводят к тому, что данные добавляются в базу Git. Очень сложно заставить Git удалить данные или сделать какие-то изменения, которые нельзя впоследствии отменить. Как и в любой другой системе контроля версий, вы можете потерять или испортить свои изменения, пока они не зафиксированы. Но, после того как вы зафиксируете снимок в Git, вам будет очень сложно что-либо потерять, особенно если вы регулярно отправляете свою базу в удаленный репозиторий (на сервер).

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

Три состояния

Теперь читайте особенно внимательно. Это самая важная вещь, которую нужно запомнить о Git, если вы хотите, чтобы оставшееся обучение прошло гладко. Git имеет три основных состояния, в которых могут находиться ваши файлы: измененные (modified), индексированные (staged) и зафиксированные (committed).

  • Измененный означает, что вы изменили файл, но еще не зафиксировали его в своем локальном репозитории;
  • Индексированный — это измененный файл, текущую версию которого вы отметили для включения в следующий коммит (для фиксации в своем локальном репозитории);
  • Зафиксированный означает, что файл уже сохранен в вашем локальном репозитории.

Таким образом, вы подошли к трем основным секциям проекта Git: рабочий каталог, индекс и репозиторий.

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

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

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

Базовый подход в работе с Git выглядит так:

  1. Вы изменяете файлы в вашем рабочем каталоге.
  2. Вы выборочно добавляете в индекс только те изменения, которые вы хотите зафиксировать следующим коммитом.
  3. Вы фиксируете изменения. При этом файлы в том состоянии, в котором они находятся в индексе, сохраняются в вашем репозитории навсегда в виде снимка.

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

По материалам книги Pro Git (авторы Scott Chacon и Ben Straub, издательство Apress). Книга распространяется по лицензии Creative Commons Attribution Non Commercial Share Alike 3.0 license.