2.2 Git и системы контроля версий

2.2 Git и системы контроля версий #

🎯 Зачем нужен Git #

Git — это система контроля версий, которая отслеживает изменения в файлах и позволяет:

  • Сохранять историю изменений
  • Работать в команде без конфликтов
  • Откатываться к предыдущим версиям
  • Создавать ветки для экспериментов

Без Git:

project_v1.zip
project_v2.zip  
project_v2_final.zip
project_v2_final_REALLY_FINAL.zip
project_v2_final_REALLY_FINAL_fixed.zip

С Git:

git log --oneline
a1b2c3d Add user authentication
d4e5f6g Fix login bug  
g7h8i9j Update documentation
j1k2l3m Initial commit

⚙️ Основы Git #

Установка и настройка #

# Установка (Ubuntu/Debian)
sudo apt update && sudo apt install git

# Первоначальная настройка
git config --global user.name "Ваше Имя"
git config --global user.email "your.email@example.com"
git config --global init.defaultBranch main

# Проверка настроек
git config --list

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

# Новый проект
mkdir my-project && cd my-project
git init

# Клонирование существующего
git clone https://github.com/user/repo.git
cd repo

Основной workflow #

# 1. Проверить статус
git status

# 2. Добавить файлы в staging
git add file.txt          # конкретный файл
git add .                 # все изменения
git add *.py             # по маске

# 3. Создать коммит
git commit -m "Add user registration feature"

# 4. Отправить на сервер
git push origin main

🌿 Работа с ветками (Branching) #

Зачем нужны ветки #

main branch:     A---B---C---F---G
                  \         /
feature branch:    D---E---/

A,B,C - стабильный код
D,E   - новая фича
F     - merge фичи в main
G     - дальнейшая разработка

Основные команды веток #

# Посмотреть ветки
git branch                # локальные ветки
git branch -r            # удаленные ветки  
git branch -a            # все ветки

# Создать и переключиться на ветку
git checkout -b feature/user-auth
# или новым способом
git switch -c feature/user-auth

# Переключиться на существующую ветку
git checkout main
git switch main

# Удалить ветку
git branch -d feature/user-auth    # только если смержена
git branch -D feature/user-auth    # принудительно

Слияние веток (Merge) #

# Переключиться на main
git checkout main

# Способ 1: Слить ветку feature (создает merge коммит)
git merge feature/user-auth

# Способ 2: Rebase для линейной истории (без merge коммита)
git rebase main feature/user-auth    # переносит коммиты на верх main
git checkout main
git merge feature/user-auth          # fast-forward merge

# Интерактивный rebase для очистки истории
git rebase -i HEAD~3                 # объединить/изменить последние 3 коммита

# Если есть конфликты - решить их и:
git add .
git commit -m "Resolve merge conflicts"  # для merge
# или
git rebase --continue                     # для rebase

🔄 Git Flow стратегии #

1. GitHub Flow (простая) #

main ←------ feature/login
     ←------ feature/payments  
     ←------ hotfix/security-bug

Процесс:

  1. Создаем ветку от main
  2. Разрабатываем фичу
  3. Создаем Pull Request
  4. После review мержим в main
  5. Удаляем ветку

2. Git Flow (сложная) #

main     ←------ release/v1.0 ←------ develop
hotfix   ↗                            ↑
         main                         feature

Ветки:

  • main — продакшн код
  • develop — разработка
  • feature/ — новые фичи
  • release/ — подготовка релиза
  • hotfix/ — срочные исправления

3. Trunk-based (для CI/CD) #

main: A---B---C---D---E---F---G
       \     /     \   /
        X---Y       Z-/

Короткоживущие ветки, частые мержи

📝 Хорошие практики коммитов #

Структура коммита #

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

Более подробное описание того, что и зачем
было сделано. Максимум 72 символа в строке.

- Добавлен валидация email
- Исправлена ошибка с регистрацией
- Обновлена документация API

Fixes #123

Типы коммитов #

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

# Примеры
git commit -m "feat(auth): add user registration endpoint"
git commit -m "fix(login): resolve session timeout issue"
git commit -m "docs(api): update authentication guide"

Плохие vs хорошие коммиты #

# ❌ Плохие коммиты
git commit -m "fix"
git commit -m "stuff"
git commit -m "changes"
git commit -m "asdfgh"

