git — краткое введение

Давненько уже работаю с такой классной штукой, как git. Git — это программа для контроля версий программ. В дальнейшем я планирую публиковать статейки, связанные с этой темой. Но чтобы как-то начать это, решил написать этот пост — краткое ознакомление с ней.Git написан Линусом Торвальдсом — автором Linux. Эта программа относится к классу программ контроля версий. К этому же классу относятся такие же программы, как SVN (Subversion) , CVS. Хотя в интернете и бытует мнение, что git сложнее, чем SVN, но мне показалось все иначе. Например, чтобы что-то делать с проектом в SVN, надо часто использовать команды из командной строки на каждое удаление, добавление файла  и т.п.. С git проще — вы просто работаете с файлами любыми средствами, а затем с помощью нескольких команд можно увидеть изменения и выполнить сразу добавление или удаление файлов пачками.

Давайте сначала поймем, зачем он вам нужен.

Если вы один программист, то вот преимущества git перед ситуацией, когда вы его не используете:

  1. В одном репозитарии (условно — одна папка) у вас хранится сразу вся история проекта с разными версиями. Вы можете создавать экспериментальные ветки, в случае успешного кода их затем объединять в стабильные ветки. Можно легко переходить в «прошлое». Например, можно быстро устранить баг в стабилной версии, а затем продолжать работать в экспериментальной альфа-версии.
  2. Легко просматривать, что вы изменили вчера и сейчас. Удобно, когда вы приходите утром на работу и хотите вспомнить, на чем же вы остановились.
  3. Заодно — git, выходит само собой, удобное средство резервирования и синхронизации. Вы можете разместить репозитарий на сервере, и с него подтягивать дома рабочие файлы, которые делали на работе,  а после правок заливать изменения обратно.
  4. В git — каждый клонированный репозитарий — не только рабочая площадка, но также и полноценный репозитарий. Если вы работали на ноутбуке, а сегодня накрылся ваш сервер с репозитарием, то ваша локальная версия на ноуте — опять же, репозитарий со всей «историей».
  5. Для git не надо online — вам достаточно «подтянуть» с сервера изменения, если были, и отключить ноутбук от интернета. Затем, работайте хоть в самолете! Делайте коммиты, пишите и просматривайте, что вы изменили. Только лишь, когда вы захотите «сбросить» все изменения в ваш главный репозитарий, только тогда вам нужен инет.

Если же вы команда, то преимущества те же, что выше, но также к ним добавляется возможность легкого ведения группового проекта. Самый замечательный пример, что все это отлично работает — ядро Linux — именно оно ведется Git-ом, и даже единичное увеличение подверсии ядра включает в себя большое количество commit-ов и работу большого количетва программистов.

Git, по моему опыту, гораздо понятнее программисту, чем тот же SVN, и гораздо логичнее. Я долго не мог принять, что в SVN создание ветви — делается через копирование файла. Какая-то странная логика. Затем, когда я освоил git, мне куда понятнее, что создание ветви — это создание нового узла дерева со своим parent или даже несколькими parent-ами. Обычнная иерархия, которая понятна не только программисту! Благодаря этому, очень легко прерывать проект и делать ответвления новый подверсий, работать с ними и затем, например, объединять с другими ветками. Git — это как бы мощный diff с элементами иерархии (diff хорошоф знаком тем, кто работает с Unix).

Что нужно четко понимать в git?

Отличительная идеология git от многих других программ контроля версий — наличие index. Index — это «промежуточный слой» между вашим рабочим файловым деревом, и того, что должно быть добавлено в репозитарий. В репозитарий добавляется только то, что есть в индексе. А в индекс вы добавляете из рабочего дерева то, что необходимо добавить затем в репозитарий. Запутано, скажете вы? Когда вы начнете работать, вы поймете, что это очень даже логично! Именно эта «фишка» git поначалу у меня вызывала непонимание.

Ветвление — одна из замечательных свойств git-а. Ветвить можно не просто разные версии программ, а даже по «мелочи». Например, вы хотите добавить новую фичу в программу. Если вы начнете работать на текущей стабильной версии, вы рискуете создать ситуацию, когда в рабочей версии будет найден баг, вам надо будет быстро его исправить, а вы не закончили и не отладили проект с вашей новой фичей. Тем самым, попадете в затруднительную ситуацию. Выход из нее простой — создали подветку, делаете свою новую фичу. Если необходимо, вы можете быстро переключаться между ветками. Ветвление в git — не ресурсоемкий процесс. Им удобно пользоваться и даже нужно. Иначе использование git превратится в стрельбу из пушки по воробьям.

Также, сразу постарайтесь приучить себя к такому способу ведения проекта в git, как активное использование масок для игнорирования файлов. То есть, вы ведете проект, но в нем есть два типа файлов и директорий — условно назовем служебные и проектные. Служебные  — те, что создаются в процессе работы и нужны только для компиляции. Проектные — те, что должны отслеживаться git-ом, лежать в репозитарии, и являться частью проекта в целом. Служебные должны исключаться через файл .gitignore (man gitignore). Причём, очень классно, что этот файл можно размещать в любой поддиректории проекта и он контролирует только файлы в той директории и поддиректориях. Приучите себя сразу формировать эти файлы (.gitignore), от рождения проекта, и постепенно, по мере работы, добавлять в него новые и новые файлы и маски. Этот файл также упростит вам жизнь с командами add & status.

Также, при групповой работе надо знать, что git — не локирует файлы на время редактирования кем либо. Один и тот же файл могут править несколько программистов. Принцип тут такой — если изменения происходили в «далеких» местах друг от друга в файле, git их объединит автоматом, если же нет — будет создан конфликт, требующий ручного исправления кем либо.

