Почему Git

:

Было время, когда я ничего не знал про VCS, ни что это такое, ни тем более зачем это мне. И верхом своих достижений считал папочку с архивами версий. К моменту осознания необходимости системы контроля версий я уже набил шишек и прочувствовал необходимость такого инструмента. Но борландовский аналог CVS меня не впечатлил. У каждого файла свой номер версии. Как мне получить срез определенного релиза я так и не разобрался. А в это время SVN победоносно шла сквозь умы разработчиков. Черт, это было то, чего мне так не хватало. Прочитав доку и начав работать я просто влюбился в нее. Да, были трудности и определенные неудобства, но куда без них.
Так я и работал бы в SVN, но ничего не стоит на месте. В интернете уже потекли тонкие ручейки новостей про Git. Я не кидаюсь за каждой новой технологией, и прошло уже достаточно много времени, пока мне не прожужжали этим Git’ом все мозги. Мне стало любопытно, я вначале присматривался, примерялся, а потом плюнул и начал новый проект на Git. Мучался с ребятами 2 недели, накачал литературы, написал шпаргалку… ничего, привыкли, … а потом меня поперло.

Теперь меня регулярно просят рассказать про Git и что в нем такого. Уже надоело, поэтому этот пост для тех, кто еще сомневается.

Все локально
Репозиторий, история, ветки и коммиты.
Отсюда вытекает 2 важных следствия: все очень быстро, и второе — вы получаете абсолютный контроль над репозиторием.

  • Создать репозиторий в текущей директории — «git init». Все.
  • Всего одна папочка .git и никакой порнографии ввиде .svn в каждой директории.
  • Интернет не нужен. Работать одному вообще шикарно — локальный репозиторий, который разворачивается за доли секунды. Работа в распределенной команде — у каждого своя копия репозитория, никто не зависит от доступности центрального сервера.
  • Не надо задумываться о создании системы резервного копирования. У каждого участника есть копия, из которой можно поднять оригинал.
    Поднимите руки те, кто поднимал потерянный svn-репо из своей копии git-репозитория .
  • В своем репозитории вы делаете все, что хотите. Любые ветки, никто их не увидит.
    Черт, я помню как мне запрещали в SVN создавать отдельную ветку для работы над экспериментальной версией.

Контроль
В Git можно делать с коммитами и историей все что угодно:
  • Удалить коммит, как будто его и не было
  • Изменить комментарий коммита
  • Поменять коммиты местами
  • Объединить несколько коммитов в один, особенно когда нужно «докоммитить» что-то забытое
  • Разбить коммит на несколько
Ветки:
  • Перенести/скопировать коммит из одной ветки в другую
  • Переместить ветку в любую точку
Очень хорошо это описано здесь: http://gq.net.ru/2009/12/16/ git-history-rewrite /
От таких возможностей сносит голову и  кому-то это может показаться слишком опасным. Да, пару раз я терял коммиты из-за своих неопытных манипуляций и потом рылся в «корзине», чтобы их восстановить.
Но по мере того, как привыкаешь к этому и понимаешь что и как работает, у тебя вырастают крылья, и ты начинаешь работать намного эффективнее, получая попутно кучу удовольствия от этого.

Ветки
Git — это ветки. Это настолько просто, гибко и удобно, что все делается в ветках. От релиза, до маленьких задач.

  • Создать ветку, переключиться в нее, объединить ветки, вернуться назад — это рутинные операции.
  • Мерджить одно удовольствие. Есть конфликты или нет, все проходит очень легко и никогда ничего не теряется.
  • За исключением релизных, большинство веток очень короткие и живут 1–3 дня.

Коммит
Чтобы сделать коммит, надо указать какие именно изменения нужно туда положить. Изменения, а не файлы. «git add» надо вызывать как для измененных, так и для новых файлов. Таким образом подготавливается временное состояние, которое я называю «временный коммит» (в оригинале «staging area» или «index»).
В чем преимущество:
  • Я всегда могу посмотреть что я буду коммитить, а что не попадет в коммит
  • Поскольку git принимает «изменения», я могу положить в коммит только часть изменений в одном файле, а другую часть в этом же файле откатить или положить в другой коммит.

    Последнее время я использую только «git add -p» — Git показывает чанк за чанком (набор изменений в рамках файла) и спрашивает добавить в коммит или нет. Так я вижу, что я изменил и буду коммитить. И поэтому в коммит у меня никогда не попадут отладочный код, комментарии, лишние правки, пробелы. И коммиты получаются четкими и атомарными.


Диф и лог
  • Я могу посмотреть диф всей ветки или группы коммитов, чтобы не листать по коммиту, особенно, если они неграмотно оформлены.
  • Могу посмотреть разницу между 2 ветками, посмотреть какими коммитами они отличаются.
  • Посмотреть диф без учета пробелов (git diff -b -w), если кто-то увлекся форматированием и превратил диф в одну сплошную кашу
  • Могу в конфиге настроить кучу алиасов, которые будут выводить логи коммитов в разных форматах, например, сформировать change-log .