# ✅ Хорошие коммиты  
git commit -m "fix(auth): resolve JWT token expiration"
git commit -m "feat(user): add profile picture upload"
git commit -m "refactor(db): optimize user queries performance"

🐙 GitHub/GitLab для команд #

Pull Requests / Merge Requests #

Создание PR:

# 1. Пушим ветку
git push origin feature/user-profile

# 2. На GitHub создаем PR через веб-интерфейс
# 3. Добавляем описание, reviewers, labels

Шаблон описания PR:

## Что сделано
- Добавлена страница профиля пользователя
- Реализована загрузка аватара
- Добавлены тесты для новой функциональности

## Как тестировать
1. Зайти на /profile
2. Загрузить картинку
3. Проверить сохранение настроек

## Скриншоты
![Profile page](screenshot.png) - 2.2

## Checklist
- [x] Тесты написаны и проходят
- [x] Документация обновлена
- [x] Нет конфликтов с main
- [x] Проведен code review

Code Review процесс #

Reviewer проверяет:
✅ Логику кода
✅ Безопасность  
✅ Производительность
✅ Тесты
✅ Соответствие стандартам команды

Типичные комментарии:
💡 "Можно использовать more efficient алгоритм"
🐛 "Здесь может возникнуть NullPointerException"
📝 "Добавьте комментарий к сложной логике"
✨ "Отличное решение!"

🔧 Git в DevOps workflow #

Pre-commit hooks #

#!/bin/sh
# .git/hooks/pre-commit

echo "Running pre-commit checks..."

# Запуск линтера
npm run lint
if [ $? -ne 0 ]; then
  echo "❌ Linting failed. Please fix errors before committing."
  exit 1
fi

# Запуск тестов
npm test
if [ $? -ne 0 ]; then
  echo "❌ Tests failed. Please fix tests before committing."
  exit 1  
fi

echo "✅ All checks passed!"

Git + CI/CD интеграция #

# .github/workflows/ci.yml
name: CI/CD Pipeline
on:
  push:
    branches: [main, develop]
  pull_request:
    branches: [main]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      
      - name: Setup Node.js
        uses: actions/setup-node@v2
        with:
          node-version: '16'
          
      - name: Install dependencies
        run: npm ci
        
      - name: Run tests
        run: npm test
        
      - name: Run linter
        run: npm run lint
        
  deploy:
    needs: test
    runs-on: ubuntu-latest
    if: github.ref == 'refs/heads/main'
    steps:
      - name: Deploy to production
        run: |
          echo "Deploying to production..."
          # Команды деплоя

🔍 Полезные Git команды #

История и логи #

# Красивый лог
git log --oneline --graph --decorate --all

# Поиск в истории
git log --grep="auth"              # поиск в сообщениях коммитов
git log -S "function_name"         # поиск добавления/удаления кода
git log --author="John Doe"        # коммиты автора

# Изменения в файле
git log -p filename.txt            # все изменения файла
git blame filename.txt             # кто что менял

Отмена изменений #

# Отменить изменения в рабочей директории
git checkout -- file.txt          # один файл
git checkout .                     # все файлы

# Убрать из staging
git reset HEAD file.txt            # один файл
git reset HEAD                     # все файлы

# Отменить последний коммит (но сохранить изменения)
git reset --soft HEAD~1

# Отменить последний коммит (и удалить изменения)
git reset --hard HEAD~1

# Создать коммит, отменяющий предыдущий
git revert HEAD

Stashing (временное сохранение) #

# Сохранить текущие изменения
git stash
git stash push -m "Work in progress on feature X"

# Посмотреть stashes
git stash list

# Применить stash
git stash pop                      # применить и удалить
git stash apply                    # применить, но оставить в stash

# Удалить stash
git stash drop stash@{0}
git stash clear                    # удалить все

🎯 Практические сценарии #

Сценарий 1: Hotfix в продакшене #

# 1. Создать hotfix ветку от main
git checkout main
git pull origin main
git checkout -b hotfix/security-fix

# 2. Исправить проблему
vim security_patch.py
git add security_patch.py
git commit -m "fix(security): patch SQL injection vulnerability"

# 3. Смержить в main
git checkout main
git merge hotfix/security-fix

# 4. Создать тег релиза
git tag -a v1.0.1 -m "Security hotfix"