Еще несколько понятий и терминов.

Commit — это как бы фиксация изменений. Коммит имеет запись в истории — кто создал, когда, одну или несколько строк от автора изменений, что сделано. Также, можете просто предствавить — что commit — как бы снимок всей директории и файлов на тот момент.

Diff — текстовые отличия в формате diff между ветками, commit-ами, файлами и т.п.. Формат его легко читаем и даже сразу понятен, если посмотреть на него — вы видите, что добавляли или удаляли и когда.

Merge — объединение веток. Благодаря иерархии (что из чего следовало) и инструментам нахождения отличий (diff), git сам определяет, что было добавлено в код, что удалено, и на основе этих изменений он делает новые файлы в объединении. Но иногда может случиться так, что один и тот же файл в близких местах менялся в разных ветках. Вот тогда возникает конфликт (см. ниже)

Conflict — конфликт. Если вы делали merge, и при этом возникли противоречия, git создает «конфликт». Эта ситуация, когда файл с конфликтом помечается внутри базы git особым образом, в самом текстовом коде возникают текстовые метки типа ‘<<<<‘ или ‘>>>>>>’ с кодами из обоих веток и от вас требуется ручное редактирование файла — устранение конфликта. Вам надо посмотреть эти метки в самом коде, решить, что правильнее, отредактировать, а потом дать понять git-у, что файл вы привели в норму (git add …). С бинарными файлами несколько иначе, но смысл тот же. При конфликте в индексе для одного файла уже хранится не один вариант, а два варианта файла — «наш» (our — то есть вариант из нашей ветки) и «ихний» (вариант из той ветки, который мы объединяем).

Repository — репозитарий, то есть хранилище. Как уже говорил, любая копия может быть репозитарием одновременно для кого либо. Вы можете сами для себя определить, где будет главная копия. Закачку и выкачку лучше всего осуществлять через ssh протокол. Делается просто — там где лежит репозитарий, он должен лежать под правами, скажем пользователя user. Тогда, чтобы вытянуть от туда, вам надо знать либо пароль user, либо иметь ssh ключ. А сама выкачка делается также просто, без всяких ssh команд: «git clone user@therehost.com:git/myproject.git», например. А дальше, git запомнит адрес репозитария, и обмен данными превратится в две простые команды: «git push» и «git pull». Если еще правильно организовать доступ по ssh ключам, то можно вообще не вводить пароли 😉 Также, в git есть unix-shell, который прописывается в /etc/shells и садится как shell для Unix аккаунта — тогда можно не беспокоится, что Unix аккаунт будет использоваться для чего либо ещё, кроме git.
Также, маленький нюанс — репозитарий может быть двух типов: bare и обычный. Обычный — это файловое дерево проекта + .git служебная директория, где все и хранится git-овское. А bare — это только файлы .git — там нет рабочей директории, и bare используется только для репозитариев с целью сохранения и взятия информации их них. Обычно, bare репозитариям дают суффикс ‘.git’ в директории, их содержащей. В остальном — работа синхронизации идентична. Делать push можно только в bare директории.

Если вы поставили git на Unix, то все по нему можно узнать из man-ов: «man git», или, например: «man git-diff» и т.п.. Все в нем делается через одну команду — git, а вторым параметром указывается сама команда. А сам «мен» по ней состоит из git и через дефис той команды, что вам нужна (список всех команд — man git).

Также, есть Windows версия, причем, в том числе с графической поддержкой, показывающей иерархии и изменения от одного commit-а к другому. Находится она здесь: mSysGit — там выбираете, например, msysGit-fullinstall-* самый свежий и ставите. Установка проста, как и все программы для Windows. Ленивые могут использовать только графическую оболочку, а продвинутым, пожалуй, будет интересен «Git Bash» из того же комплекта. Лично я предпочитаю работать в «Git Bash», так как там привычная мощная оболочка bash со всеми ее плюсами (включая, кстати ssh-* команды).

Ещё для Windows есть замечательная Unix эммуляция — cygwin. Там есть всё — и git, и bash, и rsync и другое. Вообщем, аля Unix под Windows без виртуальной машины. Именно её я и использую под Windows, когда надо проект писать для Unix, но под рукой только Windows.

Заключение

Не ждите волшебства от git-а. Он, конечно, не додумает за вас программный код, когда вы объединяете две ветки в одну с разным кодом в одном месте. Но сделает свою работу максимально правильно, упростив вам жизнь.

Я, как программист-одиночка, сейчас уже сложно представляю себе работу без git. Даже если проект поддерживается одним человеком, git сильно облегчает жизнь. И это не смотря на то, что все качества git-а раскрываются в групповой работе над проектом. Самым лучшим примером будет то, что ядро Linux поддерживается только через этот инструмент контроля версий. А ядро — самая динамично-развивающаяся часть кода в мире Linux — над ней работают сотни людей. А требования к ее надежности — самые высокие!

git — краткое введение: 4 комментария

  1. Спасибо за статью.
    Никак не мог найти доступное объяснение, что такое Git и зачем он нужен. А теперь что-то, наконец, начинает проясняться.

  2. Очень толково, благодарю за объяснения. Перекопал кучу сайтов, только у Вас нашел то, что искал. Спасибо!

  3. Большое спасибо! Продолжайте в том же духе — понятно и грамотно 🙂 Здорово, когда в статье есть не только инфа по сабжу, но и мнение автора и его рекоммендации.

Обсуждение закрыто.