Написать пост

Использование Git: советы и трюки для продвинутых пользователей

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

114 открытий573 показов
Использование Git: советы и трюки для продвинутых пользователей

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

Вместе с менторами Solvery разбираемся, как продвинутые пользователи могут сделать работу с Git еще более продуктивной. Ниже — советы по эффективной настройке, работе с ветками и автоматизации.

Как настроить Git

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

Цветной вывод команд (color.ui)

Включение цветового оформления в выводе Git значительно повышает читаемость и удобство работы. Цвета помогают быстро различать добавленные, измененные и удаленные строки, а также выделяют конфликтные участки при слиянии веток.

			git config --global color.ui auto
		

Создание алиасов (alias)

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

			git config --global alias.st status
git config --global alias.br branch


		

После этого вы быстро можете выполнять команды git status и git branch с помощью сокращений git st, git co и git br соответственно.

Настройка редактора по умолчанию (core.editor)

По умолчанию Git использует системный текстовый редактор (обычно Vim или Nano) для ввода сообщений коммита и редактирования файлов при слиянии. Вы можете изменить это поведение, указав предпочитаемый редактор, такой как Visual Studio Code или другой.

Хотите VSCode, вводите:

			git config --global core.editor "code --wait"
		

Флаг --wait необходим для того, чтобы Git ожидал закрытия файла в VSCode перед продолжением выполнения команды. Это важно, иначе Git может завершить процесс до того, как вы закончите редактирование.

Работа с ветками и коммитами

В проекте может быть огромное количество веток, и между ними нужно легко и быстро переключаться. Ниже рассмотрим основные моменты.

Используйте осмысленные названия веток, группируя их по префиксам

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

  • feature/ – для новых функций. Пример: feature/user-authentication
  • bugfix/ – для исправления ошибок. Пример: bugfix/login-error
  • hotfix/ – для срочных исправлений в продакшене. Пример: hotfix/crash-on-startup
  • release/ – для подготовки релизов. Пример: release/v1.2.0
  • Применяйте команду git branch --list с фильтрами

Для фильтрации и поиска веток используйте команду git branch --list с соответствующими шаблонами:

			git branch --list "feature/*"
		

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

-r для отображения только удалённых веток

-a для отображения всех веток (локальных и удалённых)

Используйте алиасы для быстрого переключения

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

			git config --global alias.co checkout
		

Пример использования алиаса после его создания:

			git co bugfix/fix-login-issue
		

Используйте инструменты с графическим интерфейсом

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

Популярные инструменты:

  • GitKraken — предлагает удобный интерфейс и мощные функции для управления ветками
  • SourceTree — бесплатный инструмент с поддержкой Git и Mercurial
  • Fork — быстрый и функциональный клиент для Git

Регулярно удаляйте устаревшие ветки

Удаление неиспользуемых веток помогает поддерживать чистоту репозитория и снижает путаницу.

Удаление локальной ветки:

			git branch -d old-feature-branch
		

Удаление удалённой ветки:

			git push origin --delete old-feature-branch
		
Убедитесь, что ветка действительно больше не нужна и все изменения в ней сохранены или слиты, прежде чем удалять её.

Эффективные стратегии ветвления

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

  • Git Flow: подходит для проектов с регулярными релизами

Основные ветки:

  • master (или main): содержит стабильный код, готовый к продакшену.
  • develop: основная ветка для интеграции новых функций и изменений.