# 5. Задеплоить и очистить
git push origin main --tags
git branch -d hotfix/security-fix

Сценарий 2: Разрешение конфликтов #

# При merge возник конфликт
git merge feature/payments
# CONFLICT (content): Merge conflict in app.py

# Открыть файл, увидеть:
<<<<<<< HEAD
def calculate_total(items):
    return sum(item.price for item in items)
=======
def calculate_total(items):
    return sum(item.price * item.quantity for item in items)
>>>>>>> feature/payments

# Разрешить конфликт:
def calculate_total(items):
    return sum(item.price * item.quantity for item in items)

# Завершить merge
git add app.py
git commit -m "Resolve merge conflict in calculate_total"

🛡️ Безопасность в Git #

Что НИКОГДА не коммитить #

# ❌ Секреты и пароли
DATABASE_PASSWORD=supersecret123
API_KEY=sk-1234567890abcdef

# ❌ Конфиденциальные файлы
.env
secrets.json
private_key.pem
*.p12

# ❌ Большие бинарные файлы  
video.mp4
database.dump
node_modules/

.gitignore файл #

# Dependencies
node_modules/
vendor/

# Environment variables
.env
.env.local
.env.production

# Logs
*.log
logs/

# OS generated files
.DS_Store
Thumbs.db

# IDE files
.vscode/
.idea/
*.swp

# Build outputs
dist/
build/
*.pyc

Git-crypt для чувствительных данных #

# Установка git-crypt
sudo apt install git-crypt

# Инициализация в репозитории
git-crypt init

# Настройка .gitattributes
echo "secrets.json filter=git-crypt diff=git-crypt" >> .gitattributes

# Добавление GPG ключа пользователя
git-crypt add-gpg-user user@example.com

# Теперь secrets.json будет зашифрован в Git

📚 Полезные ресурсы #

Обучающие материалы #

Инструменты #

  • GitKraken - GUI клиент для Git
  • SourceTree - бесплатный GUI от Atlassian
  • VS Code - отличная встроенная поддержка Git
  • git-flow - расширение для Git Flow workflow

Cheat sheets #

# Полезные алиасы для .gitconfig
[alias]
  st = status
  co = checkout
  br = branch
  ci = commit
  unstage = reset HEAD --
  last = log -1 HEAD
  visual = !gitk
  lg = log --oneline --graph --decorate --all
  amend = commit --amend --no-edit

🎯 Практические задания #

Задание 1: Основы Git (45 минут) #

# 1. Настройка Git (если еще не сделано)
git config --global user.name "Ваше Имя"
git config --global user.email "your.email@example.com"
git config --global init.defaultBranch main

# 2. Создайте новый проект
mkdir ~/git-practice
cd ~/git-practice
git init

# 3. Создайте базовую структуру проекта
cat > README.md << 'EOF'
# Git Practice Project

Проект для изучения основ Git и GitHub.

## Описание
Этот проект создан для практики работы с Git.

## Автор
Ваше имя
EOF

# 4. Создайте файл .gitignore
cat > .gitignore << 'EOF'
# Временные файлы
*.tmp
*.swp
*~

# Логи
*.log
logs/

# Зависимости
node_modules/
.env
EOF

# 5. Сделайте первый коммит
git add README.md .gitignore
git commit -m "Initial commit: add README and .gitignore"

# 6. Создайте файл с кодом
mkdir src
cat > src/app.py << 'EOF'
#!/usr/bin/env python3
"""
Простое приложение для демонстрации Git workflow
"""

def greet(name):
    """Функция приветствия"""
    return f"Привет, {name}!"

def main():
    """Главная функция"""
    user_name = "DevOps Engineer"
    message = greet(user_name)
    print(message)

if __name__ == "__main__":
    main()
EOF

# 7. Добавьте коммит с кодом
git add src/app.py
git commit -m "Add basic Python application"

# 8. Создайте ветку для новой функции
git checkout -b feature/add-config

# 9. Добавьте конфигурационный файл
mkdir config
cat > config/settings.yaml << 'EOF'
app:
  name: "Git Practice App"
  version: "1.0.0"
  debug: true

logging:
  level: "INFO"
  format: "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
EOF

# 10. Коммит в feature ветке
git add config/settings.yaml
git commit -m "Add application configuration"

