На правах рекламы

Шукалка

git - мой рабочий цикл

Пятница, 4 декабря 2009 г.
Рубрика: Бизнес в сети
Метки: |
Просмотров: 6129
Подписаться на комментарии по RSS

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

Но для начала пару вступительных слов, о том, что же такое вообще система контроля версий и зачем она нужна. Изначально предполагается, что такая система необходима для совместной работы нескольких участников над одним проектом, хотя лично я считаю, что такая система, как git, будет весьма и весьма полезной и одиночному разработчику. Хотя многие программисты считают, что такая система вообще лишняя, и что можно разрабатывать проекты, разделив их на модули так, чтобы каждый программист работал над своим модулем, а в конце все эти модули якобы удасться связать в кучу. Лично я считаю такой подход в корне неправильным и безнадежным по ряду причин.

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

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

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

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

Представим, например, ситуацию, когда вы работаете над задачей "А", закончили ее и отправили в центральный репозиторий svn. Позже вы приступили к задаче "B", когда вдруг обнаруживается, что при реализации задачи "A" вы допустили ошибку, которую надо срочно исправить, однако, изменения сделанные в рамках работы над задачей "B" привели систему в неработоспособное состояние. Что делать в такой ситуации? Нужно либо быстренько доделывать задачу "B", попутно исправляя ошибки в задаче "A", а потом в коммите писать: "Сделал B + исправил A". Либо делать ветку в центральном репозитории, сохранять там недоделанную задачу "B", после чего переключаться на задачу "А" и исправлять в ней ошибки. При чем эта ветка никому, кроме вас не нужна вовсе, но делать ее приходится в центральном репозитории. Или же на худой конец извлекать копию проекта в отдельный каталог и исправлять ошибки задачи "А" в отдельном каталоге.

В случае с git все предельно просто. Вам достаточно придерживаться правила: одна задача - одна ветка. Переключаться между локальными ветками вы можете сколько угодно и когда угодно. Поэтому вы легко можете сохранить недоделанные изменения задачи "B" и переключиться на ветку задачи "А", исправить там ошибки и вернуться назад к задаче "B".

Итак, с разделом мотивации я закончил. Если я вас не убедил, то, как говорится, "горбатого могила..." Нда-с... О чем это я? wink

Переходим непосредственно к рабочему циклу.

  1. Получение исходника с центрального репозитория. Выполняется приблизительно такой командой:
  2. git clone ssh://user@git.server.url:port/reponame.git
    C этого момента наш центральный репозиторий становится origin и его в дальнейших командах указывать не надо. Неплохо сразу добавить исключения в файл .git/info/exclude, чтобы предотвратить попадание всяких логов, кэша, бэкапов редактора и прочего мусора в репозиторий.
  3. Создание ветки для задачи:
    git branch <branchname>
    Посмотреть список веток так:
    git branch
    "*" указывает на текущую. Переключаемся на ту, с которой будем работать:
    git checkout <branchname>
  4. Работа с веткой. Добавляем, изменяем, удаляем любые файлы. Новые файлы надо добавить в репозиторий, одним из способов:
    git add <filename>
    git add <dirname>
    git add .
    Последний вариант хорош тем, что добавляет все новые файлы рекурсивно.
  5. Отмена не сохраненных изменений, делается с помощью одной из команд:

    git checkout <filename>
    git checkout <dirname>
    git checkout .
    По-сути мы заново вытягиваем последние версии указанных файлов.

    Сохраняем изменения (делаем коммит):

    git commit -a
    Отмена сохраненных изменеий (возврат к предыдущему коммиту):
    git reset --hard HEAD^
  6. Слияние веток. Когда работа над задачей закончена, надо слить текущую ветку с основной веткой master:
    git checkout master
    git merge <branchname>
    Если мы уже сливали ранее другую ветку и теперь оказались конфликты, они будут помечены и их необходимо будет исправить вручную, но я с таким пока ни разу не сталкивался. Исправив указанные файлы, надо снова сделать коммит.
  7. Ветки, работа над которыми прекращена и все исправления с них слиты с основной веткой master, можно удалить так:

    git branch -d <branchname>
    Если ветка была ошибкой, то ее можно удалить, не сохраняя изменений:
    git branch -D <branchname>
  1. Выдаем нашу задачу нагора. В ценральный репозиторий мы отправляем только проверенные и рабочие версии. По-крайней мере считается правилом хорошего тона недоделок не отправлять. Перед этим надо проверить, не было ли изменений в центральном репозитории, сделанных другими разработчиками:
    git pull
    Если есть изменения, они будут влиты в ваш репозиторий. Если возникли конфликты, то исправляем (еще не приходилось ни разу), после чего отправляем наши изменения в центральный репозиторий:
    git push

Вот и весь, необходимый минимум.