Git и командная разработка (для чайников) +22


Введение


Привет! Если ты сюда зашел, значит тебя заинтересовал вопрос, как программисты работают в команде. Если до этого ты работало только в соло, то тебе, наверно, кажется, что в команде работать проще, ведь больше рук и значит можно гораздо быстрее справиться с работой. Но не все так просто. Сейчас мы с тобой ознакомимся, с помощью каких инструментов ведется разработка и что происходит внутри команды.

GIT


Наверняка вам знакома такая ситуация.



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

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

Плачевная ситуация… И чтобы такого не происходило, нужно сохранять версии своего кода.

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

И тут мы можем провести аналогию с играми. Почти во всех ААА проектах есть система сохранений. Как наглядный пример можно привести игру Papers Please.



Примерно также и работают все системы контроля версий.

Version Control System (VCS) — система, записывающая изменения файла или набора файлов в течение большого периода времени, так чтобы была возможность позже вернуться к определенной версии.

Классификация СКВ:

  1. Локальные
  2. Централизованные
  3. Распределенные

С локальными СКВ мы уже разобрались (это те самые кучи одинаковых файлов)

Централизованные СКВ




  • центральный сервер
    все файлы под версионным контролем
  • ряд клиентов
    получают копии файлов

Примеры:

  • CVS
  • Subversion
  • Perforce

Распределенные СКВ




  1. Клиенты полностью копируют весь репозиторий
  2. Центральный сервер отвечает за предоставление основной копии
  3. Синхронизация может быть
    • С сервером
    • С любым клиентом


Примеры:

  • Git
  • Mercurial
  • Bazaar

Зачем нужна СКВ


  1. Хранение всех изменений проекта
  2. Возможность переключения «на любую стадию развития проекта»
  3. Возможность вести одновременную командную разработку
  4. Возможность решать проблемы, подобные следующей



GIT


Git — распределённая система контроля версий
Автор: Линус Торвальдс
2005 — первая версия

Установка:
Linux: sudo apt install git
Windows/macOS: ссылка

Используют разработчики:

  • GNU/Linux
  • Android
  • Wine
  • Google
  • Chromium
  • jQuery
  • PHP
  • MediaWiki
  • Qt

Базовые понятия


Репозиторий (repository, repo) — место, где СКВ хранит свои метаданные и базу данных объектов проекта
Рабочий каталог (working directory) — извлечённая из репозитория копия определённой версии проекта
Область подготовленных файлов (staged area) — служебный файл, содержащий информацию о том, что должно войти в следующую ревизию проекта
Ревизия (revision) — объект, хранящий изменение состояния проекта (версия проекта)
Коммит (commit) — создание новой ревизии

Настройка конфигурации GIT


Настройка имени пользователя

git config --global user.name "Your Name" 
git config --global user.email you@abc.net

Настройки сохраняются в скрытый файл .gitconfig (в домашней директории пользователя)

[user] 
name = John Doe 
email = jdoe@example.com

Создание репозитория

mkdir first_git_repo 
cd first_git_repo 
git init

Состояния файлов проекта


  1. Зафиксированный
    файл уже есть в репозитории
  2. Измененный
    файл отличается по содержанию от своего зафиксированного состояния
  3. Подготовленный
    измененный файл, который станет зафиксированным после создания новой ревизии (этот файл попадет в эту ревизию)

Работа с кодом




  • Инициализация репозитория

    git init
  • Или переход на определенную ревизию
    git checkout номер_ревизии

  1. Изменение в коде проекте: создание / удаление / редактирование файлов
    В любой IDE
  2. Просмотр состояния
    git status
  3. Добавление измененных файлов в индекс
    (перевод в состояние Staged)
    git add имена_файлов_через_пробел
  4. Создание ревизии (из Staged в Repo)
    git commit -m "Комментарий"

Суммируем




Работа с СКВ


Что хранить?

[+] Все файлы исходного кода
[+] Все ресурсы, необходимые для компиляции
[+] настройки компиляции проекта
[-] настройки проекта в IDE
[-] файлы, компилируемые из исходников
[-] исполняемые файлы

Удаление из индекса

git rm имя_файла

Коммит может содержать изменения нескольких файлов

Когда делать коммит?

  • Когда завершил маленьшую задачку
  • Если задачка большая — делим на логические подчасти
  • Код должен быть в рабочем состоянии!