# 11. Переключитесь обратно в main и смержите
git checkout main
git merge feature/add-config

# 12. Проверьте историю
git log --oneline --graph

Проверка: У вас должен быть репозиторий с несколькими коммитами и смерж из feature ветки.

Задание 2: Работа с конфликтами (30 минут) #

# 1. Создайте две ветки для симуляции конфликта
git checkout -b feature/update-readme-v1
git checkout -b feature/update-readme-v2

# 2. В первой ветке измените README
git checkout feature/update-readme-v1
cat > README.md << 'EOF'
# Git Practice Project

Проект для изучения основ Git и GitHub.

## Описание
Этот проект создан для практики работы с Git.
Добавлены новые возможности для управления конфигурацией.

## Возможности
- Базовое приложение на Python
- YAML конфигурация
- Гибкие настройки логирования

## Автор
Ваше имя
EOF

git add README.md
git commit -m "Update README: add features section"

# 3. Во второй ветке тоже измените README (в том же месте)
git checkout feature/update-readme-v2
cat > README.md << 'EOF'
# Git Practice Project

Проект для изучения основ Git и GitHub.

## Описание
Этот проект создан для практики работы с Git.
Включает примеры лучших практик DevOps.

## Технологии
- Python 3
- YAML для конфигурации
- Git для контроля версий

## Автор
Ваше имя
EOF

git add README.md
git commit -m "Update README: add technologies section"

# 4. Смержите первую ветку в main
git checkout main
git merge feature/update-readme-v1

# 5. Попробуйте смержить вторую (получите конфликт)
git merge feature/update-readme-v2

# 6. Разрешите конфликт вручную
# Откройте README.md в редакторе и объедините изменения
cat > README.md << 'EOF'
# Git Practice Project

Проект для изучения основ Git и GitHub.

## Описание
Этот проект создан для практики работы с Git.
Добавлены новые возможности для управления конфигурацией.
Включает примеры лучших практик DevOps.

## Возможности
- Базовое приложение на Python
- YAML конфигурация
- Гибкие настройки логирования

## Технологии
- Python 3
- YAML для конфигурации
- Git для контроля версий

## Автор
Ваше имя
EOF

# 7. Завершите merge
git add README.md
git commit -m "Merge feature/update-readme-v2: resolve conflict"

# 8. Посмотрите на итоговую историю
git log --oneline --graph --all

Проверка: Вы должны успешно разрешить конфликт и увидеть merge commit в истории.

Задание 3: GitHub workflow (40 минут) #

# 1. Создайте репозиторий на GitHub (через веб-интерфейс)
# Название: git-devops-practice
# Публичный репозиторий
# Не создавайте README (у нас уже есть)

# 2. Подключите локальный репозиторий к GitHub
git remote add origin https://github.com/ВАШ-USERNAME/git-devops-practice.git

# 3. Пушните код на GitHub
git push -u origin main

# 4. Создайте новую ветку для фичи
git checkout -b feature/add-tests

# 5. Добавьте файл с тестами
mkdir tests
cat > tests/test_app.py << 'EOF'
#!/usr/bin/env python3
"""
Тесты для приложения
"""
import sys
import os
sys.path.append(os.path.join(os.path.dirname(__file__), '..', 'src'))

from app import greet

def test_greet():
    """Тест функции приветствия"""
    result = greet("DevOps")
    expected = "Привет, DevOps!"
    assert result == expected, f"Expected '{expected}', got '{result}'"
    print("✅ test_greet passed")

def test_greet_empty():
    """Тест с пустым именем"""
    result = greet("")
    expected = "Привет, !"
    assert result == expected, f"Expected '{expected}', got '{result}'"
    print("✅ test_greet_empty passed")

if __name__ == "__main__":
    test_greet()
    test_greet_empty()
    print("🎉 All tests passed!")
EOF

# 6. Добавьте простой скрипт для запуска тестов
cat > run_tests.sh << 'EOF'
#!/bin/bash

echo "🧪 Running tests..."
python3 tests/test_app.py

echo "🔍 Running code style checks..."
python3 -m py_compile src/app.py tests/test_app.py

echo "✅ All checks passed!"
EOF

chmod +x run_tests.sh

# 7. Коммит изменений
git add tests/ run_tests.sh
git commit -m "Add basic tests and test runner"

