web-dev-qa-db-fra.com

Comment fusionner deux branches avec des hiérarchies de répertoires différentes dans git?

J'ai commencé à utiliser Maven avec un projet d'application Web, la hiérarchie des répertoires a donc changé. J'ai créé une nouvelle branche pour l'intégration Maven. Maintenant, j'ai deux branches l'une avec l'ancienne hiérarchie de répertoires et l'autre avec la hiérarchie de répertoires maven. Les deux branches ont de nouveaux commits (corrections de bugs et nouvelles fonctionnalités).

Je voudrais me débarrasser de l'ancienne branche et fusionner ses modifications avec la branche Maven. La fusion Git donne d'innombrables conflits qui semblent impossibles à résoudre. Je crois que c'est parce que les chemins d'accès aux fichiers ont changé.

Quelle est la meilleure façon d'aborder cette fusion?

60
anssias

Essayez de définir merge.renameLimit à quelque chose de haut pour cette fusion. git essaie de détecter les renommages, mais uniquement si le nombre de fichiers est inférieur à cette limite, car il nécessite un temps de traitement O (n ^ 2):

git config merge.renameLimit 999999

puis une fois terminé:

git config --unset merge.renameLimit
141
Robie Basak

Le billet de blog " Confluence, git, rename, merge oh my… " ajoute quelques informations intéressantes qui illustrent Robie 's réponse (voté):

Lorsque vous essayez de détecter des renommages, git fait la distinction entre les renommages exacts et inexacts avec:

  • l'ancien étant un renommage sans changer le contenu du fichier et
  • ce dernier un renommage qui pourrait inclure des modifications du contenu du fichier (par exemple renommer/déplacer une classe Java)).

Cette distinction est importante car l'algorithme de détection des renommages exacts est linéaire et sera toujours exécuté tandis que l'algorithme de détection de renommage inexact est quadratique (O(n^2)) et git ne tente pas de le faire si le nombre de fichiers a changé dépasse un certain seuil (1000 par défaut).

Lorsqu'il n'est pas défini explicitement, merge.renameLimit par défaut à 1 000 fichiers ou utilise la valeur de diff.renameLimit si défini.
Le diff.renameLimit affecte git diff, git show et git log tandis que merge.renameLimit s'applique aux tentatives de fusion (git merge, git cherry-pick) seulement.

C'est une bonne idée de changer le merge.renameLimit plutôt que de modifier le diff.renameLimit afin que git n'essaye pas de trouver des renommages lors d'opérations courantes comme en regardant git diff production.

Pour afficher les renommages, des commandes comme git show ou git log peut être utilisé avec le -M option qui active la détection de renommage.

Linus mentionne :

Ouais, pour le noyau, j'ai

    [diff]
            renamelimit=0

pour désactiver complètement la limite, car la limite par défaut est en effet très basse. Git est assez bon pour la détection de renommage.

Cependant, la raison de la faible valeur par défaut n'est pas parce qu'elle n'est pas assez accrocheuse - c'est parce qu'elle peut finir par utiliser beaucoup de mémoire (et si vous manquez de mémoire, le swap signifiera qu'elle passe de "assez accrocheur" à "lent comme la mélasse" - mais il ne sera toujours pas limité par le CPU, c'est juste une pagination comme un fou).

24
VonC