Git merge: écraser certains fichiers

L'auteur de ce sujet a trouvé une solution à son problème.
Auteur du sujet

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.

Ma plateforme avec 23 jeux de société classiques en 6 langues et 13000 joueurs: http://qcsalon.net/ | Apprenez à faire des sites web accessibles http://www.openweb.eu.org/

+0 -0

Bonjour, Je suis loin d'être doué là-dedans, donc à confirmer, mais à priori il suffit de checkout la bonne révision des fichiers et de commit.

git checkout 82f5 un.fichier un-autre.fichier

+0 -0

Un cherry pick des commits de bug fix ? Cette pagesemble décrire quelque chose d'assez similaire à ta situation.

Mais si tes bug fixes touchent des fichiers réfactorés, je ne crains que tu ais un peu de travail à la main pour résoudre d'éventuels conflits.

Édité par Davidbrcz

+0 -0
Auteur du sujet

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.

Édité par QuentinC

Ma plateforme avec 23 jeux de société classiques en 6 langues et 13000 joueurs: http://qcsalon.net/ | Apprenez à faire des sites web accessibles http://www.openweb.eu.org/

+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.

+0 -0
Auteur du sujet

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.

Ma plateforme avec 23 jeux de société classiques en 6 langues et 13000 joueurs: http://qcsalon.net/ | Apprenez à faire des sites web accessibles http://www.openweb.eu.org/

+0 -0
Staff

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.

Je parle de JavaScript et d'autres trucs sur mon blog : https://draft.li/blog

+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 :}

"Meh." Outil de diff PHP : Totem

+0 -0
Auteur du sujet

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.

Ma plateforme avec 23 jeux de société classiques en 6 langues et 13000 joueurs: http://qcsalon.net/ | Apprenez à faire des sites web accessibles http://www.openweb.eu.org/

+0 -0
Vous devez être connecté pour pouvoir poster un message.
Connexion

Pas encore inscrit ?

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