web-dev-qa-db-fra.com

Git - Différence entre 'assume-inchangé' et 'skip-worktree'

J'ai des modifications locales dans un fichier que je ne souhaite pas valider dans mon référentiel. C'est un fichier de configuration pour la construction de l'application sur un serveur, mais je veux construire localement avec des paramètres différents. Naturellement, le fichier apparaît toujours lorsque je fais 'statut Git' comme quelque chose à mettre en scène. Je voudrais cacher ce changement particulier et ne pas le commettre. Je ne ferai aucune autre modification dans le fichier.

Après quelques recherches, je vois deux options: "suppose-non modifié" et "saute-arbre de travail". Une question précédente ici en parle mais n'explique pas vraiment leurs différences. Ma question est la suivante: en quoi les deux commandes sont-elles différentes? Pourquoi quelqu'un utiliserait-il l'un ou l'autre?

376
ckb

Vous voulez skip-worktree.

assume-unchanged est conçu pour les cas où il est coûteux de vérifier si un groupe de fichiers a été modifié; Lorsque vous définissez le bit, git (bien sûr) suppose que les fichiers correspondant à cette partie de l'index n'ont pas été modifiés dans la copie de travail. Donc, cela évite un désordre d'appels stat. Ce bit est perdu chaque fois que l'entrée du fichier dans l'index change (donc, lorsque le fichier est modifié en amont).

skip-worktree est plus que cela: même où git sait que le fichier a été modifié (ou doit être modifié par un reset --hard ou similaire), il prétendra ne pas l'avoir été, en utilisant la version de l'index. Cela persiste jusqu'à ce que l'index soit supprimé.

Il existe un bon résumé des ramifications de cette différence et des cas d’utilisation types ici: http://fallengamer.livejournal.com/93321.html .

De cet article:

  • --assume-unchanged suppose qu'un développeur ne devrait pas modifier un fichier. Cet indicateur est destiné à améliorer les performances pour ne pas modifier les dossiers tels que les SDK.
  • --skip-worktree est utile lorsque vous demandez à git de ne jamais toucher à un fichier spécifique car les développeurs doivent le modifier. Par exemple, si le référentiel principal en amont héberge des fichiers de configuration prêts à la production et que vous ne souhaitez pas valider accidentellement les modifications apportées à ces fichiers, --skip-worktree est exactement ce que vous voulez.
557
Borealid

Remarque: Fallengamer a fait quelques tests en 2011 (ils peuvent donc être obsolètes), et voici ses conclusions :

Opérations

  • Le fichier est modifié à la fois dans le référentiel local et en amont
    git pull:
    Git préserve néanmoins les changements locaux.
    Ainsi, vous ne perdriez pas accidentellement les données que vous avez marquées avec l’un des drapeaux.
    • Fichier avec assume-unchanged flag: Git n’écrasera pas le fichier local. Au lieu de cela, il générerait des conflits et des conseils pour les résoudre.
    • Fichier avec skip-worktree flag: Git n’écrasera pas le fichier local. Au lieu de cela, il générerait des conflits et des conseils pour les résoudre.
  • Le fichier est modifié à la fois dans le référentiel local et en amont, en essayant de tirer quand même
    git stash
    git pull
    L’utilisation de _skip-worktree_ entraîne un travail manuel supplémentaire, mais au moins vous ne perdriez aucune donnée si vous apportiez des modifications locales.
    • Fichier avec assume-unchanged flag: ignore toutes les modifications locales sans possibilité de les restaurer. L’effet ressemble à "_git reset --hard_". L’appel "_git pull_" aboutira
    • Fichier avec skip-worktree flag: Stash ne fonctionnerait pas sur les fichiers _skip-worktree_. "_git pull_" échouera avec la même erreur que ci-dessus. Le développeur est obligé de réinitialiser manuellement l'indicateur _skip-worktree_ pour pouvoir stocker et terminer le pull défaillant.
  • Aucun changement local, fichier en amont modifié
    git pull
    Les deux drapeaux ne vous empêcheraient pas d’obtenir des modifications en amont. Git détecte que vous avez brisé la promesse _assume-unchanged_ et choisit de refléter la réalité en réinitialisant le drapeau.
    • Fichier avec assume-unchanged flag: le contenu est mis à jour, le drapeau est perdu.
      ‘_git ls-files -v_’ indique que cet indicateur est modifié en H (de h).
    • Fichier avec skip-worktree flag: le contenu est mis à jour, le drapeau est préservé.
      ‘_git ls-files -v_ 'afficherait le même drapeau S qu’avant la pull.
  • Avec le fichier local changé
    git reset --hard
    Git ne touche pas le fichier _skip-worktree_ et reflète la réalité (le fichier promis de ne pas être modifié a été modifié) pour le fichier _assume-unchanged_.
    • Fichier avec assume-unchanged flag: le contenu du fichier est annulé. L'indicateur est réinitialisé sur H (à partir de h).
    • Fichier avec skip-worktree flag: le contenu du fichier est intact. Le drapeau reste le même.

Il ajoute l'analyse suivante:

  • Il semble que skip-worktree est essaie très fort de préserver vos données locales. Mais cela ne vous empêche pas d’obtenir des modifications en amont si cela est sûr. De plus, git ne réinitialise pas le drapeau sur pull.
    Mais ignorer la commande ‘_reset --hard_ 'pourrait devenir une mauvaise surprise pour un développeur.

  • L’indicateur _Assume-unchanged_ pourrait être perdu lors de l’opération pull et les modifications locales dans ces fichiers ne semblent pas avoir d’importance pour git.

Voir:

Il conclut:

En fait, aucun des drapeaux n'est suffisamment intuitif.

  • assume-unchanged suppose qu'un développeur ne doit pas modifier un fichier. Si un fichier a été modifié, ce changement n’est pas important. Cet indicateur est destiné à améliorer les performances pour ne pas modifier les dossiers tels que les SDK.
    Mais si la promesse est brisée et qu'un fichier est réellement modifié, git rétablit le drapeau pour refléter la réalité. Il est probablement correct d’avoir des indicateurs incohérents dans des dossiers généralement non modifiés.

  • D'autre part skip-worktree est utile lorsque vous demandez à git de ne jamais toucher un fichier spécifique. Cela est utile pour un fichier de configuration déjà suivi.
    Le référentiel principal en amont héberge une configuration prête pour la production, mais vous souhaitez modifier certains paramètres de la configuration pour pouvoir effectuer des tests locaux. Et vous ne voulez pas vérifier accidentellement les modifications dans ce fichier pour affecter la configuration de production. Dans ce cas, _skip-worktree_ crée une scène parfaite.

89
VonC