Fazendo git verificar o diretório de trabalho para integridade

3

O git tem uma forma interna * para checar se os arquivos no diretório de trabalho foram alterados magicamente **?

Em caso afirmativo: Como alguém faz o git verificar a integridade do diretório de trabalho?

* Descobrir quais arquivos no diretório de trabalho são rastreados, apenas hashing deles, excluí-los, verificá-los, novamente, hash-los, novamente, e comparando os hashes não contam como "built-in". / p>

** O conteúdo dos arquivos foi alterado por causa de um raio cósmico atingindo o HDD, um unicórnio galopando sobre as placas ou outros meios que não permitem que o FS saiba que uma mudança aconteceu (como editar o dispositivo de caractere).

*** No nome, conteúdo ou outras propriedades rastreadas (como ter magicamente se tornado executável).

Note que esta questão é uma versão enfraquecida de que outra questão . Responder a essa pergunta (a que você está lendo atualmente) é mais fácil. Ligarei a esta pergunta na outra questão se esta questão for resolvida e aponte as partes da outra questão que não foram resolvidas pelas respostas abaixo desta questão.

Foi perguntado qual é a diferença entre git status e o que estou pedindo. git status apenas observa mudanças se o FS informar que mudanças ocorreram. Se os arquivos foram corrompidos magicamente, o FS não sabe, portanto, git status não indicará uma alteração. git diff , git add --all , etc. também não, é claro.

Em resposta à proposta de usar git fsck : não funciona.

O que eu fiz:

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

Neste ponto, eu abri /tmp/con no meu editor hexadecimal favorito, procurei a palavra "contents" e troquei o "s" no final por um "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

Foi proposto tocar todos os arquivos no diretório de trabalho. Alterar a data acessada não seria um grande problema, mas isso não faz com que o git volte a verificar o arquivo. Alterar a data modificada realmente faz o git verificar esses arquivos novamente, no entanto, isso também causa outros problemas: Backup de aplicativos de volta o arquivo, novamente. Com grandes repositórios, isso pode ser um problema.

    
por UTF-8 22.02.2017 / 00:05

2 respostas

0

Eu estava lendo uma resposta para outra pergunta, sobre como fazer com que o git reconheça suas novas preferências de fim de linha no github , e incluiu esta gema:

  1. Remove the index and force Git to rescan the working directory.

    rm .git/index

  2. Rewrite the Git index to pick up all the new line endings.

    git reset

  3. Show the rewritten, normalized files.

    git status

Sugere salvar seu estado atual caso você tenha alguma coisa com a qual se preocupe, o que pode ser relevante.

Especialmente desde que a etapa de reinicialização do git irá reescrever o arquivo.

    
por 09.04.2018 / 17:45
0

Esta resposta em SO diz que:

Git tries hard to get convinced from the lstat() value alone that the worktree matches the index, because falling back on file contents is very expensive.

Em outras palavras, comparar o byte a byte do arquivo levaria bastante tempo, então o git tenta otimizá-lo comparando os resultados de lstat funciona primeiro. Isso inclui o tamanho do arquivo e a hora da modificação. Se estes não forem alterados, o git assumirá que o arquivo não foi modificado. Como você provou, não é um método infalível, mas funciona para casos que o git foi projetado para manipular.

A alteração de qualquer um dos valores retornados por lstat fará com que o git verifique novamente os arquivos para modificação:

$ 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")
    
por 22.02.2017 / 23:17

Tags