5 votes

Faire en sorte que git vérifie l'intégrité du répertoire de travail

Est-ce que git a un moyen intégré* de vérifier si les fichiers du répertoire de travail ont magiquement** changé*** ?

Si oui, comment faire pour que git vérifie l'intégrité du répertoire de travail ?

* Déterminer quels fichiers du répertoire de travail sont suivis, les hacher uniquement, les supprimer, les vérifier à nouveau, les hacher à nouveau, et comparer les hachages ne compte pas vraiment comme "intégré".

** Le contenu des fichiers a changé à cause d'un rayon cosmique qui a frappé le disque dur, d'une licorne qui a galopé sur les plaques, ou d'autres moyens qui ne permettent pas au FS de savoir qu'un changement s'est produit (comme l'édition du périphérique de caractères).

*** Dans le nom, le contenu, ou d'autres propriétés suivies (comme le fait d'être devenu exécutable par magie).


Notez que cette question est une version affaiblie de la question suivante l'autre question . Il est plus facile de répondre à cette question (celle que vous êtes en train de lire). Je ferai un lien vers cette question dans l'autre question si celle-ci est résolue et j'indiquerai les parties de l'autre question qui n'ont pas été résolues par les réponses sous cette question.

On s'est demandé quelle était la différence entre git status et ce que je demande, c'est. git status ne remarque les changements que si le FS lui dit que des changements se sont produits. Si des fichiers ont été corrompus par magie, le FS ne le sait donc pas, git status n'indique pas un changement. git diff , git add --all etc. ne le feront pas non plus, bien sûr.


En réponse à la proposition d'utiliser git fsck : Ça ne marche pas.

Ce que j'ai fait :

christoph@christoph-laptop-16-04-2:/t$ dd if=/dev/zero bs=1M count=30 of=/tmp/con
30+0 records in
30+0 records out
31457280 bytes (31 MB, 30 MiB) copied, 0.0143967 s, 2.2 GB/s
christoph@christoph-laptop-16-04-2:/t$ mkfs.ext4 /tmp/con
mke2fs 1.42.13 (17-May-2015)
Discarding device blocks: done                            
Creating filesystem with 30720 1k blocks and 7680 inodes
Filesystem UUID: 9865efe8-fb30-42ab-ace7-a8f88330bdfd
Superblock backups stored on blocks: 
    8193, 24577

Allocating group tables: done                            
Writing inode tables: done                            
Creating journal (1024 blocks): done
Writing superblocks and filesystem accounting information: done

christoph@christoph-laptop-16-04-2:/t$ sudo mount -t ext4 -o loop /tmp/con /mnt
[sudo] password for christoph: 
christoph@christoph-laptop-16-04-2:/t$ cd /mnt
christoph@christoph-laptop-16-04-2:/mnt$ sudo chown christoph .
christoph@christoph-laptop-16-04-2:/mnt$ git init
Initialized empty Git repository in /mnt/.git/
christoph@christoph-laptop-16-04-2:/mnt$ echo "some contents" > file
christoph@christoph-laptop-16-04-2:/mnt$ git add file 
christoph@christoph-laptop-16-04-2:/mnt$ git commit -m "a"
[master (root-commit) d29fbd5] a
 1 file changed, 1 insertion(+)
 create mode 100644 file
christoph@christoph-laptop-16-04-2:/mnt$ git status
On branch master
nothing to commit, working directory clean
christoph@christoph-laptop-16-04-2:/mnt$ cd ~
christoph@christoph-laptop-16-04-2:~$ sudo umount /mnt

A ce moment-là, j'ai ouvert /tmp/con dans mon éditeur hexagonal préféré, j'ai cherché le mot "contents", et j'ai remplacé le "s" de la fin par un "z".

christoph@christoph-laptop-16-04-2:~$ sudo mount -t ext4 -o loop /tmp/con /mnt
christoph@christoph-laptop-16-04-2:~$ cd /mnt
christoph@christoph-laptop-16-04-2:/mnt$ git status
On branch master
nothing to commit, working directory clean
christoph@christoph-laptop-16-04-2:/mnt$ cat file 
some contentz
christoph@christoph-laptop-16-04-2:/mnt$ git fsck
Checking object directories: 100% (256/256), done.
christoph@christoph-laptop-16-04-2:/mnt$ git status
On branch master
nothing to commit, working directory clean
christoph@christoph-laptop-16-04-2:/mnt$ cat file
some contentz

Il a été proposé de toucher tous les fichiers du répertoire de travail. Changer leur date d'accès ne serait pas un gros problème mais cela ne fait pas recontrôler le fichier par git. Changer leur date de modification fait que git vérifie à nouveau ces fichiers, mais cela cause aussi d'autres problèmes : Les applications de sauvegarde sauvegardent le fichier, à nouveau. Avec des dépôts importants, cela peut être un problème.

1voto

davenpcj Points 216

J'ai lu une réponse à une autre question, sur la façon de faire reconnaître par git vos nouvelles préférences de fin de ligne. sur github et il comprenait cette perle :

  1. Supprime l'index et force Git à rescanner le répertoire de travail.

    rm .git/index

  2. Réécriture de l'index Git pour prendre en compte toutes les nouvelles fins de lignes.

    git reset

  3. Montrer les fichiers réécrits et normalisés.

    git status

Il suggère de sauvegarder votre état actuel au cas où vous auriez quelque chose d'autre à faire valoir, qui pourrait être pertinent.

D'autant plus que l'étape git reset réécrira le fichier.

0voto

gronostaj Points 50460

Cette réponse sur le SO dit cela :

Git essaie de se convaincre, à partir de la seule valeur de lstat(), que l'arbre de travail correspond à l'index, car se baser sur le contenu des fichiers est très coûteux.

En d'autres termes, la comparaison du fichier octet par octet prendrait beaucoup de temps, c'est pourquoi git tente de l'optimiser en comparant les résultats de lstat d'abord. Cela inclut la taille du fichier et le temps de modification. S'ils sont inchangés, git suppose que le fichier n'a pas été modifié. Comme vous l'avez prouvé, ce n'est pas une méthode infaillible, mais elle fonctionne pour les cas que git a été conçu pour gérer.

La modification de l'une des valeurs renvoyées par lstat fera en sorte que git revérifie les fichiers en cas de modification :

$ touch file
$ git status
On branch master
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

        modified:   file

no changes added to commit (use "git add" and/or "git commit -a")

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X