Просмотр истории

git log
git log --graph



Номер ревизии = SHA-1 хэш изменений

Переключение на ревизию

git checkout sha1_hash 
git checkout первые_8_цифр_sha1

Ветки


Ветка (англ. branch) — это последовательность коммитов, в которой ведётся параллельная разработка какого-либо функционала

Основная ветка – master



Ветки в GIT


Показать все ветки, существующие в репозитарии

git branch

Создать ветку

git branch имя

Переключиться на ветку

git checkout имя
На этот момент не должно быть несохранённых изменений

Создать ветку и переключиться на неё

git checkout -b имя

Слияние веток


Объединение веток (англ. merge) — процесс интеграции изменений (коммитов) одной ветки в другую:

b1 — ветка, в которую мы добавляем изменения
b2 — ветка из которой мы добавляем изменения



git checkout b1 
git merge b2

Просмотр истории


Оконные утилиты:

  • gitg
  • gitk
  • gitx
  • gitKraken



Удаление веток


Удалить ветку

git branch –d имя_ветки

УДАЛИТЬ ветку

git branch –D имя_ветки

А точнее, удалить ветку, не дожидаясь перемещения коммитов в master

Буфер несохраненных изменений


Или «что делать, если нужно переключиться на другую ветку, а коммит делать рано?»

Записать изменения во временный буфер

git stash

Извлечь из буфера эти изменения

git stash pop

Полезные ссылки:

git-scm.com/book/ru/v2
githowto.com/ru
ru.wikipedia.org/wiki/Система_управления_версиями

Командная разработка


Итак, если ты добрался до этой строчки, то значит ты хотя бы чуть-чуть разобрался с git’ом (очень на это надеюсь). Но что же насчет командной разработки? Давай рассмотрим этот вопрос поподробнее.

Небольшая юмористическая задачка:

Дано:

  • N разработчиков
  • Рабочие места
  • Техническое задание (ТЗ)
  • Интернет

Вопрос:

  • Как выполнить проект не привлекая внимание санитаров?

Ответ:

  • Слаженная команда и упорный труд

Хм, а что же такое вообще команда? Что она из себя представляет?

Команда – это небольшое количество людей:

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

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

Так-с, теперь тебе понятно, что такое команда. Но следующий вопрос, который возникает в твоей голове (да, да, авторы данной статьи умеют читать мысли): «А кто за что отвечает в команде? У каждого «есть свое место»? Или все делают, что захотят?».

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

  1. Team Leader:

    Team Leader — это нечто среднее между проектным менеджером и квалифицированным девелопером.

    На проектах есть две lead роли: менеджерская — PM, и техническая — System Architect. Тимлид отчасти выполняет обе роли, но акцент его обязанностей направлен на менеджмент (акцент на техническую часть — это tech lead).

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

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

    Под техническую роль: участие в написании технической документации, выбор технологий для проекта, разработка архитектуры, R&D, code review, менторинг джуниоров, проведение технических собеседований, грамотное вовлечение новых членов команды в рабочий процесс, ответственность за техническую часть проекта.

    Типичный рабочий день тимлида включает в себя:

    • рассмотрение новых задач и их распределение
    • стендап с командой
    • митинги
    • программирование
    • архитектурные вопросы
    • code review
  2. Project manager:

    Project Manager — это специалист, чьей главной задачей является управление проектом в целом: проектирование и расстановка приоритетов, планирование выполнения задач, контроль, коммуникации, а также оперативное решение проблем.

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

    Задачи PM’а можно классифицировать как тактические и стратегические. Тактические — это решение каждодневных проблем проекта, устранение препятствий с пути команды. Стратегические заключаются в том, чтобы координировать общую цель проекта, путь к ней, а также скорость передвижения.

    «Главная постановка задачи для PM’а: „Нам нужно, чтобы это работало“, что подразумевает, что команда предоставит результат в разумные сроки с разумным уровнем качества».
  3. Тестировщик:

    Тестировщик — это специалист, который занимается тестированием программного продукта с целью выявления ошибок в его работе и их последующего исправления.

    Главные должностные обязанности тестировщика:

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

  4. Разработчики:

    • Junior:
      Junior – разработчик начального уровня.

      Пройдя интернатуру, человек превращается в полноценного джуна. Основное требование к нему — способность самостоятельно выполнять технические задачи. Если в проекте выстроена архитектура, он должен без задержки реализовать очередной кусок типовой логики приложения. Хотя Junior может время от времени ошибаться, не понимать нюансов, обсуждать планы реализации с тимлидом или вместе с ним проверять готовый код.

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

      Middle – разработчик среднего уровня.

      Основное требование к мидл-разработчику — способность самостоятельно выполнять поставленные перед ним задачи. Очень похоже на то, что было написано в предыдущем пункте, правда? Однако есть важный нюанс — здесь отсутствует слово «технические». То есть на новом уровне нужно понимать требования бизнеса и уметь переводить их в технические решения.

      Таким образом:

      1. Мидл-разработчик понимает, что именно делает приложение. Это позволяет глубже понять задачу, а, значит, точнее ее оценить и качественнее реализовать. Если требования не полностью покрывают какой-то сценарий, хороший разработчик обратит на это внимание на этапе планирования. А не когда приложение начнет валиться при любом нестандартном действии пользователя.
      2. Мидл-разработчик знаком со стандартными шаблонами и решениями при построении приложения в своей области, понимает, зачем они нужны, и умеет их применять. Стандартизация решений имеет большое значение при коллективной разработке кода, т. к. позволяет новому человеку быстрее разобраться, что к чему, и минимизирует количество ошибок. Понимание структуры типового приложения делает задачу его построения с нуля достаточно тривиальной, позволяет рассуждать о принципах правильной реализации и отличать хороший код от плохого.
      3. Мидл-разработчик понимает, что работает не один. Он умеет взаимодействовать с другими членами команды: может обсудить сложный момент с дизайнером, уточнить у бизнес-аналитика неполные требования или согласовать какое-то важное техническое решение с архитектором проекта (если такой есть) и, конечно, владеет соответствующими инструментами коллективной разработки.
    • Senior:

      Senior – разработчик высокого уровня, повидавший много кода, набивший кучу шишек и сумевший сделать из этого правильные выводы. Основная задача синьора — принимать правильные технологические решения в проекте. «Правильные» — это такие, которые приносят максимальную пользу бизнесу и минимизируют затраты. Хороший синьор не только понимает, что разрабатывает команда, но думает, какие задачи должно решить готовое приложение. Разрабатывая площадку для аукциона, синьор всегда задается вопросом о пиковой нагрузке и старается предусмотреть попытки конкурентной записи в таблицы БД. Он заранее думает об узких местах системы, о возможности ее масштабирования, помнит об уязвимостях и проблемах, вызванных неправильным использованием инструментов.

      Такой специалист делает удивительную вещь — решает проблемы еще до того, как они появились. Со стороны это напоминает дар предвидения. А вот если ваш проект живет от пожара до пожара, а вам постоянно приходится выкидывать и переписывать куски кода — это симптомы, что проект получает недостаточно синьорного внимания.
  5. Дизайнер:

    Дизайнер – тот человек, который занимается дизайном. Логично, не правда ли?

    Работа дизаи?нера начинается задолго до того, как появляется первыи? пиксель, и заканчивается намного позже последнего.

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

    Дело в том, что для решения задачи недостаточно нарисовать картинку. В процессе работы хороший дизайнер проходит шесть шагов. Вот они:
    • Понимание проблемы:

      Работа начинается с понимания проблемы, как театр с вешалки: пока не сдашь верхнюю одежду, дальше не пройдешь. Если не вникнуть в проблему, получится нежизнеспособный продукт.
    • Поиск решения:

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

      Это как раз и есть рисование картинок и подбор шрифтов. Многие дизайнеры начинают отсюда и тут же заканчивают работу, а результаты работы таких дизайнеров можно в больших количествах увидеть на Дриббле или Бехэнсе.
    • Согласование:

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

    Ну вот, теперь, наконец, ты знаком со всеми должностями в командной разработке. Здесь я перечислил лишь те должности, которые связанны с программированием. Если рассматривать разработку программного продукта в качестве бизнес-проекта, то конечно же там добавятся еще роли, например, бухгалтеры, маркетологи и т.д.

Заключение


Чтож, если ты дочитал до этого момента – поздравляю, ты нереально крут! Нет, ну правда, у тебя мозг еще не вскипел от такого количества информации? Надеюсь, что нет.

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

Спасибо за внимание!

Статья написана в сотрудничестве с RicardoMilos




К сожалению, не доступен сервер mySQL