Git merge: écraser certains fichiers

Le problème exposé dans ce sujet a été résolu.

Bonjour,

Je souhaiterais pour un git merge, que certains fichiers spécifiques soient écrasés plutôt que fusionnés, tandis que pour tous les autres fichiers ce soit un merge normal qui soit exécuté. Est-ce que je peux faire ça, et si oui, comment ?

Explication du contexte: j'ai deux branches, dev et master. JE me trouve actuellement sur dev et j'aimerais fusionner avec master, sur dev donc. J'insiste, je veux bien fusionner master sur dev et pas l'inverse ! Oui je sais, je suis peut-être bizarre; on aura l'occasion d'y revenir si vous avez envie.

depuis le moment où j'ai créé la branche dev, un certain nombre de bugs ont été corrigés sur master entre temps. Les bugs en question n'ont pas encore été corrigé sur dev puisque la création de la branche est antérieure à la correction de ces bugs. En plus simple, les deux branches dev et master ont évolué complètement indépendament. IL me faut donc fusionner la branche master depuis dev pour que ces bugs soient désormais aussi corrigés sur dev.

Or, sur dev, certains fichiers ont depuis été refactorés, c'était justement un des objectifs de cette banche dev. En faisant un git merge, je suis à peu près certain que l'opération va planter et je vais me retrouver avec des fichiers automergé qui seront pourris où il faudra effacer près de 50% à la main (en plus le risque d'erreur est très élevé dans ce genre de manip). JE voudrais donc que pour ces fichiers, et seulement ceux-là, git n'essaye même pas de les fusionner, mais qu'il prenne à la place ma version locale sans poser de question; tandis que les autres seront fusionnés de manière classique avec la'lgorithme par défaut de git.

Bien sûr, la solution crado est de faire une copie des fichiers en question en-dehors du dépôt, lancer le git merge, remettre les fichiers préalablement copiés, puis enfin commit, mais je me doute bien qu'il y a une solution moins hacky.

En d'autres termes pour ceux qui ont connu SVN, je voudrais que l'option mine full soit choisie automatiquement pour résoudre les conflits sur ces fichiers-là, mais seulement ceux-là.

Question bonus pour ceux qui ont des conseils à fournir en la matnière, puis-je améliorer mon système/workflow pour ne plus être coincé par ce genre de problème à l'avenir ? Par exemple est-ce que j'ai fait une erreur en corrigeant toute une flopée de bugs directement sur master ? J'aurais dû faire autrement ?

Merci pour vos réponses.

+0 -0

Un cherry pick des commits de bug fix ?

Ca a bien l'air d'être quelque chose comme ça en effet. Mais…

Primo, je ne suis pas sûr d'avoir tout pigé. Si je comprends, je dois faire ça en étant dans ma branche dev, est-ce que c'est bien ça ?

git cherry-pick le_sha_du_dernier_commit_de_master

ET secundo, je ne suis pas sûr que ça résoud effectivement complètement mon problème. Parce que si un même commit sur master a modifié le fichier A et B, et que moi dans ma branche dev je veux merger A et écraser B, avec cherry-pick, je peux pas, d'après ce que je comprends. Ou alors il faut être vraiment carré et toujours prendre la précaution de commit A et B séparément l'un après l'autre. Facile à dire, mais en pratique, galère.

Merci.

Rajout: ah, en fait, plus bas dans la page que tu mentionnes, ils disent autre chose d'intéressant: quand on merge deux branches contenant des fichiers binaires, on ne peut pas les fusionner automatiquement et donc on doit choisir quelle version on prend, ce qu'ils propose de faire avec une des deux commandes suivantes (mutuellement exclusives) :

git checkout –ours – fichier.ext
git checkout –theirs – fichier.ext

Alors question, est-ce que ça peut marcher pour des fichiers texte aussi ? ET comment savoir si c'est ours ou theirs ? ils parlent d'inversion pour rebase et du coup ça m'emmêle.

+0 -0

Tu peux éventuellement ré-écrire l'histoire à coup de rebase interactif pour découper le commit en 2, si tu n'as pas rendu public les commits. Comme tu le remarques, c'est dans ce genre de cas qu'on trouve l’intérêt des faire des petits commits assez régulièrement.

Sinon un git patch entre master/a et dev/a appliqué sur dev/a et un checkout de master/b dans dev/b pour récupérer master/b et écraser ainsi écraser dev/b.

Tu peux éventuellement ré-écrire l'histoire à coup de rebase interactif pour découper le commit en 2, si tu n'as pas rendu public les commits.

Ca dépend ce qu'on entend par rendre public… pour le cas ici, par chance, c'est un projet closed source, sur un dépôt privé hébergé sur un serveur que je contrôle, et je suis seul; mais d'après ce que j'ai déjà pu lire, faire du rebase n'est pas conseillé, dès le moment où on a push… au pire si je fais tout foirer je refais un nouveau dépôt mais bof, je perds tout l'historique précédent et un jour ça pourrait m'être fatal.

Par contre je note ta solution permettant de récupérer un seul fichier d'une autre branche, je ne savais pas qu'on pouvait. Ca pourrait être utile, à un détail près: c'est le contraire que je veux faire, garder dev/B et évincer ce qui vient de master/B. Donc pour que ça marche il faut pouvoir faire checkout dernier_commit_avant_merge à la place de checkout master.

Merci.

+0 -0

au pire si je fais tout foirer je refais un nouveau dépôt mais bof, je perds tout l'historique précédent et un jour ça pourrait m'être fatal.

cp -r repo/.git repo_git_backup, puis tu fais ton rebase, tu push --force et voilà. Comme t'es seul, ça pose pas de problème. Si t'as tout foiré, tu reprends le .git backupé et tu push --force pour revenir à l'état précédent. :)

Ou mieux, tu fais une nouvelle branche, tu rebases cette branche, et si c'est pas ce que tu veux après le rebase tu supprimes la branche. Si c'est ce que tu veux, tu la merges.

+0 -0

Tu peux normalement demander à git de pas nerger auomatiquement et résoudre les conflits par lui-même.

btw, normalement tes bugs fixes, il faut les cherry-pick depuis master pour éviter ce genre de cas épineux :}

+0 -0

btw, normalement tes bugs fixes, il faut les cherry-pick depuis master pour éviter ce genre de cas épineux :}

Merci du conseil, c'est effectivement ce que je vais essayer de faire à l'avenir pour éviter de me retrouver de nouveau dans cette situation.

Sinon, ça a fonctionné avec la solution des checkout. LE sujet est donc résolu. Merci à tous pour vos réponses.

+0 -0
Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte