Git - Ignorer les fichiers lors de la fusion

115

J'ai un repo appelé myreposur le beanstalkserveur distant .

Je l'ai cloné sur ma machine locale. Création de deux branches supplémentaires: staginget dev. J'ai également poussé ces branches à distance.

Maintenant:

 local                   remote                   server
 --------------------------------------------------------  
 master  ==> Pushes to  `master`  ==> deployed to `prod`
 staging ==> Pushes to  `staging` ==> deployed to `staging`
 dev     ==> Pushes to  `dev`     ==> deployed to `dev`

J'ai un fichier appelé config.xmlqui est différent sur chaque branche.

Je souhaite ignorer ce fichier uniquement lors des fusions. Mais je veux que cela soit inclus lorsque je passe à la caisse ou que je m'engage depuis / vers la branche du dépôt.

La raison pour laquelle je veux cela est que nous avons un script de déploiement qui extrait (checkout) la branche spécifique et se déploie sur les serveurs respectifs. Nous avons donc besoin d'un config.xmlfichier de cette branche spécifique dans le serveur spécifique comme indiqué ci-dessus lors du déploiement.

Je suppose que cela .gitignorene fonctionnera pas. Quelles sont les autres options? Notez que le fichier ignoré doit faire partie de l'extraction et de la validation, ce qui est important. il ne doit être ignoré que lors des fusions.

Merci!

Kevin Rave
la source
Dans son mode par défaut, git pull est un raccourci pour git fetch suivi de git merge FETCH_HEAD. Donc, vos déclarations sont en quelque sorte en conflit les unes avec les autres.
zzk
Eh bien, je dirais, sa caisse. Ne tirez pas. Je mettrai à jour la question pour être claire.
Kevin Rave
2
avez-vous déjà trouvé une solution à cela? Les attributs git ne sont utiles que dans le cas où le fichier a des conflits entre les branches fusionnées, donc ce n'est pas toujours suffisant.
pvinis
avez-vous cherché des liens symboliques (non suivis de git) ou même durs à la rescousse?
Frank Nocke

Réponses:

94

J'ai surmonté ce problème en utilisant la commande git merge avec l' --no-commitoption, puis j'ai explicitement supprimé le fichier intermédiaire et ignoré les modifications apportées au fichier. Par exemple: disons que je veux ignorer toute modification pour que myfile.txtje procède comme suit:

git merge --no-ff --no-commit <merge-branch>
git reset HEAD myfile.txt
git checkout -- myfile.txt
git commit -m "merged <merge-branch>"

Vous pouvez placer les instructions 2 et 3 dans une boucle for, si vous avez une liste de fichiers à ignorer.

unmesh-gurjar
la source
2
J'ajouterais "--no-ff" si vous voulez qu'un fichier ne soit pas écrasé lorsque la fusion se produit dans une stratégie d'avance rapide.
Ilia Shakitko
1
alors que fait git reset HEAD myfile.txtexactement? Comment cela aide-t-il à atteindre notre objectif ici?
Kid_Learning_C
Comment mettre les lignes 2 et 3 en boucle?
AndroidDev
52

J'ai fini par trouver git attributes. Essayer. Travailler jusqu'à présent. N'a pas encore vérifié tous les scénarios. Mais ça devrait être la solution.

Stratégies de fusion - Attributs Git

Kevin Rave
la source
4
mais j'ai trouvé ce git-scm.com/book/ch7-2.html#Merge-Strategies
Nate-
1
Voici le lien correct pour la section des stratégies de fusion de la documentation sur les attributs git: git-scm.com/book/en/v2/…
Adrian Laurenzi
3
J'ai
ShawnFeatherly
10
Cela semble être un problème s'il n'y a pas de conflits? Les fichiers seront toujours fusionnés?
Brett
18

.gitattributes - est un fichier de niveau racine de votre référentiel qui définit les attributs d'un sous-répertoire ou d'un sous-ensemble de fichiers.

Vous pouvez spécifier l'attribut pour indiquer à Git d'utiliser différentes stratégies de fusion pour un fichier spécifique. Ici, nous voulons préserver l'existant config.xmlpour notre agence. Nous devons régler le merge=ourspour config.xmldans le .gitattributesfichier.

