← Назад к вопросам

Как будешь решать конфликт при слиянии?

1.0 Junior🔥 151 комментариев
#Инструменты и DevOps

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI2 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Решение конфликтов при слиянии (Git Merge)

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

Шаг 1: Понимание конфликта

Когда я выполню git merge или git rebase, Git может сказать:

AUTO_MERGE FAILED
CONFLICT (content): Merge conflict in src/components/Button.tsx

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

Типы конфликтов:

  1. Content conflict — изменения в коде в одном файле
  2. Delete/modify conflict — один удалил файл, другой изменил
  3. Rename conflict — разные переименования одного файла

Шаг 2: Локализация конфликтов

Сначала видно, какие файлы в конфликте:

git status
# On branch feature
# You have unmerged paths:
#   (use "git add <file>..." to mark resolution)
#   both modified: src/components/Button.tsx

Открываю файл в редакторе. Git автоматически маркирует конфликтные области:

// src/components/Button.tsx
function Button() {
<<<<<<< HEAD (current branch)
  return <button className="btn btn-primary">Click</button>;
=======
  return <button className="btn btn-secondary">Click</button>;
>>>>>>> feature-branch
}

Маркеры конфликта:

  • <<<<<<< HEAD — текущая ветка (куда я мержу)
  • ======= — разделитель
  • >>>>>>> branch-name — ветка, которую я мержу

Шаг 3: Анализ конфликта

Прежде чем просто выбирать один вариант, я:

  1. Понимаю контекст — почему эти изменения?

    • Смотрю коммиты в обеих ветках
    • Читаю комментарии в PR
    • Проверяю, не зависит ли один код от другого
  2. Определяю правильное решение — это может быть:

    • Взять полностью одну ветку
    • Взять полностью другую ветку
    • Объединить обе версии
    • Написать что-то совсем новое
# Просмотреть разные версии
git log --oneline HEAD -- src/components/Button.tsx
git log --oneline feature-branch -- src/components/Button.tsx

# Показать конфликтный файл из HEAD
git show HEAD:src/components/Button.tsx

# Показать конфликтный файл из другой ветки
git show feature-branch:src/components/Button.tsx

Шаг 4: Решение конфликта

Вариант 1: Взять нашу версию

git checkout --ours src/components/Button.tsx

Вариант 2: Взять их версию

git checkout --theirs src/components/Button.tsx

Вариант 3: Ручное разрешение (самый частый случай)

Открываю файл и вручную выбираю, что оставить:

// БЫЛО (конфликт):
<<<<<<< HEAD
  return <button className="btn btn-primary">Click</button>;
=======
  return <button className="btn btn-secondary">Click</button>;
>>>>>>> feature-branch

// СТАЛО (оба нужны?):
export interface ButtonProps {
  variant?: 'primary' | 'secondary';
}

function Button({ variant = 'primary' }: ButtonProps) {
  const className = `btn btn-${variant}`;
  return <button className={className}>Click</button>;
}

Этот подход часто лучше, чем просто выбирать один вариант.

Шаг 5: Использование инструментов

VSCode разрешает конфликты автоматически:

  • Видны кнопки: "Accept Current Change", "Accept Incoming Change", "Accept Both Changes"
  • Я клик, и конфликт разрешен

Для более сложных случаев — мерж-тул:

git mergetool
# Открывает специальный редактор (Mergetool) для разрешения

Три-панельный вид в Mergetool:

  • Левая панель: наша версия
  • Центральная панель: результат
  • Правая панель: их версия

Шаг 6: Проверка решения

После ручного разрешения нужно убедиться, что код правильный:

# 1. Удалить маркеры конфликта (если они остались)
# 2. Проверить синтаксис
git diff HEAD src/components/Button.tsx

# 3. Запустить тесты
npm test src/components/Button.test.tsx

# 4. Запустить проверку типов
npx tsc --noEmit

# 5. Запустить линтер
npm run lint src/components/Button.tsx

Шаг 7: Завершение слияния

После разрешения всех конфликтов:

# Добавить все разрешённые файлы
git add src/components/Button.tsx

# Завершить слияние (commit создастся автоматически)
git commit

# Или если был rebase:
git rebase --continue

Практические стратегии

**Стратегия 1: "Наша" (Ours) Использую, если мой код важнее:

git merge -X ours feature-branch

**Стратегия 2: "Их" (Theirs) Использую, если мержу feature-branch и его код лучше:

git merge -X theirs feature-branch

**Стратегия 3: Рекурсивное слияние Для больших проектов:

git merge -X recursive=patience feature-branch

Типичные конфликты и их решение

1. Конфликт в CSS (Tailwind)

// HEAD
className="px-4 py-2 bg-blue-500"

// feature-branch
className="px-4 py-2 bg-red-500"

// Решение: договориться о правильном цвете, затем обновить
className="px-4 py-2 bg-green-500"

2. Конфликт в импортах

// HEAD
import { Button, Input } from './ui';

// feature-branch
import { Button, Select } from './ui';

// Решение:
import { Button, Input, Select } from './ui';

3. Конфликт в package.json Удобнее использовать npm merge:

git checkout --theirs package.json
npm install
git add package.json package-lock.json

Как избежать конфликтов

  1. Синхронизируюсь с main регулярно

    • git pull origin main каждый день
    • Разрешаю конфликты малыми кусками
  2. Делаю тонкие PR вместо больших

    • Меньше файлов = меньше конфликтов
  3. Общаюсь с командой

    • Если два человека меняют одно и то же — договариваемся
  4. Использую feature-ветки логически

    • Одна ветка = одна фича, не десять

Ключевой вывод

Конфликт при слиянии не страшно. Главное — не паниковать, понять контекст, проанализировать обе версии, выбрать правильное решение (часто это комбинация обоих вариантов), и обязательно протестировать результат. VSCode хорошо помогает с визуализацией конфликтов, а команды git show позволяют понять историю каждого варианта.