# 8. Пушните ветку на GitHub
git push origin feature/add-tests

# 9. Создайте Pull Request через веб-интерфейс GitHub
# - Перейдите на GitHub
# - Нажмите "Compare & pull request"
# - Заполните описание PR
# - Создайте PR

Задание 4: GitHub Actions CI/CD (35 минут) #

# 1. Создайте каталог для GitHub Actions
mkdir -p .github/workflows

# 2. Создайте workflow файл
cat > .github/workflows/ci.yml << 'EOF'
name: CI/CD Pipeline

on:
  push:
    branches: [ main, develop ]
  pull_request:
    branches: [ main ]

jobs:
  test:
    runs-on: ubuntu-latest
    
    steps:
    - uses: actions/checkout@v3
    
    - name: Set up Python 3.9
      uses: actions/setup-python@v3
      with:
        python-version: 3.9
    
    - name: Install dependencies
      run: |
        python -m pip install --upgrade pip
        # pip install -r requirements.txt  # если есть файл зависимостей
    
    - name: Run tests
      run: |
        python tests/test_app.py
    
    - name: Check code syntax
      run: |
        python -m py_compile src/app.py
        python -m py_compile tests/test_app.py
    
    - name: Run application
      run: |
        python src/app.py
  
  security-scan:
    runs-on: ubuntu-latest
    
    steps:
    - uses: actions/checkout@v3
    
    - name: Run security scan
      run: |
        echo "🔍 Running security checks..."
        # Проверяем, что нет секретов в коде
        if grep -r "password\|secret\|key\|token" --include="*.py" --include="*.yaml" .; then
          echo "❌ Potential secrets found in code!"
          exit 1
        else
          echo "✅ No secrets detected"
        fi
    
  build:
    needs: [test, security-scan]
    runs-on: ubuntu-latest
    
    steps:
    - uses: actions/checkout@v3
    
    - name: Build application
      run: |
        echo "🏗️ Building application..."
        mkdir -p dist
        cp -r src/ dist/
        cp -r config/ dist/
        cp README.md dist/
        echo "✅ Build completed"
    
    - name: Archive build artifacts
      uses: actions/upload-artifact@v3
      with:
        name: application-build
        path: dist/
EOF

# 3. Коммит workflow
git add .github/workflows/ci.yml
git commit -m "Add GitHub Actions CI/CD pipeline"

# 4. Добавьте файл с зависимостями проекта
cat > requirements.txt << 'EOF'
# Производственные зависимости
pyyaml>=6.0

# Зависимости для разработки
pytest>=7.0
flake8>=4.0
EOF

git add requirements.txt
git commit -m "Add project dependencies"

# 5. Обновите workflow для использования requirements.txt
cat > .github/workflows/ci.yml << 'EOF'
name: CI/CD Pipeline

on:
  push:
    branches: [ main, develop ]
  pull_request:
    branches: [ main ]

jobs:
  test:
    runs-on: ubuntu-latest
    
    steps:
    - uses: actions/checkout@v3
    
    - name: Set up Python 3.9
      uses: actions/setup-python@v3
      with:
        python-version: 3.9
    
    - name: Install dependencies
      run: |
        python -m pip install --upgrade pip
        pip install -r requirements.txt
    
    - name: Lint with flake8
      run: |
        # Остановить build если есть синтаксические ошибки
        flake8 src/ tests/ --count --select=E9,F63,F7,F82 --show-source --statistics
        # Предупреждения для остальных ошибок
        flake8 src/ tests/ --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics
    
    - name: Test with pytest
      run: |
        python tests/test_app.py
    
    - name: Run application smoke test
      run: |
        timeout 5s python src/app.py || test $? = 124
  
  security-scan:
    runs-on: ubuntu-latest
    
    steps:
    - uses: actions/checkout@v3
    
    - name: Run security scan
      run: |
        echo "🔍 Running security checks..."
        if grep -r "password\|secret\|key\|token" --include="*.py" --include="*.yaml" .; then
          echo "❌ Potential secrets found in code!"
          exit 1
        else
          echo "✅ No secrets detected"
        fi
  
  build:
    needs: [test, security-scan]
    runs-on: ubuntu-latest
    
    steps:
    - uses: actions/checkout@v3
    
    - name: Build application package
      run: |
        echo "🏗️ Building application..."
        mkdir -p dist
        cp -r src/ dist/
        cp -r config/ dist/
        cp requirements.txt dist/
        cp README.md dist/
        
        # Создание версии
        echo "1.0.0-$(git rev-parse --short HEAD)" > dist/VERSION
        
        echo "✅ Build completed"
    
    - name: Archive build artifacts
      uses: actions/upload-artifact@v3
      with:
        name: application-build-${{ github.sha }}
        path: dist/