Вспомогательные ветки:

  • feature/*: ветки для разработки новых функций.
  • release/*: ветки для подготовки релизов.
  • hotfix/*: ветки для срочных исправлений в продакшене.

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

  • GitHub Flow: более простая модель, ориентированная на непрерывную интеграцию и развёртывание (CI/CD)

Основные ветки:

  • main: единственная долговременная ветка, всегда содержит стабильный и готовый к развёртыванию код.

Вспомогательные ветки:

  • feature/*: короткоживущие ветки для разработки новых функций или исправлений.

GitHub Flow прост в освоении, подходит для проектов с непрерывным развёртыванием и быстро интегрирует изменения в основную ветку. Но в нем нет четкого разделения стадий разработки и релизов.

  • GitLab Flow: сочетает Git Flow и GitHub Flow

Основные ветки:

  • main: основная ветка разработки.
  • pre-production: ветка для подготовки к релизу и тестирования.
  • production: ветка, отражающая код, развёрнутый в продакшене.

Вспомогательные ветки:

  • feature/*: ветки для разработки новых функций.

В GitLab Flow есть гибкая настройка, четкое разделение стадий подготовки релизов и продакшена и поддержка интеграции с CI/CD пайплайнами. Однако настройка может быть более сложной, чем в случае с GitHub Flow.

  • Trunk-Based Development: подходит для небольших команд и частых деплоев

Основные ветки:

  • main (или trunk): единственная долговременная ветка, в которую вносятся все изменения.

Вспомогательные ветки:

  • Короткоживущие feature-ветки: существуют от нескольких часов до одного дня и быстро сливаются обратно в main.

Trunk-Based Development упрощает интеграцию изменений и снижает вероятность конфликтов, поддерживает частые релизы и быстрый цикл разработки и поощряет культуру непрерывной интеграции и доставки. Но при этом инструмент требует высокой дисциплины и автоматизированного тестирования.

Что такое rebase -i и когда он нужен

git rebase -i (интерактивный ребейз) — это мощный инструмент Git, позволяющий переписывать историю коммитов. Он используется для различных целей, включая объединение коммитов, изменение сообщений, удаление или переупорядочивание коммитов. Используйте rebase с осторожностью, так как происходит переписывание общей истории.

Для чего нужен:

  • Для «причесывания» истории перед слиянием feature branch в main. Перед слиянием вашей функциональной ветки (feature branch) в основную ветку (main), вы можете использовать интерактивный ребейз относительно main, чтобы очистить историю коммитов в вашей ветке 
			git rebase -i main
		
  • Команда git rebase -i HEAD~3 откроет интерактивный ребейз для последних трёх коммитов. Это позволяет объединить эти коммиты в один с помощью опций squash или fixup
			git rebase -i HEAD~3
		
  • с) Для удаления или переупорядочивания коммитов. Указав хэш коммита (<commit-hash>), вы начинаете интерактивный ребейз с родителя указанного коммита:
			git rebase -i commit-hash
		

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

Используйте структуру

<тип>(<область>): <краткое описание>

<подробное описание>

<ссылки на задачи или проблемы>

  • <тип>: описывает категорию изменений.
  • (<область>): необязательный параметр, указывающий часть кодовой базы, на которую влияют изменения.
  • <краткое описание>: лаконичное описание изменений (не более 50 символов).
  • Подробное описание: объясняет детали изменений и их причины.
  • Ссылки на задачи или проблемы: помогает связать коммит с конкретными задачами (например, Closes #123).

Придерживайтесь типов коммитов:

  • feat: новая функциональность
  • fix: исправление бага
  • docs: изменения в документации
  • style: форматирование, отсутствующие точки с запятой и т.д.
  • refactor: рефакторинг кода
  • test: добавление или изменение тестов
  • chore: обновление задач сборки, настроек менеджера пакетов и т.д.

Пишите краткое описание в повелительном наклонении:

Например, feat(auth): add password reset functionality или «Добавить поддержку новой библиотеки», «Исправить ошибку в функции обработки данных»

Ограничивайте длину строк

Заголовок: не более 50 символов.

Тело коммита: не более 72 символов в строке.

Работа с удаленными репозиториями

Удалённые репозитории — это хранилища, которые находятся на серверах, и к которым разработчики подключаются для обмена кодом. Вот несколько советов, чтобы оптимизировать работу с ними:

  • Используйте git fetch вместо git pull. Это позволяет просмотреть изменения перед слиянием:
			git fetch origin
git merge origin/main

		
  • Настройте git pull для использования rebase. Это поможет избежать лишних merge-коммитов:
			git config --global pull.rebase true
// Создает или изменяет настройку в вашем глобальном конфигурационном файле (~/.gitconfig). 
// Эта настройка будет использоваться как значение по умолчанию для новых клонированных репозиториев
// НЕ изменяет настройки в уже существующих репозиториях.
		
Изменение глобальной конфигурации pull.rebase повлияет на все репозитории на вашем компьютере. Убедитесь, что это изменение согласуется с рабочим процессом вашей команды.
  • Используйте git pull --ff-only для получения изменений без создания merge-коммита:
			git pull --ff-only origin main
		
Fast-forward происходит, когда текущая ветка может быть просто передвинута вперёд до состояния удалённой ветки без необходимости создания нового merge-коммита. Это полезно для поддержания линейной истории коммитов и упрощения навигации по истории проекта. 
Артем Геташвилиментор Solvery
  • Перед pull или fetch убедитесь, что ваши локальные изменения сохранены:
			git stash save "Сохранение локальных изменений перед pull"
git pull
git stash pop

		

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

При работе над большими проектами также важно настроить синхронизацию. Вот основные хаки:

			git remote add upstream <repository-url>
		

origin: По умолчанию, это удалённый репозиторий вашего форка или основного репозитория проекта.

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

Пример просмотра списка всех удалённых репозиториев:

			git remote -v
		
  • Настройте push для синхронизации с нужным репозиторием:
			git push -u origin feature-branch
		

--set-upstream: Этот флаг устанавливает связку между вашей локальной веткой и удалённой веткой, позволяя в будущем использовать просто git push или git pull без указания удалённого репозитория и ветки.

Написание чётких сообщений коммитов для каждого атомарного изменения облегчает понимание истории изменений и упрощает процесс ревью кода.
  • Используйте git remote prune для удаления ссылок на несуществующие ветки:
			git remote prune origin
		

Проблема устаревших веток: Когда ветка удаляется из удалённого репозитория, Git по-прежнему хранит ссылку на неё в вашем локальном репозитории.

Решение: git remote prune удаляет такие устаревшие ссылки, поддерживая ваш репозиторий в актуальном состоянии.

Пример предварительного просмотра веток, которые будут удалены при git remote prune:

			git remote prune origin --dry-run
		

Как избежать конфликтов при мерже и ребейзе

  • Регулярно синхронизируйте свою ветку с основной:
			git checkout feature-branch
git rebase main
git status

		

Если ребейз нежелателен, можно использовать git merge main для интеграции изменений из основной ветки. Это сохранит историю коммитов неизменной, но может добавить merge-коммиты.

  • Разбивайте большие изменения на мелкие, атомарные коммиты:
			git add -p
git commit -m "Add new feature: step 1"

		
Написание чётких сообщений коммитов для каждого атомарного изменения облегчает понимание истории изменений и упрощает процесс ревью кода.
  • Используйте инструменты для визуализации веток:
			git log --graph --oneline --all
		

Или GitKraken, SourceTree и Git Extensions в качестве удобных графических интерфейсов для визуализации истории.

  • При возникновении конфликтов используйте инструменты для их разрешения:
			git mergetool
		

Используйте популярные мердж-тулы, такие как:

  • KDiff3 — есть поддержка трёхстороннего слияния, автоматическое обнаружение конфликтов.
  • Meld — интуитивно понятный интерфейс, поддержка сравнения и слияния файлов.
  • Beyond Compare — мощные возможности сравнения, интеграция с различными системами контроля версий.
  • P4Merge — бесплатный инструмент с поддержкой визуального слияния, интеграция с Perforce.

Пример:

			git config --global merge.tool meld
		

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

При работе с большими проектами часто возникают проблемы с производительностью Git. Это связано с тем, что репозитории могут содержать множество файлов или объёмные данные, которые усложняют управление историей изменений. Вот несколько советов:

  • Используйте shallow clone для получения только последних изменений:
			git clone --depth 1
		

Возвращение к обычному клону:

			git fetch --unshallow
		
  • Команда, которая выполняет сборку мусора, удаляет ненужные файлы и оптимизирует базу данных Git:
			git gc
		

git gc --aggressive — это команда для агрессивной оптимизации репозитория Git. Применяйте ее очень аккуратно, так как она выполняет несколько операций: переупаковка всех объектов в репозитории, максимальное сжатие данных и удаление недостижимых объектов, что может привести к удалению коммитов и файлов в Git, а также увеличению времени работы.

  • Настройте .gitignore для исключения ненужных файлов:
			*.log
node_modules/
build/

		

Есть репозиторий с шаблоном для вашего любимого ЯП.

  • Применяйте sparse-checkout для работы только с нужными директориями:
			git clone --no-checkout https://github.com/example/large-repo.git
cd large-repo
git sparse-checkout init --cone
git sparse-checkout set dir1 dir2
git checkout

		
  • --no-checkout: При клонировании репозитория файлы не будут автоматически извлечены. 
  • git sparse-checkout init: Инициализирует режим sparse-checkout. 
  • git sparse-checkout set dir1 dir2: Указывает директории или файлы, которые вы хотите извлечь.

Автоматизация в Git

Одной из продвинутых возможностей Git является использование хуков (hooks) — это специальные скрипты, которые автоматически выполняются при наступлении определённых событий, таких как создание коммита или переключение ветки. Хуки помогают автоматизировать различные задачи, например, проверку кода перед коммитом или запуск тестов. Это значительно упрощает процесс разработки и делает его более надёжным. Ниже — несколько основных советов.

  • pre-commit: проверка кода перед коммитом:
			#!/bin/sh
npm run lint
npm test

		

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

  • prepare-commit-msg: автоматическое добавление префикса к сообщению коммита:
			#!/bin/sh
BRANCH_NAME=$(git symbolic-ref --short HEAD)
sed -i.bak -e "1s/^/[$BRANCH_NAME] /" $1

		

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

  • post-commit: автоматическое обновление документации:
			#!/bin/sh
npm run generate-docs
git add docs/
git commit --amend --no-edit  // может привести к проблемам при совместной работе, так как изменяет уже созданный коммит
		

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

  • pre-push: запуск тестов перед отправкой изменений:
			#!/bin/sh
npm run test:full
		

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

Для настройки hooks:

  1. Создайте файлы в .git/hooks/
  2. Сделайте их исполняемыми: chmod +x .git/hooks/pre-commit
  3. Для совместного использования, храните hooks в репозитории и используйте симлинки или git config core.hooksPath
Важно: Локальные хуки не передаются при клонировании репозитория. Это означает, что каждый разработчик должен настраивать хуки вручную или использовать общий путь для хуков через core.hooksPath, если нужно обеспечить одинаковое поведение в команде.

Бесшовная интеграция с CI/CD

Git тесно интегрируется с системами непрерывной интеграции и доставки (CI/CD), что позволяет автоматически запускать сборки, тесты и деплой проекта. Это помогает сократить время на ручные операции и снизить вероятность ошибок. Ниже моменты, которые нужно учесть.

  • Используйте .gitlab-ci.yml или .github/workflows для определения пайплайнов

Файлы конфигурации .gitlab-ci.yml для GitLab или .github/workflows для GitHub Actions определяют последовательность шагов (jobs) и условий их выполнения (triggers) в процессе CI/CD. Эти файлы хранятся в корне репозитория и автоматически используются системами CI/CD при определённых событиях.

  • Настройте автоматический запуск тестов при пуше:
			# .github/workflows/ci.yml
name: CI

on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v3
      - name: Install dependencies
        run: npm ci
      - name: Run tests
        run: npm test

		

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

  • Автоматизируйте деплой при мерже в main:
			# .github/workflows/deploy.yml
name: Deploy

on:
  push:
    branches: [ main ]

jobs:
  deploy:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v2
      - name: Install dependencies
        run: npm ci
      - name: Build
        run: npm run build
      - name: Deploy
        run: npm run deploy

		

Автоматизация развертывания (деплоя) при мерже изменений в основную ветку (main) обеспечивает быстрый и надёжный процесс доставки обновлений в продакшен. Это минимизирует человеческий фактор и ускоряет выпуск новых версий.

  • Используйте git tags для управления релизами:
			# .github/workflows/release.yml
name: Release

on:
  push:
    tags:
      - 'v*'

jobs:
  build:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v2
      - name: Install dependencies
        run: npm ci
      - name: Build
        run: npm run build
      - name: Publish
        run: npm publish

		

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

Вместо заключения

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

  • Установите чёткие правила именования веток и коммитов
  • Настройте автоматическое форматирование кода
  • Настройте систему непрерывной интеграции для автоматических проверок при каждом пуше
Выстраивайте процессы разработки в компании так, чтобы над одной веткой работал один человек в течении короткого времени и мержил её в основную ветку. Тогда 99% проблем, с которыми вы можете столкнуться, потеряют свою актуальность.
Евгений Павловментор Solvery
Следите за новыми постами
Следите за новыми постами по любимым темам
114 открытий573 показов