git pull en conservant les modifications locales


132

Comment puis-je mettre à jour (extraire) en toute sécurité un projet git, en gardant des fichiers spécifiques intacts, même s'il y a des modifications en amont?

myrepo / config / config.php

Y a-t-il un moyen, même si ce fichier était modifié à distance, lorsque je git pull, tout le reste est mis à jour, mais ce fichier est inchangé (même pas fusionné)?

PS. Je dois faire ce que je demande car je n'écris que des scripts de déploiement basés sur git. Je ne peux pas changer les fichiers de configuration en modèles.

donc, j'ai besoin d'un moyen d'écrire des scripts de mise à jour qui ne perdent pas ce qui a été modifié localement. J'espérais quelque chose d'aussi simple que:

git assume-remote-unchanged file1
git assume-remote-unchanged file2

puis git pull


Les changements sont-ils config.phpvalidés?
Mark Longair


Ce n'est pas engagé. Je préfère ne pas avoir à
Johnny Everson

@JhonnyEverson: C'est la même classe générale de problème (vous avez un fichier de configuration et vous ne voulez pas valider des paramètres spécifiques, mais la structure du fichier de configuration doit être suivie.)
Daenyth

Réponses:


248

Il existe une solution simple basée sur Git stash. Rangez tout ce que vous avez changé, tirez toutes les nouveautés, appliquez votre réserve.

git stash
git pull
git stash pop

Sur le stash pop, il peut y avoir des conflits. Dans le cas que vous décrivez, il y aurait en fait un conflit pour config.php. Mais résoudre le conflit est facile parce que vous savez que ce que vous mettez dans la cachette est ce que vous voulez. Alors fais ceci:

git checkout --theirs -- config.php

5
cette commande git checkout --theirs est très déroutante. Il a fait ce que je voulais une fois et quelque chose de vraiment mauvais une autre fois. Vous avez une bonne documentation là-dessus?
Milimetric

3
Oui, parfois «le leur» et «le nôtre» peuvent prêter à confusion. Dans un git merge«nôtre» se trouve ce qui se trouve actuellement dans le répertoire de travail. Mais pour un git rebase(ou git rebase -onto) le sens peut être échangé.
GoZoner

1
git stash , git pull , git stash apply Vous pouvez déposer la cachette avec: git stash dropUne fois que vous avez fusionné les modifications avec succès
BeingSuman

11
Le truc avec git est que vous devez comprendre ce qu'il va faire. L'autre chose avec git, c'est que même pour les gens intelligents, il est souvent très difficile de comprendre ce que git va faire.
Brad Thomas

1
Vous devriez vérifier s'il y a vraiment quelque chose à cacher. Sinon, vous afficherez les modifications cachées d'une version antérieure git stash.
Jörn Reimerdes

15

Si vous avez un fichier dans votre dépôt qu'il est censé être personnalisé par la plupart des extracteurs, renommez le fichier en quelque chose comme config.php.templateet ajoutez config.phpà votre fichier .gitignore.


5
vérifiez également cette réponse , vous pouvez utiliser .gitattributespour toujours conserver vos modifications lors de la fusion.
KurzedMetal

C'est plus ce dont j'avais besoin. Le modèle est la solution élégante, mais j'ai peur de ne pas pouvoir l'utiliser car je suis juste en train d'écrire des scripts de déploiement.
Johnny Everson

6

Mise à jour: cela répond littéralement à la question posée, mais je pense que la réponse de KurzedMetal est vraiment ce que vous voulez.

En admettant que:

  1. Tu es sur la branche master
  2. La branche amont est masterenorigin
  3. Vous n'avez aucune modification non validée

.... vous pourriez faire:

# Do a pull as usual, but don't commit the result:
git pull --no-commit

# Overwrite config/config.php with the version that was there before the merge
# and also stage that version:
git checkout HEAD config/config.php

# Create the commit:
git commit -F .git/MERGE_MSG

Vous pouvez créer un alias pour cela si vous devez le faire fréquemment. Notez que si vous avez des modifications non validées sur config/config.php, cela les rejettera.



1

Pour répondre à la question: si vous souhaitez exclure certains fichiers d'une extraction, vous pouvez utiliser l' extraction partielle

1) Dans .git/info/sparse-checkout, définissez ce que vous souhaitez conserver. Ici, nous voulons tout (*) mais (notez le point d'exclamation) config.php:

 /*
 !/config.php

2) Dites à git que vous voulez prendre en compte le paiement partiel

 git config core.sparseCheckout true

3) Si vous avez déjà ce fichier localement, faites ce que fait git sur une extraction éparse (dites-lui qu'il doit exclure ce fichier en définissant le drapeau "skip-worktree" dessus)

git update-index --skip-worktree config.php

4) Profitez d'un référentiel où votre fichier config.php est le vôtre - quels que soient les changements sur le référentiel.


Veuillez noter que les valeurs de configuration NE DOIVENT PAS être dans le contrôle de code source:

  • C'est une faille de sécurité potentielle
  • Cela pose des problèmes comme celui-ci pour le déploiement

Cela signifie que vous DEVEZ les exclure (les mettre dans .gitignore avant la première validation), et créer le fichier approprié sur chaque instance où vous extrayez votre application (en copiant et en adaptant un fichier "modèle")

Notez qu'une fois qu'un fichier est pris en charge par git, .gitignore n'aura aucun effet.

Étant donné que, une fois le fichier sous contrôle de code source, vous n'avez que deux choix (): - rebaser tout votre historique pour supprimer le fichier (avec git filter-branch) - créer un commit qui supprime le fichier. C'est comme mener une bataille perdue, mais, eh bien, il faut parfois vivre avec ça.


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.