Типовые сценарии работы c Git
smurav edited this page Sep 21, 2011
·
5 revisions
В этом разделе будут показаны и разобраны подробно несколько обычных и чуть меньше необычных для работы с git ситуаций.
Git обладает необычайной легкостью в использовании не только как распределенная система контроля версий, но и в работе с локальными проектами. Давайте разберем обычный цикл — начиная с создания репозитария — работы разработчика git над собственным персональным проектом:
- mkdir git-demo
- cd git-demo
- git init
- git add .
- git commit -m «initial commit»
- git branch new-feature
- git checkout new-feature
- git add.
- git commit -m «Done with the new feature»
- git checkout master
- git diff HEAD new-feature
- git merge new-feature
- git branch -d new-feature
- git log --since=«1 day»
Разберем каждое из действий...
- просто создаем рабочую директорию проекта;
- переходим в неё;
- создаем репозитарий в директории;
- индексируем все существующие файлы проекта (если, конечно, они вообще были);
- создаем инициализирующий коммит;
- новая ветка;
- переключение в нее (можно сделать в один шаг командой git checkout -b new-feature);
- после непосредственной работы с кодом, индексируем внесенные изменения;
- совершаем коммит;
- переключаемся в основную ветку;
- смотрим отличия между последним коммитом активной ветки и последним коммитом экспериментальной;
- проводим слияние;
- если не было никаких конфликтов, удаляем ненужную больше ветку;
- ну и на всякий случай оценим проведенную за последний день работу.
Почему именно так? Зачем отказываться от линейной модели? Хотя бы даже потому, что у программиста появляется дополнительная гибкость:
- он может переключаться между задачами (ветками);
- под рукой всегда остается «чистовик» — ветка master;
- коммиты становятся мельче и точнее.
Предположим, что вы и несколько ваших напарников создали общественный репозитарий, чтобы заняться неким общим проектом. Как выглядит самая распространенная для git модель общей работы?
- git clone http://yourserver.com/~you/proj.git … возможно, прошло некоторое время.
- git pull
- git diff HEAD^
- git checkout -b bad-feature … работаем некоторое время.
- git commit -a -m «Created a bad feature»
- git checkout master
- git pull
- git merge bad-feature
- git commit -a
- git diff HEAD^ … запускаем тесты проекта, обнаруживаем, что где-то произошла ошибка. Упс.
- git reset --hard ORIG_HEAD
- git checkout bad-feature … исправляем ошибку.
- git -m bad-feature good-feature
- git commit -a -m «Better feature»
- git checkout master
- git pull
- git merge good-feature
- git push
- git branch -d good-feature
Итак...
- первым делом создаем копию удаленного репозитария;
- «Вытягиваем» последние обновления;
- смотрим, что же изменилось;
- создаем новую ветвь и переключаемся в нее;
- индексируем все изменения и одновременно создаем из них коммит;
- переключаемся в главную ветвь;
- обновляем ее;
- проводим слияние с веткой bad-feature;
- обнаружив и разрешив конфликт, делаем коммит слияния;
- после совершения коммита отслеживаем изменения, запускаем, например, юнит-тесты и с ужасом обнаруживаем, что после слияния проект валится на большей части тестов. В принципе, тесты можно было прогнать и до коммита, в момент слияния (между пунктами 8 и 9); тогда бы хватило «мягкого» резета;
- таким образом, приходится совершить «жесткий» сброс произошедшего слияния, ветки вернулись в исходное до состояние;
- переключаемся в неудачную ветку;
- вносим необходимые изменения и переименовываем ветку;
- совершаем коммит;
- переходим в главную ветку;
- опять ее обновляем;
- На этот раз бесконфликтно делаем слияние;
- закидываем изменения в удаленный репозитарий;
- удаляем ненужную теперь ветку.