Resolução de conflitos
Aprenda a identificar e resolver os conflitos de merge que surgem durante a colaboração.
Resolução de conflitos
Os conflitos no Git são inevitáveis no desenvolvimento colaborativo. Este tutorial vai ensinar você a entender, identificar e resolver conflitos de merge com eficiência, para manter um workflow fluido em equipe.
O que é um conflito no Git?
Um conflito ocorre quando o Git não consegue mesclar automaticamente as alterações de duas branches porque elas modificam as mesmas linhas de código de maneira incompatível.
Tipos de conflitos
1. Conflitos de conteúdo
Modificações simultâneas das mesmas linhas:
# Branche A modifie :
function greet() {
return "Hello World!";
}
# Branche B modifie :
function greet() {
return "Bonjour le monde!";
}
2. Conflitos de renomeação
# Branche A : renomme file.txt en document.txt
# Branche B : modifie le contenu de file.txt
# Résultat : Git ne sait pas quoi faire
3. Conflitos de exclusão
# Branche A : supprime file.txt
# Branche B : modifie file.txt
# Résultat : Conflit de suppression/modification
Anatomia de um conflito
Marcadores de conflito
<<<<<<< HEAD
function calculateTotal(items) {
return items.reduce((sum, item) => sum + item.price, 0);
}
=======
function calculateTotal(items) {
let total = 0;
for (let item of items) {
total += item.price;
}
return total;
}
>>>>>>> feature/new-calculation
Explicação dos marcadores:
<<<<<<< HEAD: início da sua versão (branch atual)=======: separador entre as versões>>>>>>> feature/new-calculation: fim da versão da outra branch
Identificar os conflitos
Comandos de diagnóstico
# Voir l'état des conflits
git status
# Lister les fichiers en conflit
git diff --name-only --diff-filter=U
# Voir les détails des conflits
git diff
# Voir les conflits avec plus de contexte
git diff --conflict=diff3
Saída típica do git status
On branch main
You have unmerged paths.
(fix conflicts and run "git commit")
(use "git merge --abort" to abort the merge)
Unmerged paths:
(use "git add <file>..." to mark resolution)
both modified: src/calculator.js
both modified: README.md
no changes added to commit (use "git add" or "git commit -a")
Estratégias de resolução
1. Resolução manual
# 1. Identifier les fichiers en conflit
git status
# 2. Ouvrir le fichier et éditer manuellement
# Supprimer les marqueurs <<<<<<, =======, >>>>>>>
# Garder le code désiré
# 3. Marquer comme résolu
git add fichier-resolu.js
# 4. Finaliser la fusion
git commit
2. Escolher uma versão completa
# Garder votre version (HEAD)
git checkout --ours fichier.js
git add fichier.js
# Garder leur version
git checkout --theirs fichier.js
git add fichier.js
# Finaliser
git commit
3. Ferramentas de merge
# Configurer un outil de merge
git config --global merge.tool vimdiff
# Lancer l'outil
git mergetool
# Autres outils populaires
git config --global merge.tool vscode
git config --global merge.tool kdiff3
git config --global merge.tool meld
Resolução passo a passo
Exemplo prático completo
# Situation : Conflit lors d'un merge
git merge feature/user-profile
# Auto-merging src/user.js
# CONFLICT (content): Merge conflict in src/user.js
# Automatic merge failed; fix conflicts and then commit the result.
# 1. Examiner le conflit
git status
cat src/user.js
Conteúdo do arquivo com conflito:
class User {
constructor(name, email) {
this.name = name;
this.email = email;
<<<<<<< HEAD
this.id = Math.random().toString(36);
this.createdAt = new Date();
=======
this.id = generateUniqueId();
this.timestamp = Date.now();
>>>>>>> feature/user-profile
}
}
# 2. Résoudre le conflit (édition manuelle)
# Décider de combiner les deux approches
Resolução:
class User {
constructor(name, email) {
this.name = name;
this.email = email;
this.id = generateUniqueId(); // Utiliser la fonction plus robuste
this.createdAt = new Date(); // Garder le format Date
this.timestamp = Date.now(); // Ajouter aussi le timestamp
}
}
# 3. Marquer comme résolu
git add src/user.js
# 4. Vérifier que tous les conflits sont résolus
git status
# 5. Finaliser le merge
git commit -m "Merge feature/user-profile
Resolved conflicts in user.js by combining both ID generation
approaches and keeping both timestamp formats for compatibility."
Ferramentas de resolução
VS Code
O VS Code oferece uma interface intuitiva para resolver conflitos:
// settings.json
{
"git.mergeEditor": true,
"merge-conflict.autoNavigateNextConflict.enabled": true
}
Funcionalidades:
- Accept Current Change: manter a sua versão
- Accept Incoming Change: manter a versão da outra branch
- Accept Both Changes: combinar as duas
- Compare Changes: ver as diferenças lado a lado
GitKraken
Interface gráfica avançada:
- Visualização das branches e dos conflitos
- Editor de merge integrado
- Histórico das resoluções
Linha de comando com vimdiff
# Configuration
git config --global merge.tool vimdiff
# Utilisation
git mergetool
# Navigation dans vimdiff
# :diffget LOCAL - Prendre la version locale
# :diffget REMOTE - Prendre la version distante
# :diffget BASE - Prendre la version de base
Prevenção de conflitos
Boas práticas
-
Sincronização frequente
# Récupérer régulièrement les changements git fetch origin git merge origin/main -
Branches curtas
# Éviter les branches de longue durée # Merger fréquemment les petites fonctionnalités -
Comunicação em equipe
# Coordonner les modifications sur les mêmes fichiers # Utiliser les issues GitHub pour planifier -
Rebase antes do merge
git fetch origin git rebase origin/main # Résoudre les conflits un par un git push --force-with-lease origin feature-branch
Organização do código
// Éviter les conflits en structurant le code
// Séparer les fonctionnalités en modules distincts
// ❌ Tout dans un fichier
// app.js (500 lignes)
// ✅ Modules séparés
// auth.js
// user.js
// api.js
// utils.js
Conflitos avançados
Conflitos durante o rebase
# Démarrer un rebase
git rebase main
# En cas de conflit
# 1. Résoudre le conflit
# 2. Ajouter les fichiers résolus
git add .
# 3. Continuer le rebase
git rebase --continue
# Ou abandonner
git rebase --abort
Conflitos com cherry-pick
# Cherry-pick avec conflit
git cherry-pick abc1234
# Résoudre et continuer
git add .
git cherry-pick --continue
# Ou abandonner
git cherry-pick --abort
Conflitos de merge vs rebase
Conflitos de merge:
- Resolvidos de uma só vez
- Histórico preservado
- Commit de merge criado
Conflitos de rebase:
- Resolvidos commit por commit
- Histórico linear
- Nenhum commit de merge
Exercícios práticos
Exercício 1: conflito simples
# 1. Créer un dépôt de test
mkdir conflict-demo
cd conflict-demo
git init
# 2. Créer un fichier initial
echo "function greet() {
return 'Hello';
}" > greet.js
git add greet.js
git commit -m "Initial greeting function"
# 3. Créer deux branches avec modifications conflictuelles
git checkout -b feature-french
echo "function greet() {
return 'Bonjour';
}" > greet.js
git add greet.js
git commit -m "Add French greeting"
git checkout main
git checkout -b feature-spanish
echo "function greet() {
return 'Hola';
}" > greet.js
git add greet.js
git commit -m "Add Spanish greeting"
# 4. Merger et résoudre le conflit
git checkout main
git merge feature-french
git merge feature-spanish
# Conflit attendu !
# 5. Résoudre en combinant les langues
echo "function greet(language = 'en') {
const greetings = {
'en': 'Hello',
'fr': 'Bonjour',
'es': 'Hola'
};
return greetings[language] || greetings['en'];
}" > greet.js
git add greet.js
git commit -m "Resolve conflict by supporting multiple languages"
Exercício 2: conflito complexo com vários arquivos
# 1. Créer un projet avec plusieurs fichiers
echo "# My App" > README.md
echo "const version = '1.0.0';" > version.js
echo "function add(a, b) { return a + b; }" > math.js
git add .
git commit -m "Initial project setup"
# 2. Branche A : Modifications multiples
git checkout -b feature-updates
echo "# My Awesome App
Version 2.0 with new features!" > README.md
echo "const version = '2.0.0';" > version.js
echo "function add(a, b) {
if (typeof a !== 'number' || typeof b !== 'number') {
throw new Error('Invalid input');
}
return a + b;
}" > math.js
git add .
git commit -m "Update to version 2.0 with validation"
# 3. Branche B : Modifications différentes
git checkout main
git checkout -b feature-improvements
echo "# My App
Now with better performance!" > README.md
echo "const version = '1.1.0';" > version.js
echo "function add(a, b) {
// Optimized addition
return Number(a) + Number(b);
}" > math.js
git add .
git commit -m "Performance improvements v1.1"
# 4. Merger et résoudre tous les conflits
git checkout main
git merge feature-updates
git merge feature-improvements
# Résoudre chaque fichier individuellement
Estratégias de equipe
Workflow com conflitos mínimos
# 1. Feature branches courtes
git checkout -b feature/small-change
# ... développement rapide ...
git push origin feature/small-change
# ... PR et merge rapide ...
# 2. Rebase avant PR
git fetch origin
git rebase origin/main
git push --force-with-lease origin feature/small-change
# 3. Merge fréquent de main
git checkout feature/long-running
git merge origin/main
# Résoudre les conflits au fur et à mesure
Comunicação dos conflitos
# Template de message pour conflit résolu
## Conflit résolu dans PR #123
**Fichiers affectés :**
- src/user.js
- src/auth.js
**Nature du conflit :**
Modifications simultanées des méthodes d'authentification
**Résolution choisie :**
Combinaison des deux approches :
- Garde la validation de feature-a
- Intègre l'optimisation de feature-b
**Tests effectués :**
- [ ] Tests unitaires passent
- [ ] Tests d'intégration OK
- [ ] Validation manuelle
cc @team-lead @reviewer
Solução de problemas avançada
Desfazer uma resolução de conflito
# Si vous avez fait une erreur dans la résolution
git reset --hard HEAD~1 # Annule le commit de merge
git merge feature-branch # Recommence le merge
Ver o histórico dos conflitos
# Voir les merges précédents
git log --merges --oneline
# Voir les détails d'un merge
git show commit-hash
# Voir les conflits d'un merge spécifique
git log --cc commit-hash
Resolução automática
# Configurer des stratégies de merge
git config merge.ours.driver true # Toujours garder notre version
git config merge.theirs.driver "cp %B %A" # Toujours garder leur version
# Dans .gitattributes
*.generated merge=ours
*.config merge=theirs
Recursos adicionais
Ferramentas recomendadas
- Beyond Compare: ferramenta profissional de diff/merge
- P4Merge: gratuita e eficiente
- Meld: código aberto, multiplataforma
- KDiff3: merge de 3 vias
Documentação
Conclusão
A resolução de conflitos é uma habilidade essencial para qualquer desenvolvedor que trabalha em equipe. Com prática e as ferramentas certas, os conflitos passam a ser uma parte normal e gerenciável do workflow de desenvolvimento.
No próximo tutorial, vamos explorar os workflows avançados do Git usados em equipes profissionais.
Tempo de leitura estimado: 30 minutos
Nível: Intermediário
Etapa anterior: Colaboração com o GitHub
Próxima etapa: Workflows avançados do Git