Quelle version du fichier git sera finalement utilisée: LOCAL, BASE ou REMOTE?


174

Quand il y a une collision pendant git merge, j'ouvre un outil de fusion appelé Meld . Il ouvre trois fichiers LOCAL, BASE et REMOTE. Comme je l'ai lu, LOCAL est ma branche locale, BASE est l'ancêtre commun et REMOTE est la branche à fusionner.

Passons maintenant à ma question: quelle version du fichier sera finalement utilisée? Est-ce REMOTE? Si tel est le cas, puis-je le modifier comme je le souhaite, quel que soit le contenu de la branche BASE par exemple?

Réponses:


142

Il est celui au milieu: BASE.

En fait, ce BASEn'est pas l'ancêtre commun, mais la fusion à moitié terminée où les conflits sont marqués par >>>>et <<<<.

Vous pouvez voir les noms de fichiers en haut de la fenêtre d'édition de fusion.

Voir la capture d'écran ici

fondre la base

Vous pouvez modifier le BASEfichier à votre guise avec ou sans les commandes de fusion.
Vous pouvez également vous débarrasser de meld et simplement éditer le fichier avec votre éditeur de texte préféré.

  • Le code entre <<<< HEADet =====marqueurs est celui de votre fichier local avant la fusion.
  • Le code entre ====et >>>> <branch name>est celui du fichier distant.

3
Certaines personnes comprennent mieux les blocs conflictuels dans un fichier dont la fusion automatique a échoué si l' merge.conflictstyleoption de configuration est définie sur au diff3lieu de la valeur par défaut merge.
kostix

3
En fait, je ne vois pas la TÊTE, <<< et === chante. Dans le cas où vous avez fourni la fenêtre du milieu serait vide. Mais ce n'est qu'une note pour les autres, merci pour votre réponse.
tsusanka

Si vous ne voyez pas les HEAD, <<<<<et les =====signes, cela signifie qu'il n'y a pas de conflit du tout. Dans ce cas, la fenêtre du milieu ne sera pas vide, elle affichera le résultat de la fusion, mais il n'y aura pas de partie "rouge"
Fabien Quatravaux

10
Quand je fais des fusions avec Meld, je ne vois pas de marqueurs <<<<<<, ======ni de >>>>>>marqueurs dans le volet central (c'est-à-dire la version BASE) non plus; et parfois, le volet central sera vide, comme l'aGr l'a signalé. Peut-être que cette différence est due à des paramètres différents. Quand je commence l'outil Meld, les fichiers suivants existeront, en supposant que le nom du fichier dans le référentiel est X.java: X.java, X.java.orig, X.java.BACKUP.#, X.java.BASE.#, X.java.LOCAL.#, X.java.REMOTE.#, où #est un nombre. L'appel du résultat de fusion la version BASE est déroutant; MERGED serait mieux.
Teemu Leisti

3
BASE est en fait l'ancêtre commun, MERGED est le nom du fichier contenant les informations de fusion partielle. S'il vous plaît voir ma question et réponse Configurer et utiliser Meld comme votre git difftool et mergetool qui explique exactement comment cela fonctionne. HTH.
mattst

107

Meld a une fonction de fusion à 3 voies cachée activée en passant le 4ème paramètre:

meld $LOCAL $BASE $REMOTE $MERGED

Les volets droit et gauche sont ouverts en mode lecture seule, vous ne pouvez donc pas fusionner accidentellement dans le mauvais sens. Le volet du milieu montre le résultat de la fusion. Pour les conflits, il montre la version de base afin que vous puissiez voir tous les éléments importants: le texte original au milieu et les modifications conflictuelles des deux côtés. Enfin, lorsque vous appuyez sur le bouton "Enregistrer", le fichier $ MERGED est écrit - exactement comme prévu par git.

Le fichier ~ / .gitconfig que j'utilise contient les paramètres suivants:

[merge]
tool = mymeld
conflictstyle = diff3
[mergetool "mymeld"]
cmd = meld --diff $BASE $LOCAL --diff $BASE $REMOTE --diff $LOCAL $BASE $REMOTE $MERGED

Cela ouvre la fusion avec 3 onglets, le 1er et le 2ème onglet contenant les différences simples que j'essaie de fusionner, et le 3ème onglet, ouvert par défaut, montre la vue de fusion à 3 voies.

Maintenant, la raison pour laquelle la fonctionnalité est cachée est qu'elle n'est pas encore assez polie. C'est très utile tel qu'il est maintenant, mais Kai Willadsen, l'auteur de la fusion, a souligné quelques rides à aplanir. Par exemple, il n'y a pas d'interface graphique pour démarrer le mode de fusion à 3 voies, la syntaxe de la ligne de commande est un peu obscure, etc. Si vous parlez python et que vous avez du temps libre, vous savez quoi faire.

Edit: Dans les nouvelles versions de Meld, la synaxe a légèrement changé. C'était dans les commentaires, mais cela fait partie de la réponse.

La commande meld utilise maintenant l'option --output, donc la dernière ligne de l'extrait ci-dessus devrait être:

cmd = meld --diff $BASE $LOCAL --diff $BASE $REMOTE --diff $LOCAL $BASE $REMOTE --output $MERGED

7
@Jesse, @lumbric, il semble que les versions plus récentes de meld utilisent l'indicateur --outputpour le résultat $ MERGED. J'ai découvert cela en regardant le script de lancement de fusion fourni avec ma version de git: github.com/git/git/blob/master/mergetools/meld
Johann

1
@lumbric je crois que oui, pour Meld 1.7.x + avec le --output option. Voir cette ligne dans le script de lancement:"$merge_tool_path" --output "$MERGED" "$LOCAL" "$BASE" "$REMOTE"
Johann

12
Dans la dernière fusion (version> 1.8.4), nous devons utiliser l'option --auto-merge. cmd = meld --diff $ BASE $ LOCAL --diff $ BASE $ REMOTE --auto-merge $ LOCAL $ BASE $ REMOTE --output $ MERGED
RoboAlex

7
J'ai eu le même problème que @pingpongboss en utilisant Meld 1.8.4: Meld ouvrait les choses dans un volet séparé, au lieu d'ouvrir le 3e onglet. La commande finally a bien fonctionné est: cmd = meld $LOCAL $BASE $REMOTE --auto-merge --output $MERGED. Ainsi, cela ouvre 3 onglets (bonne vieille méthode), fusionne automatiquement les fusions non conflictuelles au milieu, où le milieu est $ MERGED, et sera utilisé comme sortie de résolution de conflit.
farmir

2
La syntaxe pour la sortie peut être --output=<file>ou -o <file>, voirmeld --help
levsa

57

Il y a 4 fichiers impliqués:

  1. $LOCALLe fichier sur la branche où vous fusionnez; non touché par le processus de fusion lorsqu'il vous est montré

  2. $REMOTELe fichier sur la branche à partir de laquelle vous fusionnez; non touché par le processus de fusion lorsqu'il vous est montré

  3. $BASEL'ancêtre commun de $ LOCAL et $ REMOTE, ie. le point où les deux branches ont commencé à détourner le fichier considéré; non touché par le processus de fusion lorsqu'il vous est montré

  4. $MERGEDLe fichier partiellement fusionné, avec des conflits; c'est le seul fichier touché par le processus de fusion et, en fait, ne vous a jamais été montré dansmeld


Le $MERGEDfichier est celui qui contient les <<<<<<, >>>>>>, =====(et, peut - être, ||||||) des marqueurs (que des conflits de délimiter). Il s'agit du fichier que vous modifiez manuellement pour corriger les conflits.

L'édition manuelle des conflits et l'édition des conflits visuels se font sur différents fichiers et présentent des informations différentes.

Lorsque vous utilisez le mergetool (on suppose meld), les fichiers qui y voient sont: $LOCAL, $BASE, $REMOTE. Notez que vous ne voyez pas le $MERGEDfichier, bien qu'il soit passé comme paramètre caché pour meldy écrire le résultat de la modification.

En d'autres termes, dans meld, vous éditez le fichier au milieu, le $BASEfichier, et vous sélectionnez manuellement toutes les modifications de gauche ou de droite . C'est un fichier propre, non touché par le processus de fusion. Le seul problème est que, lorsque vous enregistrez, vous ne sauvegardez pas dans le $BASEfichier, mais dans le quatrième paramètre caché de meld, c'est-à-dire le $MERGEDfichier (que vous ne voyez même pas). Le $BASEfichier ne pas contient aucun conflit ou se confond avec succès partiel , car il est pas le $MERGEDfichier .

Dans l'édition visuelle, lorsque vous vous présentez, le $BASEfichier (au lieu du $MERGEDfichier) gitrejette fondamentalement toutes ses tentatives de fusion (ces tentatives sont visibles, si vous le souhaitez, dans le fichier $ MERGED) et vous permet d' effectuer complètement la fusion. à partir de zéro .

L'essentiel est que dans les conflits de fusion manuels et visuels, vous ne regardez pas les mêmes fichiers, mais le résultat final est écrit dans le même fichier (c'est-à-dire le $MERGEDfichier).

