3 min read

Git : Fusionner deux dépôts

point clé : préservant l'historique

We used AI while writing this content.

Pour fusionner deux dépôts GitHub tout en préservant l'historique complet des commits, vous devez ajouter un dépôt en tant que remote dans l'autre, récupérer ses branches, puis le fusionner ou l'importer dans un sous-répertoire en utilisant git subtree ou git filter-repo. Cette approche garantit qu'aucun commit n'est perdu.


Configuration

1. Préparer le dépôt cible

Commencez par cloner le dépôt qui servira de base :

# Cloner le dépôt principal
git clone https://github.com/votre-org/depotA.git
cd depotA

2. Ajouter le second dépôt comme remote

Ajoutez le second dépôt en tant que remote et récupérez ses données :

git remote add depotB https://github.com/votre-org/depotB.git
git fetch depotB

3. Importer le second dépôt dans un sous-répertoire

Pour préserver l'historique tout en gardant une structure propre, déplacez les fichiers du second dépôt dans un sous-répertoire :

# Créer une branche depuis depotB
git checkout -b depotB-branch depotB/main

# Déplacer tous les fichiers dans un sous-dossier
mkdir depotB
git mv * depotB/
git commit -m "Déplacer les fichiers de depotB dans un sous-répertoire"

Note : Si vous avez des fichiers cachés (commençant par .), utilisez :

git mv .[!.]* depotB/

4. Fusionner dans la branche principale

Revenez sur la branche principale et fusionnez les modifications :

git checkout main
git merge depotB-branch --allow-unrelated-histories

L'option --allow-unrelated-histories est nécessaire car les deux dépôts n'ont pas d'ancêtre commun.


5. Publier le dépôt fusionné

Poussez les modifications vers GitHub :

git push origin main

Options de fusion

Approche Description Avantages Inconvénients
Fusion directe (--allow-unrelated-histories) Fusionne les historiques directement Simple, préserve tous les commits Peut causer des conflits si les fichiers se chevauchent
Fusion en sous-arbre (git subtree) Importe depotB dans un sous-répertoire de depotA Séparation claire, préserve l'historique Configuration légèrement plus complexe
Filter-Repo (git filter-repo) Réécrit l'historique de depotB dans un sous-dossier avant fusion Très propre, évite les conflits Nécessite l'installation de git-filter-repo

Méthodes avancées

Utilisation de git filter-repo (recommandé pour les gros dépôts)

Si vous travaillez avec de gros dépôts, git filter-repo offre une approche plus propre :

# Installer git-filter-repo
pip install git-filter-repo

# Dans le dépôt source
git filter-repo --to-subdirectory-filter depotB/

# Puis ajouter comme remote et fusionner

Voir ici pour en savoir plus sur git filter-repo.

Utilisation de git subtree

Alternative élégante pour maintenir une séparation logique :

git subtree add --prefix=depotB https://github.com/votre-org/depotB.git main

Résolution des conflits de fusion

Comprendre l'erreur MERGE_HEAD

Si vous voyez un message indiquant qu'une fusion est en cours, cela signifie que Git a détecté des conflits qui doivent être résolus manuellement.

1. Vérifier l'état

git status

Cette commande affichera les fichiers en conflit.

2. Résoudre les conflits

Ouvrez les fichiers marqués comme unmerged et cherchez les marqueurs de conflit :

<<<<<<< HEAD
votre version
=======
version de l'autre branche
>>>>>>> depotB-branch

Choisissez ou combinez les versions, puis supprimez ces marqueurs.

3. Marquer les conflits comme résolus

git add fichier-resolu

4. Finaliser la fusion

git commit

Git créera automatiquement un commit de fusion.

Annuler la fusion

Si vous préférez recommencer :

git merge --abort

Cela annulera la fusion et restaurera l'état précédent.


Points d'attention

Conflits potentiels

  • Fichiers identiques : Si les deux dépôts contiennent des fichiers avec les mêmes noms/chemins, vous devrez résoudre les conflits manuellement.
  • Gros historiques : Pour les dépôts volumineux, utilisez git filter-repo pour des fusions plus propres.
  • Structure du projet : Planifiez à l'avance l'organisation des répertoires pour éviter la confusion.

Sous-modules vs Fusion complète

  • Fusion complète : Intègre tout le code et l'historique dans un seul dépôt.
  • Submodules Git : Maintient les dépôts séparés mais liés. Utilisez cette approche si vous voulez garder les projets faiblement couplés :
git submodule add https://github.com/votre-org/depotB.git depotB

Liens utiles


Résumé

Étape Commande clé
1. Cloner le dépôt principal git clone <url>
2. Ajouter le remote git remote add depotB <url>
3. Créer une branche de fusion git checkout -b depotB-branch depotB/main
4. Organiser en sous-répertoire git mv * depotB/
5. Fusionner git merge depotB-branch --allow-unrelated-histories
6. Résoudre les conflits git add + git commit
7. Annuler si nécessaire git merge --abort