EOF

git add .github/workflows/ci.yml
git commit -m "Update CI pipeline with linting and versioning"

# 6. Пушните все изменения
git push origin feature/add-tests

Проверка: После push на GitHub должен запуститься CI pipeline. Проверьте вкладку “Actions” в репозитории.

Задание 5: Продвинутые Git операции (25 минут) #

# 1. Интерактивный rebase для очистки истории
# Создайте несколько "грязных" коммитов
echo "debug line" >> src/app.py
git add src/app.py
git commit -m "debug"

echo "# TODO: fix this" >> src/app.py
git add src/app.py
git commit -m "wip"

echo "more debug" >> src/app.py
git add src/app.py
git commit -m "temp commit"

# 2. Используйте интерактивный rebase для очистки
git rebase -i HEAD~3
# В редакторе измените pick на squash для объединения коммитов
# pick → s (squash) для объединения в предыдущий коммит

# 3. Создайте signed коммиты (если настроен GPG)
git config --global commit.gpgsign true  # если есть GPG ключ

# 4. Создайте и примените патч
git format-patch -1 HEAD --stdout > my-feature.patch
# git apply my-feature.patch  # для применения в другом репозитории

# 5. Используйте git stash для временного сохранения
echo "temporary changes" >> README.md
git stash push -m "Temporary README changes"
git stash list
git stash pop

# 6. Работа с submodules (пример)
# git submodule add https://github.com/example/library.git lib/external
# git submodule init
# git submodule update

# 7. Продвинутый поиск в истории
# Найти когда была удалена строка
git log -S "deleted_text" --source --all

# Найти коммиты автора
git log --author="Your Name" --oneline

# Показать изменения в файле за период
git log --since="2 weeks ago" --until="1 week ago" -- src/app.py

# 8. Создайте alias для частых команд
git config --global alias.unstage 'reset HEAD --'
git config --global alias.last 'log -1 HEAD'
git config --global alias.visual '!gitk'
git config --global alias.pushf 'push --force-with-lease'

# 9. Настройте git hooks
cat > .git/hooks/pre-commit << 'EOF'
#!/bin/bash
echo "🔍 Running pre-commit checks..."

# Проверить синтаксис Python файлов
for file in $(git diff --cached --name-only --diff-filter=ACM | grep '\.py$'); do
    python -m py_compile "$file"
    if [ $? -ne 0 ]; then
        echo "❌ Syntax error in $file"
        exit 1
    fi
done

# Проверить на секреты
if git diff --cached | grep -E "(password|secret|key|token)" >/dev/null; then
    echo "❌ Potential secrets found in staged changes!"
    echo "Please remove sensitive data before committing."
    exit 1
fi

echo "✅ Pre-commit checks passed"
EOF

chmod +x .git/hooks/pre-commit

Проверка: Все Git операции должны выполняться без ошибок, pre-commit hook должен срабатывать при коммитах.

📊 Проверочный тест Git #

  1. Какая команда показывает различия между рабочей копией и staging area?
  2. Как отменить последний коммит, сохранив изменения в рабочей копии?
  3. Какая команда создает новую ветку и сразу переключается на неё?
  4. Как посмотреть историю коммитов в графическом виде в терминале?
  5. Как временно сохранить незакоммиченные изменения?

Ответы:

  1. git diff
  2. git reset --soft HEAD~1
  3. git checkout -b branch-name
  4. git log --oneline --graph --all
  5. git stash

🎯 Заключение #

Git — это основа современной разработки. Ключевые принципы:

Коммитьте часто маленькими логическими частями
Пишите понятные сообщения коммитов
Используйте ветки для всех изменений
Делайте code review перед мержем
Никогда не коммитьте секреты
Автоматизируйте проверки через CI/CD

Помните: Git — это не просто инструмент версионирования, это основа для командной работы и DevOps процессов.


Следующий раздел: 2.3 Docker и контейнеризация