Git – Différence Entre ‘suppose-inchangé’ et ‘skip-worktree’

J’ai des modifications locales à un fichier que je ne veux pas engager dans mon référentiel. C’est un fichier de configuration pour la construction de l’application sur un serveur, mais je veux créer localement avec différents parameters. Naturellement, le fichier apparaît toujours lorsque je fais «git status» comme quelque chose à mettre en scène. Je voudrais cacher ce changement particulier et ne pas le commettre. Je ne ferai aucune autre modification au fichier.

Après quelques recherches, je vois 2 options: ‘assumer inchangé’ et ‘sauter-worktree’. Une question précédente parle d’eux 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?

    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 si git sait que le fichier a été modifié (ou doit être modifié par un reset --hard ou similaire), il fera semblant de ne pas l’avoir utilisé à la place de la version de l’index . Cela persiste jusqu’à ce que l’index soit supprimé.

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

    De cet article:

    • --assume-unchanged suppose qu’un développeur ne doit 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 pour la production et que vous ne voulez pas commettre accidentellement des modifications sur ces fichiers, --skip-worktree est exactement ce que vous voulez.

    Note: fallengamer a fait des tests en 2011 (ils sont peut-être obsolètes) et voici ses conclusions :

    Les opérations

    • Le fichier est modifié à la fois dans le référentiel local et en amont
      git pull :
      Git conserve de toute façon les changements locaux.
      Ainsi, vous ne perdriez pas accidentellement les données que vous avez marquées avec l’un des indicateurs.
      • Fichier avec un drapeau supposé assume-unchanged : Git ne remplace pas le fichier local. Au lieu de cela il produirait des conflits et des conseils sur la façon de les résoudre
      • Fichier avec indicateur skip-worktree : Git ne remplace pas le fichier local. Au lieu de cela il produirait des conflits et des conseils sur la façon de 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 aviez des modifications locales.
      • Fichier avec un drapeau supposé assume-unchanged : rejette toutes les modifications locales sans aucune possibilité de les restaurer. L’effet est comme ‘ git reset --hard ‘. ‘ git pull ‘ appel réussira
      • Fichier avec indicateur skip-worktree : Stash ne fonctionnerait pas sur skip-worktree 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 ranger et terminer le pull défaillant.

    .

    • Aucune modification locale, 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 rompu la promesse assume-unchanged et choisit de refléter la réalité en réinitialisant le drapeau.
      • Fichier avec indicateur assume-unchanged : le contenu est mis à jour, l’indicateur est perdu.
        git ls-files -v ‘ montrerait que le drapeau est modifié en H (de h ).
      • Fichier avec indicateur skip-worktree : le contenu est mis à jour, l’indicateur est conservé.
        git ls-files -v ‘ afficherait le même drapeau S qu’avant la pull .

    .

    • Avec fichier local modifié
      git reset --hard
      Git ne touche pas le fichier skip-worktree et reflète la réalité (le fichier promis à être inchangé a effectivement été modifié) pour le fichier skip-worktree assume-unchanged .
      • Fichier avec indicateur assume-unchanged : le contenu du fichier est annulé. Le drapeau est remis à H (à partir de h ).
      • Fichier avec indicateur skip-worktree : le contenu du fichier est intact. Le drapeau rest le même.

    Il ajoute l’parsing suivante:

    • Il semble que skip-worktree s’efforce de préserver vos données locales . Mais cela ne vous empêche pas d’obtenir des modifications en amont si elles sont sûres. De plus, git ne réinitialise pas le drapeau en pull .
      Mais ignorer la commande ‘ reset --hard ‘ pourrait devenir une mauvaise surprise pour un développeur.

    • Assume-unchanged indicateur Assume-unchanged puisse être perdu lors de l’opération d’ pull et que les modifications locales à l’intérieur de ces fichiers ne semblent pas importantes pour git.

    Voir:

    • Commentaire de Junio ​​(mainteneur actuel de git) concernant l’intention de assume-unchanged ,
    • différence entre assume-unchanged et skip-worktree comme indiqué dans la liste de diffusion git lors de l’ajout du correctif skip-worktree .

    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 rompue et qu’un fichier est réellement modifié, git rétablit l’indicateur pour refléter la réalité. Il est probablement correct d’avoir des indicateurs incohérents dans les dossiers généralement non-modifiés.

    • D’un autre côté, 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 repository principal en amont héberge une configuration prête pour la production, mais vous souhaitez modifier certains parameters de la configuration pour pouvoir effectuer des tests locaux. Et vous ne voulez pas vérifier accidentellement les modifications dans un tel fichier pour affecter la configuration de production. Dans ce cas, skip-worktree fait une scène parfaite.