La correction manuelle des conflits se fait sur , $MERGEDcar git n'a pas moyen de vous présenter trois fichiers, il écrase les informations des trois fichiers ( $LOCAL, $BASE, $REMOTE) dans ce $MERGEDfichier.

Mais les outils visuels ont les moyens de vous montrer trois fichiers: ils vous montrent les $LOCAL, $BASE, les $REMOTEfichiers. Vous ramassez des changements $LOCALet des $REMOTEfichiers et vous apportez ceux dans le $BASEfichier, complètement re-construction et même la tentative avortée d' écraser la fusion qui est le $MERGEDfichier.


Je voulais juste qu'il y ait des outils (par exemple au-delà de la comparaison) qui affichent les 4 fichiers
yoniLavi

@yoniYalovitsky: oui ou p4merge
user1284631

J'avais l'habitude d'utiliser l'outil de fusion du package ClearCase
mishmashru

@yoniLavi - ces outils affichent 4 volets , mais pas nécessairement les quatre fichiers décrits dans cette réponse. En particulier, vous pouvez mettre en place ces outils 4 volet pour vous montrer $LOCAL, $REMOTE, $BASEet la sortie égale initialement $BASE, mais qui est différent $MERGEDen ce sens qu'il n'a pas la tentative de git de fusionner les fichiers et les marqueurs de conflit et ainsi de suite. En fait, ce serait la façon d'utiliser ces outils qui est la plus similaire à l'approche à 3 volets de LOCAL / REMOTE / BASE + OUTPUT, qui ne montre pas fusionné. Le quatrième volet vous permet simplement de séparer la base de la sortie.
BeeOnRope

16

La solution de Cosmin fonctionne, mais le fichier $ BASE est mis à jour - pas $ MERGED . Cela mettra à jour le fichier $ MERGED :

Fondre: v1.8.4

[merge]
  conflictstyle = diff3
  tool = mymeld
[mergetool "mymeld"]
  cmd = meld --auto-merge --output $MERGED $LOCAL $BASE $REMOTE --diff $BASE $LOCAL --diff $BASE $REMOTE

Je peux le confirmer, la solution de Saad fonctionne pour moi sur Ubuntu. En ce qui concerne la question initiale, c'est la bonne réponse actuelle.
cosmin

3
Dans ma version de meld - 3.11, cette commande fonctionne très bien:cmd = meld --auto-merge --output $MERGED $LOCAL $BASE $REMOTE
MartinM

pourquoi auriez-vous besoin --diff $BASE $LOCAL --diff $BASE $REMOTEà la fin? pour moi sur 1.8.4, cela fonctionne très bien (pour autant que je puisse voir):cmd = meld --auto-merge --output $MERGED $LOCAL $BASE $REMOTE
farmir

1
@farmir: Ce n'est pas nécessaire. Il ouvre deux autres onglets dans meld afin que vous puissiez voir LOCAL et REMOTE par rapport à BASE individuellement.
Sam Kauffman

1
Quel que soit l'ordre que j'essaie avec ces arguments, l'onglet à trois est toujours le troisième onglet, tandis que le premier onglet est toujours sélectionné par défaut. Existe-t-il un moyen de sélectionner l'onglet à trois par défaut?
Sam Kauffman

13

Avec Meld 1.7, la solution de Tomek Bury ne fonctionne plus.

Les paramètres par défaut ne m'ont pas satisfait:

Paramètres par défaut

Au lieu de cela pour Meld> = 1,7, je suggère l'une des deux autres solutions.

Première solution :

 meld $LOCAL $BASE $REMOTE --auto-merge

première solution

Deuxième solution :

 meld $LOCAL $MERGED $REMOTE

deuxième solution

.gitconfig

Copiez et collez ceci dans votre .gitconfigfichier pour obtenir les solutions décrites ci-dessus:

[merge]
    tool = meld16
[mergetool "meld17"]
    # use this for Meld >=1.7
    # see http://stackoverflow.com/a/22911793/859591
    # second solution:
    cmd = meld $LOCAL $MERGED $REMOTE
    # first solution:
    #cmd = meld $LOCAL $BASE $REMOTE --auto-merge
[mergetool "meld16"]
    cmd = meld --diff $BASE $LOCAL --diff $BASE $REMOTE --diff $LOCAL $BASE $REMOTE --output $MERGED

[include]
    # requires git v1.7.10+
    path = .gitconfig.local

Copiez et collez ceci dans un .gitconfig.localfichier pour définir meld17 ou meld16 uniquement pour cette machine au cas où vous utilisez votre .gitconfig sur plusieurs machines:

# This is a host specific config file!
# Note that git 1.7.10+ is needed
# http://stackoverflow.com/a/9733277/859591
[merge]
    tool = meld17

Cela ne fonctionne pas sur Meld 1.8.4. Si vous exécutez cmd = meld $LOCAL $BASE $REMOTE --auto-merge, le volet du milieu sera le $ BASE, et non le $ MERGE qui est réellement utilisé comme sortie de résolution de conflit.
farmir

1
@farmir Vous avez choisi $ BASE comme deuxième onglet.
Alex78191

11

J'ai constaté qu'aucun des fichiers par défaut affichés n'était en cours d'enregistrement. meld montrait $LOCAL, $REMOTEet $BASEpar défaut. Pour que cela fonctionne, j'avais besoin de faire un spectacle de fusion $MERGEDau lieu de $BASE. Mettre ceci dans mon ~/.gitconfigfixe pour moi:

[merge]
        tool = mymeld
[mergetool "mymeld"]
        cmd = meld "$LOCAL" "$MERGED" "$REMOTE"

J'utilise Arch, avec:

$ git --version
git version 1.8.2
$ meld --version
meld 1.7.1

Excusez-moi, cette configuration est-elle compatible avec Inux?
MadMad666

2

Pour une raison quelconque, les dernières versions de meld n'affiche pas les lignes de marqueur ajoutées pour les conflits (<<<<<<<, =======, >>>>>>>). Si vous voulez voir ces lignes, vous devez installer meld v 1.3.3 ou une version antérieure.


J'ai trouvé utile la réponse de @lumbric stackoverflow.com/a/22911793/641892
wnasich

2

Veuillez consulter la réponse de Saad pour la bonne réponse.

Avec meld 1.8.1 sur Ubuntu, j'obtenais le

nombre incorrect d'arguments fournis à --diff

et en ajoutant le --output avant que $ MERGED ne le corrige pour moi:

[mergetool "mymeld"]
cmd = meld --diff $BASE $LOCAL --diff $BASE $REMOTE --diff $LOCAL $BASE $REMOTE --output $MERGED
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.