Gardez le fichier dans un dépôt Git, mais ne suivez pas les modifications

305

J'ai plusieurs fichiers dans un site CodeIgniter que je souhaiterai avoir dans le référentiel mais sans suivre les modifications.

Par exemple, je déploie une nouvelle installation de ce framework sur un nouveau client, je souhaite que les fichiers suivants soient téléchargés (ils ont des valeurs par défaut CHANGEME) et je dois juste apporter des modifications spécifiques à ce client (informations d'identification de la base de données, informations d'adresse e-mail, CSS personnalisé).

// the production config files i want the files but they need to be updated to specific client needs
application/config/production/config.php
application/config/production/database.php
application/config/production/tank_auth.php
// index page, defines the environment (production|development)
/index.php
// all of the css/js cache (keep the folder but not the contents)
/assets/cache/*
// production user based styling (color, fonts etc) needs to be updated specific to client needs
/assets/frontend/css/user/frontend-user.css

Actuellement, si je cours

git clone [email protected]:user123/myRepo.git httpdocs

puis éditez les fichiers ci-dessus, tout va bien. Jusqu'à ce que je publie un correctif ou un correctif et que j'exécute git pull. Toutes mes modifications sont alors écrasées.

gorelative
la source
Vous pouvez simplement ignorer les fichiers d'informations d'identification / de configuration du client et demander au programme de créer des fichiers par défaut s'ils sont manquants lorsque le dépôt est installé?
MatthewG

Réponses:

618

git a une solution différente pour ce faire. Modifiez d'abord le fichier dont vous ne souhaitez pas le suivi et utilisez la commande suivante:

git update-index --assume-unchanged FILE_NAME

et si vous souhaitez suivre à nouveau les modifications, utilisez cette commande:

git update-index --no-assume-unchanged FILE_NAME

documentation git-update-index

nasirkhan
la source
J'ai fait ce que vous dites, mais l'état de git continue de dire que le fichier est modifié
rraallvv
7
Oui, cela devrait être la "réponse acceptée". A travaillé pour moi.
joshmcode
34
Selon Junio ​​Hamano (le mainteneur de Git): "Supposons-inchangé ne devrait pas être abusé pour un mécanisme d'ignorer. [...] ce n'est pas une promesse de Git que Git considérera toujours que ces chemins ne sont pas modifiés --- si Git peut déterminer un chemin qui est marqué comme supposant-inchangé a changé sans entraîner de coût supplémentaire lstat (2), il se réserve le droit de signaler que le chemin a été modifié (en conséquence, "git commit -a" est libre de valider changement)." En d'autres termes, assumer-inchangé est juste pour les problèmes de performances locaux. Si Git peut déterminer que ces fichiers ont changé de manière plus légère, il le fera.
Alejandro García Iglesias
41
En lisant les informations, je pense que l' --skip-worktreeoption est mieux adaptée à ce travail que --assume-unchanged.
PJSCopeland
26
--skip-worktree est en effet la meilleure option. Plus d'informations: stackoverflow.com/questions/13630849/…
Customizer
80

Pour extraire une réponse des commentaires d'une autre réponse:

$ git update-index --skip-worktree FILENAME

Semble être une meilleure option que --assume-unchanged

Vous pouvez en lire plus à ce sujet ici: Git - Différence entre 'assume-unchanged' et 'skip-worktree'

Anthony
la source
Lorsque je fais cela et que j'essaie de changer de branche, j'obtiens "Les fichiers d'arborescence de travail non suivis suivants seront écrasés par la caisse ... Veuillez les déplacer ou les supprimer avant de changer de branche". Des idées pour éviter?
Patrick Szalapski
L'article référencé par @aexl a été déplacé vers compiledsuccessfully.dev/git-skip-worktree
Andrew Keeton
1
Les docs disent que c'est une mauvaise idée. "Les utilisateurs essaient souvent d'utiliser les bits supposés inchangés et de saut de travail pour dire à Git d'ignorer les modifications apportées aux fichiers qui sont suivis. Cela ne fonctionne pas comme prévu, car Git peut toujours vérifier les fichiers d'arborescence de travail par rapport à l'index lors de certaines opérations. En général, Git ne fournit pas un moyen d'ignorer les modifications apportées aux fichiers suivis, des solutions alternatives sont donc recommandées. "
Curtis Blackwell
58

Pour mes projets Code Igniter, je garde database.php.example et config.php.example dans le référentiel.

Ensuite, j'ajoute config.php et applications / config / database.php au fichier .gitignore .

Donc, enfin, lorsque je déploie, je peux copier les fichiers .example (dans config.php et database.php), les personnaliser et ils ne seront pas suivis par GIT.

superiggy
la source
12
Belle solution, mais je pense que la réponse de nasirkhan est la meilleure.
wordsforhewise
Ce n'est pas une bonne solution. Si vous videz votre index git, vous allez commencer à suivre les modifications lorsque vous ne le souhaitez pas. Voir la réponse @nasirkhans pour la bonne façon de procéder.
Brian Melton-Grace - MSFT du
3
Je ne suis pas d'accord avec les deux commentaires précédents. De cette façon, il est beaucoup plus facile de mettre à jour les valeurs "par défaut" sans avoir à les extraire et à copier votre configuration locale ailleurs juste pour la remettre ensuite. En outre, il s'applique à tous les référentiels, vous n'avez donc pas à effectuer de changements de repo répétés.
OskarD90
1
s'il est dans gitignore, pourquoi recommencerait-il à suivre les changements
Shapeshifter
Résout le problème du PO mais ne répond pas vraiment à la question.
Travis Wilson du
1

Je les mettrais dans votre .gitignoredossier et les copierais juste manuellement au besoin.

Ainsi, le nom de fichier squelette serait dans git, les noms de fichiers ignorés ne seraient pas dans git (mais seraient dans .gitignore). De cette façon, lorsque l'étape manuelle pour les copier dans «réel» à partir de «modèle» (meilleur nom que squelette peut-être) est terminée, ils sont immédiatement ignorés.

Michael Durrant
la source
1
theres aucun moyen de les ajouter dans le repo d'abord, puis les ajouter à .gitignore? Ce serait génial s'il y avait une solution pour cela d'inclure les fichiers mais pas de changements après un certain commit ou quelque chose.
Gorelative
1
@mklauber Je veux les garder indéfiniment jusqu'à ce que je cours git rm <file>. Le but est IE: un fichier config.php. Je veux garder le fichier de configuration, mais je ne veux évidemment pas suivre les informations d'identification de la base de données de client en client car elles sont différentes.
Gorelative
1
Oui, j'ai un problème avec notre fichier rails database.yml. Nous gardons un squelette, puis le copions et le modifions.
Michael Durrant
si je crée ces fichiers de configuration "Skeleton", les ajouteriez-vous à un commit initial. puis en modifiant .gitignore pour ignorer le fichier? En effet, conserver le fichier dans le référentiel mais comme un squelette?
Gorelative
10
Vous avez ces deux options: Ajoutez le fichier par git add file1puis modifiez votre .gitignorefichier. Le fichier validé y restera et ne sera pas mis à jour. Ou: Vous pouvez ajouter le fichier à .gitignorepuis l'ajouter avec git add --force file1pour forcer le fichier. Vous pouvez utiliser la 2e option chaque fois que vous devez écraser le fichier
klaustopher
1

Les réponses données résolvent le problème seulement partiellement, mais introduisent encore plus de problèmes.

J'avais besoin de conserver le fichier "Web.Local.config". La seule solution qui a fonctionné pour moi était de:

1. Exclure le fichier du projet

2. Créez une copie distincte du fichier en tant que Web.LocalTemplate.config

Maintenant que "Web.LocalTemplate.config" est suivi par Git, tous les développeurs peuvent l'utiliser comme point de départ. Cependant, le "Web.Local.config", ne faisant pas partie du projet sera automatiquement ignoré.

Hrvoje Matić
la source
Comment est git update-index --skip-worktree FILENAME ne résout-on que partiellement votre problème, ou même en ajoute-t-il plus? Cela résout exactement ce que vous essayez de faire. Est-ce que tu l'as essayé?
Amir Asyraf