merge=ours dites à git d'utiliser notre fichier (branche actuelle), si un conflit de fusion se produit.

  1. Ajouter un .gitattributesfichier au niveau racine du référentiel

  2. Vous pouvez configurer un attribut pour confix.xml dans le .gitattributesfichier

    config.xml merge=ours
    
  3. Et puis définissez une stratégie de fusion factice avec:

    $ git config --global merge.ours.driver true
    

Si vous fusionnez une branche de stagformulaire dev, au lieu d'avoir des conflits de fusion avec le fichier config.xml, config.xml de la branche stag est conservé dans la version d'origine.

eigenharsha
la source
16
Mais que faire s'il n'y a pas de conflit? Comment toujours conserver un certain fichier lors de la fusion?
Igor Yalovoy
2
@IgorYalovoy: S'il n'y a pas de conflit ... eh bien, c'est un peu délicat car cela fonctionne en fait à partir des ID de hachage, mais: si elle config.xmlest complètement inchangée de la base de fusion à l'une ou l'autre des versions de pointe de branche, Git prend simplement la version modifiée, sans en regardant le merge.ours.driverdécor. Vous avez donc raison de vous inquiéter.
torek le
1
copier-coller depuis Git Docs: Merge Strategies - Git attributes. Lien
kyb
Cette méthode entraîne des «validations de fusion» à chaque fois que FYI.
rsmets
2
«le nôtre» semble être un nom arbitraire pour la nouvelle stratégie introduite. J'ai trouvé cela déroutant, car il theirss'agit d'une stratégie de fusion intégrée. Mais il semble que l'on puisse écrire <pattern> merge=foo, alors git config --global merge.foo.driver true, et cela fonctionnera de la même manière.
Kyle Strand
8

Vous pouvez commencer par utiliser git merge --no-commit, puis éditer la fusion comme vous le souhaitez, c'est-à-dire en désinstallant config.xmlou tout autre fichier, puis valider. Je suppose que vous voudrez l'automatiser davantage après cela en utilisant des crochets, mais je pense que cela vaudrait la peine de passer manuellement au moins une fois.

gcbenison
la source
2
git attributesN'offrir une solution droit? Je ne peux pas comprendre cela. git-scm.com/book/en/…
Kevin Rave
4

Vous pouvez utiliser .gitignorepour garder le config.xmlhors du référentiel, puis utiliser un hook post-commit pour télécharger le config.xmlfichier approprié sur le serveur.

tlehman
la source
1
Je sais que c'est une sorte de piratage. J'essaye de trouver une solution propre. Et git attributes. Une idée de comment ça marche? Je ne peux pas comprendre cela. git-scm.com/book/en/…
Kevin Rave
1
Je n'en ai pas entendu parler, j'essaie d'appliquer l'attribut merge = our, semble prometteur.
tlehman
1
Les attributs Git sont géniaux! Vous pouvez même dire à git comment différencier des fichiers non texte, vous pouvez donc utiliser pdf2text pour différer des PDF!
tlehman
2

Exemple:

  1. Vous avez deux branches: master,develop
  2. Vous avez créé un fichier dans la developbranche et souhaitez l'ignorer lors de la fusion

Code:

git config --global merge.ours.driver true
git checkout master
echo "path/file_to_ignore merge=ours" >> .gitattributes
git merge develop

Vous pouvez également ignorer les fichiers avec la même extension

par exemple tous les fichiers avec l' .txtextension:

echo "*.txt merge=ours" >> .gitattributes
Sole Sensei
la source
1

Ici git-update-index - Enregistre le contenu du fichier dans l'arborescence de travail dans l'index.

git update-index --assume-unchanged <PATH_OF_THE_FILE>

Exemple:-

git update-index --assume-unchanged somelocation/pom.xml

Sireesh Yarlagadda
la source
C'est bien quand on pousse, mais on se plaint quand même quand tirer peut écraser le fichier.
Rolf
1
avez-vous essayé d'ajouter votre entrée de fichier dans le fichier .gitignore. @Rolf
Sireesh Yarlagadda