Лог — это вообще бездна возможностей.

Stash
Я работаю над задачей, разобрал проект на части и тут мне надо все бросить, переключиться на другую ветку, чтобы пофикстить баг или провести ревью. Я сохраняю свои правки во временном состоянии (stash), переключаюсь, делаю все, что мне надо, возвращаюсь обратно, восстанавливаю свои правки и продолжаю работать.

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

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

Субмодули
Git позволяет включать в проект другие проекты. Подключаются они как субмодули:

  
  
       
  
   
        
   
   
  $ git submodule add git://github.com/maxim-oleinik/sfDoctrine2Plugin.git plugins/sfDoctrine2Plugin

  
  
       
  

Git создаст директорию «plugins/sfDoctrine2Plugin» и развернет там еще один репозиторий, а под контроль поставит хеш ревизии. Если зайти в эту директорию, то мы попадем уже в другой проект. Там можно работать и коммитить как обычно, только в родительском проекте Git покажет, что подпроект обновился и предложит сохранить ссылку на новый коммит.
  • Удобно работать в основном проекте и одновременно коммитить в разные субмодули.
  • В Git нельзя подключить указанную директории из другого проекта, как это делает svn:externals. Только весь проект целиком.
    В том и суть, чтобы выделять самостоятельные модули и оформлять их в отдельные репозитарии. Правда, становится немного неудобно работать, когда у субмодулей есть свои субмодули и т.д.

GUI и консоль
Я, честно говоря, не знаю какой есть GUI у Git. Я никогда им не пользовался и рекомендую не лишать себя удовольствия работы с Git’ом в консоли. Не превращайтесь в мартышек, которые ищут нужную кнопку или галочку в интерфейсе, вместо того, чтобы просто набрать команду в консоли.
Ладно, без обид. Я просто хотел сказать, что работа в консоли намного богаче и удобнее.
У кого нет нормальной консоли… ну, тогда выбирайте GUI, IDE или… OS, у которой эта консоль есть.
Единственным окошком, которым я регулярно пользуюсь, — это «gitk -all &». Он показывает дерево коммитов с ветками и тегами. Очень удобно смотреть где ты сейчас находишься, где какие ветки и как они переплетаются. Там есть простой поиск и просмотр дифа.

Работа в команде

  • В git нельзя закрыть доступ к определенной ветке или модулю. Или все или ничего. Но это еще ни разу не создало мне проблем. Если кто-то ошибся и закоммитил не туда, куда ему следовало (как мы заранее договорились), тогда я просто откачу эти правки так, как будто их и никогда и не было, и проведу разъяснительную беседу.
    Как вариант, можно выделить отдельный репозитарий с ограниченным доступом и рабочий — для всех.
  • Все задачи делаются атомарно в ветках и в таком же виде передаются на ревью и мердж. Т. е. при желании, ни один коммит не попадет в основной ствол без ревью.
  • Очень удобно проводить ревью задачи, которая выполнена в отдельной ветке. Посмотреть полный диф всех коммитов, что-то исправить, прокомментировать, отправить обратно на доработку, а потом объединить отдельные коммиты и слить в основную ветку.

GitHub
Это классная платформа, где можно бесплатно разместить и опубликовать свой репозиторий. Где живет куча проектов, которые форкаются, развиваются и обсуждаются. Сейчас там лежат все мои проекты.
Бесплатно для открытых проектов и мин 200 руб/мес, чтобы закрыть доступ.

Это конечно, далеко не все, что может Git. Есть еще куча всего, чего я не рассказал и чего я до сих пор еще не знаю. Я постарался осветить принципиальные моменты.
У Git’a, конечно, есть и определенные минусы и трудности, но без них не бывает. Да они и не существенны. Чаще всего это вопрос git-way .
Правда у Git’а есть один серьезный минус — он не для ленивых. Поэтому подумайте заранее, прежде чем предлагать Git таким ребятам.

Что дальше


Дальше — начинать работать. Можно читать кучу обзоров и обсуждать сколько угодно, но до тех пор пока не начнешь работать, ничего не изменится.
За один день я перерыл доку и начал работать, 2 недели привыкал, через месяц учил остальных, через 3 — расправил крылья.

Как начать

  1. Скачать, установить и настроить, я думаю, ни у кого не возникнет проблем. Почитаете еще статьи в этом блоге про настройки и прочие фишки.
  2. Прочитайте любую книгу из списке указанного ниже. Правда, прочитайте. Хоть по диагонали, зато будете знать, что вообще есть. Это легко сделать за пару часов.
  3. И начинайте работать над новым проектом или переносите существующий (импортировать не составить труда).
Есть чит-шит , который поможет с командами на первое время. Есть «git help <команда>». Рекомендую не лениться и регулярно читать хелп для каждой новой команды, а потом еще читать и перечитывать. Так я узнал большинство возможностей, тонкостей и нюансов.
Ну и пишите, если что не понятно. Мне очень трудно понять, какие очевидные для меня вещи, не понятны новичкам. За второй статьей дело не станет.

Ссылки: