Всё, что менеджеру проектов надо знать о Git

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

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

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

А вот GitHub, GitLab, Bitbucket — это веб-сервисы, которые работают поверх Git. Они дают сервера в интернете, где можно хранить копии репозиториев, и предлагают кучу инструментов для совместной работы.

Я использую гитхаб и в этой статье буду говорить о гитхабе.

Начнём с базового минимума: разберёмся, что такое репозиторий, коммит и ветка, научимся базовым командам. Менеджеру не особо важно уметь коммитить и пушить, но для понимания, что там с гитом делают разрабы, въехать в это надо.

Терминал или графический интерфейс (GUI): выбираем самый удобный способ

Работа через терминал

Собственно, заходим через терминал в папочку с гит-репозиторием и выполняем консольные команды. Классика, как она есть.

Плюсы:

  • Полный контроль. Вы можете выполнять любые команды, весь спектр возможностей гита, а не только те, которые вам дали разработчики графического клиента.
  • Универсальность. Терминал есть везде. Баш на линуксе, павершелл на винде, zsh на маке. На сервере может вообще, не быть гуя, тут-то умение работать через консоль вам пригодится.
  • Понимание процессов. Так лучше понимаешь, что происходит под капотом. Это помогает быстрее разбираться в сложных ситуациях.


Минусы:

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

Работа через GUI-клиенты (например, VSC с GitLens)

В VSC и Cursor есть встроенный инструмент для работы с гитом. Кроме того, есть прекрасное расширение GitLens, добавляющее множество возможностей. Я работаю именно так.

Плюсы:

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

Минусы (на них хотелось бы закрыть глаза, но увы):

  • Ограниченная функциональность. Я так и не понял, как жёстко откатить репо к определённому коммиту в VSC. Вот тут придёт на помощь терминал.
  • Поломки. Когда вы таки сломаете репо, починить его через графический интерфейс может и не получиться.

Какой итог

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

Словарь

Давайте разберёмся с базовыми понятиями, прежде, чем лезть в терминал.

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

Коммит (commit) — это состояние репозитория в определённый момент. Что-то вроде снимка. Вы можете в любой момент откатиться на любой коммит, это очень удобно. Коммит всегда сопровождается комментарием, что же в нём изменилось.

Ветка (branch) — ответвление кода. Каждый разработчик пишет каждую новую фичу в своей ветке, это пришло от наших предков-обезьян. Потом ветки вливаются в мастер ветку и становятся «реальностью». Главное правило — каждая новая фича делается в отдельной ветке, в мастер ничего не пушится.

Пуш (push) и Пул (pull) — это команды для синхронизации с удалённым репозиторием (например, на GitHub). 

  • push — отправить свои коммиты,
  • pull — забрать свежие изменения.

Путь проекта: от идеи до GitHub за 5 шагов

Итак, у нас есть папка с проектом на компьютере. Мы хотим начать вести его историю с помощью Git, а потом выгрузить на GitHub. Что делать? На самом деле, в VSC вам достаточно перейти на вкладку гита, нажать на кнопку инициализации и ввести имя репо. Если вы авторизованы в гитхабе, конечно. Через терминал чуть длиннее. Итак.

Инициализируем репозиторий

Для инициализации папки и превращения в репозиторий, заходим в неё в терминале и пишем (естественно, гит должен быть инсталлирован):

git init

Эта команда создаст внутри скрытую папку .git. Именно в ней Git будет хранить всю историю изменений. Всё, локальный репо создан.

Добавляем файлы под версионный контроль

Делается в два этапа. Укажем, какие именно файлы мы будем отслеживать. Например, мы создали index.html и style.css. Чтобы подготовить их к коммиту, используем команду git add.

Можно добавлять файлы по одному:
git add index.html

А можно добавить сразу все изменённые файлы в папке:
git add

Эта команда помещает файлы в так называемую «область подготовки» (staging area).

Фиксируем изменения (тот самый коммит)

Пора делать коммит — «снимок» состояния. У каждого коммита должно быть осмысленное сообщение, чтобы потом мы или коллеги поняли, что именно было сделано.

git commit -m "Первый коммит: создана структура проекта"

Ключ -m как раз позволяет написать сообщение прямо в команде. По-хорошему, в департаменте разработки должна быть система, в которой расписано, как комментировать коммиты. Если писать комментарии типа: «Мелкие фиксы», вы потом запутаетесь.

Привязываем к удалённому репозиторию

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

Для этого создаём пустой репозиторий на гитхабе, а потом выполняем в терминале команду:

git remote add origin https://github.com/твой_ник/твой_репозиторий.git

Эта команда говорит: «Дорогой Git, по этому адресу будет жить удалённая версия нашего репозитория, а звать её будем origin». Это стандартное имя для основного удалённого репозитория.

Отправляем изменения на GitHub

Теперь можем отправлять коммиты в «облако». Делаем это командой push. В первый раз она выглядит длинновато:

​git push -u origin main

Разберём:

  • push — команда «отправить».
  • origin — куда отправляем (то имя, что мы задали на предыдущем шаге).
  • main — какую ветку отправляем (main — обычно основная ветка в проекте).
  • -u — этот флаг создаёт связь между локальной и удалённой веткой. Благодаря ему в следующий раз достаточно будет написать просто git push.

При первом пуше через консоль GitHub попросит авторизоваться. В VSC вы авторизовались открытым ключом ранее.

Вот мы и прошли полный цикл: создали репозиторий, сделали первый коммит и отправили работу на GitHub. 

Теперь давайте разбираться с ветками.

Ветки

Работать в чистовой ветке — плохая идея, можно что-нибудь сломать.

Если вы хотите реализовать новую фичу, надо создавать новую ветку. В этом разделе полностью разберём работу с ветками.

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

Чтобы создать новую ветку, используем команду git branch:

git branch feature/header

Ветка создана, но мы всё ещё находимся в main. Чтобы перейти в новую ветку и начать в ней работать, нужна команда git checkout:

git checkout feature/header

Теперь мы находимся в своей личной «песочнице». Все коммиты, которые мы будем делать, сохранятся только в истории ветки feature/header и не повлияют на main.

Ваша локальная папка «переключится» на ветку, в ней будут файлы, соответствующие ветке.

Эти две команды можно объединить в одну, чтобы было быстрее:

git checkout -b feature/header

Эта команда сразу и создаст новую ветку, и переключит нас на неё. Флаг -b — это сокращение от branch.

Когда работа над задачей в ветке закончена и её изменения успешно слиты с main (как сливать ветки, опишу ниже), эту ветку можно и нужно удалить. Иначе она будет мешаться. Делаем это командой git branch с флагом -d (от delete):

git branch -d feature/header

Мы создали отдельную ветку, поработали в ней, сделали несколько коммитов, и теперь наша новая фича полностью готова. Теперь будем мёрджить.

Мёрджим

Слияние — это процесс переноса изменений (коммитов) из одной ветки в другую. В нашем случае мы хотим перенести всё, что сделали в ветке feature/header, в ветку main.

В VSC делается примерно по тому же принципу. Переключаемся в интерфейсе на main, пулим изменения, через контекстное меню инициируем слияение, выбираем ветку, которую будем вливать.

Делаем так:

  1. Переключаемся на целевую ветку. Сначала нужно перейти в ту ветку, с которой мы хотим объединить изменения. В нашем случае это main.

    git checkout main
  2. Обновляем основную ветку. Если работаете совместно, обязательно нужно спулить изменения из основной ветки, которые сделали другие разрабы.

    git pull origin main
  3. Выполняем слияние. Теперь в ветке main выполняем команду git merge и указываем имя ветки, из которой мы хотим забрать изменения.

    git merge feature/header

После этой команды Git попытается автоматически объединить две ветки. Он возьмёт все коммиты из feature/header, которых нет в main, и добавит их в неё.

Что такое коммит слияния

Чаще всего Git создаёт специальный коммит слияния (merge commit). Это коммит, у которого есть сразу два родителя — последний коммит в main до слияния и последний коммит в твоей рабочей ветке. Он наглядно показывает в истории, в какой момент произошло объединение веток.

Иногда, если с момента создания ветки feature/header в main не появилось новых коммитов, Git может выполнить так называемое «ускоренное слияние» (fast-forward). В этом случае он просто передвинет указатель ветки main на последний коммит из feature/header, не создавая отдельного коммита слияния.

Что делать с конфликтами

Иногда Git не может автоматически объединить ветки. Это происходит, если в обеих ветках были изменены одни и те же строки в одном и том же файле. Такая ситуация называется конфликтом слияния.

Git не знает, какую версию кода считать правильной, поэтому он останавливает слияние и просит нас решить этот конфликт ручками. 

Он помечает конфликтующие места в файлах специальными маркерами — <<<<<<<, =======, >>>>>>>

Наша задача — открыть эти файлы, посмотреть на изменения из обеих веток, решить, какой код оставить (или написать новый вариант), удалить маркеры Git и сохранить файлы.

В VSC вам покажут конфликты на разных вкладках с цветовой индикацией, там разруливать конфликты очень удобно.

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

Когда все конфликты будут решены, нужно будет снова добавить исправленные файлы командой git add и завершить слияние, создав коммит: git commit Git сам подставит стандартное сообщение о слиянии.

Проверяем историю и состояние

У Git есть простые команды, чтобы в любой момент разобраться в происходящем.

git status

Если бы нужно было выбрать только одну команду, которую стоит выучить, это была бы git status

Команда даёт ответ на три вопроса:

  • Какие файлы изменены, но ещё не подготовлены к коммиту? (Changes not staged for commit). Это файлы, которые мы поменяли, но ещё не добавили в «корзину» через git add.
  • Какие файлы готовы к коммиту? (Changes to be committed). Это то, что мы уже добавили через git add и что попадёт в следующий коммит.
  • Какие файлы Git ещё не отслеживает? (Untracked files). Это новые файлы в проекте, о которых Git пока ничего не знает.

git log

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

У неё есть много других полезных опций, которые делают вывод гораздо удобнее:

  • git log —oneline: показывает каждый коммит в одну строку: только хеш (уникальный идентификатор) и сообщение. Подходит для быстрого обзора истории.
  • git log —graph: Рисует текстовое «дерево», которое показывает, как ветки создавались, расходились и сливались обратно.
  • git log -p: Показывает не только информацию о коммитах, но и сами изменения в каждом из них. Удобно, чтобы найти, когда и где была добавлена конкретная строка кода.

Часто эти флаги комбинируют, например, git log --oneline --graph --all покажет краткую историю всех веток в виде наглядного дерева.

git diff

Команда git diff позволяет увидеть разницу между разными состояниями файлов. Иногда (всегда) полезно перед коммитом ещё раз проверить, какие именно изменения мы собираемся сохранить.

  • git diff: Показывает разницу между тем, что у нас сейчас в рабочих файлах, и тем, что было в последнем коммите. Мы увидим все изменения, которые ещё не были добавлены через git add.
  • git diff —staged (или —cached): Показывает изменения, которые мы уже подготовили к коммиту (добавили через git add), в сравнении с последним коммитом. Это наш шанс проверить, не добавили ли мы в коммит чего-то лишнего.

Как отменять и исправлять ошибки

Даже когда вы работаете с гитом давно и вроде как всё умеете, всё равно, возможны ошибки. К счастью почти всё можно исправить.

«Мы сделали коммит, но забыли добавить файл или опечатались в сообщении»

Забыли добавить файл или опечатались в описании коммита. Не беда.

Для этого есть команда git commit --amend (это «внести поправку» на английском). Она позволяет «дополнить» самый последний коммит.

  1. Если мы забыли добавить файл, просто сделаем это сейчас через git add забытый_файл.js.
  2. Выполняем команду: git commit --amend

И сразу откроется редактор, где мы сможем поправить сообщение коммита. Если мы просто хотели добавить файл, можем ничего не менять и сразу закрыть редактор. Git возьмёт новые изменения из git add, объединит их с предыдущим коммитом и создаст один исправленный коммит вместо старого.

Команду можно применять только для незапушенных коммитов.

«Мы случайно добавили лишний файл в „корзину“»

Мы готовим коммит, пишем git add, и внезапно понимаем, что в область подготовки улетел временный файл или что-то, что коммитить ещё рано.

Вообще, чтобы такого не было, надо пользоваться .gitignore

Чтобы убрать файл из области подготовки, но оставить его изменения в рабочей папке, используем команду git reset:

git reset HEAD <имя_лишнего_файла>

Команда git status после этого покажет, что файл снова находится в разделе «Changes not staged for commit».

«Мы хотим отменить все изменения в файле и вернуть его к последней сохранённой версии»

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

git checkout -- <имя_файла>

Будьте внимательны с этой командой, она затрёт вашу работу, причём без подтверждения. Применяйте, только если точно знаете, что делаете.

«Мы запушили коммит на GitHub, и с ужасом поняли, что он всё ломает»

Для безопасной отмены публичных коммитов есть команда git revert.

git revert <хеш_плохого_коммита>

Она не удаляет старый коммит. А создаёт новый, который делает ровно противоположные изменения. Если в плохом коммите мы добавили строку, revert-коммит её удалит. История проекта остаётся чистой и последовательной, а все члены команды легко смогут синхронизировать свои репозитории.

«Мы сделали несколько плохих коммитов локально и хотим их просто удалить»

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

git reset --hard HEAD~3

Эта команда удалит последние 3 коммита и вернёт состояние всех файлов к моменту до них. HEAD~3 означает «на 3 коммита назад от текущего».

Очень важно: git reset --hard переписывает историю и стирает изменения. Используем её только для локальных коммитов, которые ещё не были отправлены в общий репозиторий.

Pull Request как инструмент код ревью

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

Pull Request (PR) — это заявка на слияние собственной ветки с основной. Это не команда Git, а функция интерфейса GitHub.

В VSC также есть инструмент для создания пулл реквеста, его проверки, комментирования и утверждения.

Рабочий процесс в команде (Git Flow)

Вот как выглядит стандартный цикл работы над задачей от начала до конца:

  1. Обновление. Прежде чем начать новую задачу, обязательно спули последние изменения. VSC, кстати, умеет пулить автоматически.
    • git checkout main — переключаемся на основную ветку.
    • git pull origin main — забираем все свежие изменения с GitHub.
  2. Создание ветки. Создаём новую ветку для своей задачи от актуальной версии main. Название ветки должно отражать суть задачи (например, feature/user-login или fix/header-bug).
    • git checkout -b feature/user-login
  3. Работа и коммиты. Пишем код, делаем коммиты. Стараемся, чтобы каждый коммит был логически завершённым и имел понятное сообщение. Вообще, коммитить надо как минимум, раз в день.

Можем делать много мелких коммитов — перед созданием Pull Request их можно будет «причесать» с помощью интерактивного rebase.

  1. Пушим ветку на GitHub. Когда задача готова (или хотя бы готова к первой проверке), отправляем свою ветку на удалённый сервер.
    • git push -u origin feature/user-login
  2. Создание Pull Request. Заходим на сайт GitHub. Он, скорее всего, сам заметит новую ветку и предложит создать Pull Request. Нам откроется форма создания PR. Пишем нормальный заголовок (чтобы все всё поняли) и добавляем описание: что мы сделали, как это проверить, какие моменты могут быть неочевидны. Чем лучше мы опишем свою работу, тем проще коллегам будет её проверить.
  1. Код-ревью. Тут начинается самое интересное. Коллеги смотрят на предложенные нами изменения прямо в интерфейсе GitHub. Они могут оставлять комментарии к любой строке кода, задавать вопросы или просить исправить часть. Это и есть код-ревью.
  2. Доработка. Если коллеги попросили что-то изменить, мы продолжаем работать в своей ветке feature/user-login локально. Делаем новые коммиты, исправляем замечания и отправляем их на GitHub командой git push. Все новые коммиты автоматически добавятся в уже существующий Pull Request.
  3. Слияние (Merge). Когда все замечания устранены и команда дала нам всё окнула (обычно в GitHub ставят Approve), наш Pull Request готов к слиянию. Чаще всего это делает старший разработчик (или мы сами, если есть права). Он нажимает зелёную кнопку Merge pull request в интерфейсе GitHub.
  4. Уборка. После слияния наша ветка feature/user-login больше не нужна. Её можно удалить и на GitHub (обычно для этого есть специальная кнопка после мёрджа), и у себя локально (git branch -d feature/user-login).

Разумеется, вся эта история с пулл-реквестом нужна, только если вы работаете совместно.

git rebase —interactive 

Напоследок расскажу о ребейс.

Когда мы работаем над задачей, у нас может накопиться много «рабочих» коммитов: одно поправили, другое, третье. Хотелось бы не разводить мусор, а объединить их в один коммит перед вливанием.

Для такой уборки используем интерактивный режим git rebase -i. Его можно назвать «git commit --amend на стероидах».

Допустим, у нас в ветке есть 3 лишних коммита. Мы можем сказать Git: «Хотим пересмотреть последние 3 коммита»:

git rebase -i HEAD~3

Git откроет в терминале текстовый редактор со списком этих коммитов. Напротив каждого коммита будет стоять слово pick (выбрать).

Здесь мы можем давать команды:

  • pick: оставить коммит как есть;
  • reword: оставить коммит, но изменить его сообщение;
  • squash или s: объединить этот коммит с предыдущим. Можем написать новое, общее сообщение для них;
  • drop или d: просто удалить коммит.

Например, чтобы объединить три коммита в один, мы можем оставить pick у первого, а у второго и третьего заменить его на squash. Git выполнит слияние и предложит написать одно общее сообщение для нового коммита.

rebase — это инструмент, который переписывает историю. Он создаёт новые коммиты вместо старых. 

Всегда, всегда предупреждаем команду, если используем git rebase на публичных ветках (main, master) или любых других ветках, которые уже были отправлены на удалённый сервер и используются другими людьми.

Применение ребейс в чистовой ветке небезопасно. Эту команду можно полноценно применять только для наведения порядка в своей рабочей локальной ветке.


Если хотите разобраться с гитом глубже, читайте эту книжку.

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


Опубликовано

в

от

Метки:

Подпишитесь на новые посты, чтобы не пропускать их (РКН о сборе имейлов уведомлён должным образом):

Добавить комментарий

Предыдущий пост
Статья критикует распространённые «маразмы оптимизации»: потерю стратегии, экономию на ключевых…