Ignorer les modifications spécifiques à un fichier dans git, mais pas le fichier entier

j'ai un fichier dans un dépôt git qui a une modification locale. Je veux que git ignore le changement local pour toujours, mais pas le fichier. En particulier,

  • si le fichier n'est pas touché à part ce changement, git add . ne devrait jamais le mettre en scène.
  • de même, git commit -a ne devrait pas le commettre.
  • si jamais je fais une modification supplémentaire au fichier, je devrais être en mesure de mettre en scène et de commettre ce changement - mais le le changement que j'ignore devrait et non être mis en scène et engagé.

y a-t-il un moyen de le faire? En faisant quelques recherches, j'ai lu à propos de "cycle de purification / purification", où, si je lis bien,

  1. le fichier serait marqué comme inchangé,
  2. la modification que j'ai faite serait écrasé quand je caisse,
  3. et alors un script réappliquerait automatiquement le changement et marquerait alors le fichier inchangé à nouveau.

je suis très nouveau à git et à scripting, bien que (je suis un stagiaire avec C# et expérience Java), donc si c'est ce que je dois faire, Pouvez-vous s'il vous plaît poster des instructions détaillées ou un lien vers un tutoriel sur la façon de définir un cycle smudge/clean up?

Contexte: je veux que mon travail de la branche hors de synchronisation avec le tronc. Il y a un bug de faible priorité qui n'affecte que les machines de développement, donc plutôt que répare ça, on commente juste le code criminel. Évidemment, nous ne voulons pas que ce code soit retiré de la production, où il fonctionne très bien.

30
demandé sur Kevin 2013-05-17 02:05:16

9 réponses

comme je le vois, la situation que vous décrivez est la suivante: vous voulez maintenir un répertoire de travail qui est différent du dépôt local.

ce n'est pas conseillé; parce que ces changements ne sont pas commis, vous aurez peu de recours si un fichier est accidentellement supprimé ou modifié d'une manière que vous ne voulez pas.

il est donc recommandé que vous commettiez effectivement toutes vos modifications. Si vous souhaitez séparer ces modifications, vous pouvez faites ça facilement en utilisant une branche. Exemple

git checkout -b new-branch
# now you can change the file without affecting master
echo bar >> foo
git add
git commit
# and back to master
git checkout master
4
répondu Steven Penny 2013-05-17 03:57:48

vous pouvez utiliser le bit skip-worktree. Allumez-le avec:

git update-index --skip-worktree <file>

après cela, git ne mettra jamais en scène des changements locaux pour <file> et échouera (fort) si git lui-même doit écrire à <file> (disons, dans une fusion ou une caisse).

si vous voulez un jour mettre en scène un changement futur, vous pouvez le désactiver, mettre en scène le nouveau changement, puis le remettre en marche:

git update-index --no-skip-worktree <file>
git add -p <file>
git update-index --skip-worktree <file>

bien que pas parfait, ce pourrait être bon assez. Ce sera à vous de remarquer que <file> a des changements non marqués, puisque git ne vous dira plus que

Note: ma suggestion initiale était d'utiliser l'hypothèse-inchangée. Comme expliqué dans Git - différence entre "supposer-inchangé" et "skip-worktree " , il est vraiment skip-worktree que vous voulez.

34
répondu Mark Lodato 2018-04-27 23:08:16

le" patch mode " de Git est parfait pour ajouter seulement certaines modifications d'un fichier à votre commit.

pour le Démarrer, tapez git add -p , git commit -p (direct à commit message when done), ou git add --interactive (plus d'invites).

il vous emmène essentiellement à travers chaque section de code montré dans git diff et vous demande si vous voulez le mettre en scène ou non.

lorsque vous atteignez le changement, répondez n o, ou e pour ouvrir le patch dans votre $de l'ÉDITEUR.

3
répondu Riking 2016-01-27 19:36:47

Note: d'autres personnes ont dit que se tenir à l'écart des changements locaux persistants est une mauvaise idée, et je n'ai aucune raison de ne pas être d'accord. Envisagez d'autres options.

Voici la méthode que j'aime:

  1. faites quelques changements que vous voulez garder sur votre machine locale.
  2. utilisez git branch local et git checkout local pour créer une nouvelle branche pour vos modifications locales. (Si je ne me trompe pas, ces commandes ne configureront pas une branche distante automatiquement, donc la nouvelle branche ne sera pas poussée.)
  3. utilisez git commit pour propager vos modifications.
  4. faire les changements que vous voulez pousser en amont.
  5. utilisez git checkout parent pour revenir à la branche que vous voulez pousser.
  6. utilisez git commit pour vous engager dans cette branche.
  7. utilisez git push pour pousser vos modifications.
  8. utilisez git checkout local pour retourner à votre succursale locale.
  9. utilisez git rebase parent pour passer de parent à local . L'utilisation de rebase vous permettra de faire en sorte que vos modifications locales restent en haut des changements dans parent .
  10. retournez à l'étape 4 et répétez ad nauseam.

avec ceci, vous n'avez pas à dire manuellement à git quels changements sont locaux et lesquels ne sont pas à chaque fois que vous voulez faire un changement.

2
répondu Tanner Swett 2015-01-21 21:23:42

Oui, cela pourrait probablement être fait en utilisant des filtres de purge. Cependant, je conseillerais fortement de ne pas le faire, car il serait plutôt complexe et sujet à des erreurs (par exemple, il confondrait de nombreux outils en se basant sur git, il rendrait les problèmes difficiles à déboguer, etc.).

Aussi, il n'est généralement pas une bonne idée d'avoir permanents des changements locaux. Un point important de l'utilisation D'un SCM est que vous pouvez vérifier une version et le faire fonctionner immédiatement. Cela signifie que tout le que vous avez besoin doit être vérifiée.

Je ne pense pas qu'il y ait une" bonne " façon de le faire, ni avec git ni probablement avec la plupart des autres SCM. Je vous recommande de reconsidérer vos exigences.

le problème semble être que vous avez un fichier avec "mixed content": certains contenus qui sont toujours les mêmes, et d'autres qui doivent être modifiés localement (options spécifiques à la machine?). La façon recommandée de gérer ceci n'est pas de vérifier le fichier problématique, mais au lieu de cela, cochez un fichier "template", puis générez le fichier réel au moment de la compilation. Essayez de l'enquête sur ce. Il y aura plus de travail maintenant (peut-être), mais cela facilitera les choses, surtout si vous devez supporter plus de variation ou si d'autres personnes veulent travailler sur le même projet.

modifier (sur la base d'informations dans le commentaire)

vous écrivez que vous voulez ignorer un changement de code local qui est seulement nécessaire pour les machines de développement, mais pas dans la production.

dans ce cas, au lieu de commenter, envelopper le code dans un État quelconque, de sorte qu'il ne fonctionne que sur les machines dev (par exemple en utilisant une compilation conditionnelle, ou en lisant un fichier de configuration ou une propriété d'environnement, ou ...(1)). Ensuite, vous pouvez vérifier le code normalement.

encore mieux, il suffit de corriger le bug. Si un bug rend le développement difficile, alors IMHO il est de haute priorité.

commentant le code est pas une bonne idée. Il est sujet aux erreurs et doit être fait chaque fois que vous vérifiez. Par-dessus tout, l'exécution de code différent dans le développement et dans la production demande des problèmes et doit être évitée dans la mesure du possible.

(1) comme exemple: dans notre entreprise, nous avons une variable d'environnement spécifique pour des cas comme celui-ci. Il indique si le code est en développement, en test bêta ou en production, et est défini par nos scripts de construction et de déploiement. Cependant, il est généralement utilisé uniquement pour des choses simples comme le choix de différents chemins de fichier. Changer la logique du programme en fonction de l'environnement est déconseillé, comme expliqué ci-dessus.

1
répondu sleske 2013-05-17 17:10:54

ces réponses sont bonnes, mais ne résoudront peut-être pas le mieux le problème de @Kevin. J'avais un problème similaire, éditant souvent un fichier de configuration de sorte que l'application sur laquelle je travaillais accédait à ma propre base de données de développement privée au lieu de celle de production. Ce n'est qu'une question de temps avant que je vérifie accidentellement et pousse ces changements de configuration! J'ai juste besoin d'un poids léger façon d'ignorer un fichier. Voici ce que j'ai appris:

  • Première, faites vos changements nécessaires à votre dossier. Je l'appellerai my_config .

  • faire un fichier patch de ce changement avec git diff >../somewhere-else/my_config.patch

  • Maintenant, dites à git d'ignorer ce fichier (sans avoir à changer le fichier enregistré .gitignore): git update-index --assume-unchanged my_config

maintenant, tant que vous n'apportez pas de changements à my_config que vous do voulez vérifier dans, vous pouvez travailler librement. Pour arrêter d'ignorer my_config , faites git update-index --no-assume-unchanged my_config . Après avoir apporté les modifications de quelqu'un d'autre à my_config , vous pouvez facilement restaurer votre changement privé avec git apply ../somewhere-else/my_config.patch , alors ...supposons-inchangé encore une fois, comme ci-dessus, et de retourner au travail!

voici quelques alias utiles que vous pouvez mettre dans votre ~/.gitconfig :

[alias]
    unchanged = update-index --assume-unchanged
    changed = update-index --no-assume-unchanged
    show-unchanged = !"git ls-files -v | sed -e 's/^[a-z] //p; d'"
1
répondu Tyler Perkins 2018-03-19 18:30:00

si vous ne pouvez pas l'utiliser .gitignore comme vous avez besoin de faire des changements parallèles dans le même fichier(comme trouvé dans vos commentaires) alors une option est git add-p En utilisant ce que vous pouvez ajouter ou sauter en conséquence.

le problème en utilisant la commande git ci-dessus est qu'il s'agit plutôt d'un processus manuel. Je suppose que vous ne trouverez pas d'autre approche automatisée pour Vous problème.

0
répondu Bijendra 2013-05-17 05:59:05

à partir de Git 2.5 (juillet 2015), vous pouvez utiliser git worktree :

git worktree add -b patch-1 ../patch-1

il s'agit essentiellement de créer une branche, mais il met la nouvelle branche dans une nouveau dossier à côté du dossier parent. C'est sympa parce que tu peux travailler sur cette branche, même sans commettre, puis revenir à master avec un nettoyage répertoire de travail.

0
répondu 2016-01-24 03:38:20

si vous utilisez intellij comme IDE, alors il a une fonctionnalité soignée (listes de modifications) qui, je crois, fait exactement ce que OP demande.

vous pouvez marquer et nommer une partie spécifique de votre diff locale. Si mémoire sert, cela gardera ces changements séparés de toutes les autres modifications locales et ne sera mis en scène pour commettre que si vous choisissez activement de le faire - tant que vous faites votre commettre d'intellij.

0
répondu LOAS 2018-02-19 10:25:37