sirve - Git: encuentra blobs duplicados(archivos) en este árbol
subir archivos git (5)
Esto es una especie de continuación de esta pregunta .
Si hay varios blobs con los mismos contenidos, solo se almacenan una vez en el repositorio de git porque sus SHA-1 serán idénticos. ¿Cómo se podría encontrar todos los archivos duplicados para un árbol determinado?
¿Tendría que caminar por el árbol y buscar hashes duplicados, o tiene git enlaces de retroceso de cada blob a todos los archivos en un árbol que hace referencia a él?
Ejecutar esto en la base de código en la que trabajo fue una revelación que puedo decirte!
#!/usr/bin/perl
# usage: git ls-tree -r HEAD | $PROGRAM_NAME
use strict;
use warnings;
my $sha1_path = {};
while (my $line = <STDIN>) {
chomp $line;
if ($line =~ m{ /A /d+ /s+ /w+ /s+ (/w+) /s+ (/S+) /z }xms) {
my $sha1 = $1;
my $path = $2;
push @{$sha1_path->{$sha1}}, $path;
}
}
foreach my $sha1 (keys %$sha1_path) {
if (scalar @{$sha1_path->{$sha1}} > 1) {
foreach my $path (@{$sha1_path->{$sha1}}) {
print "$sha1 $path/n";
}
print ''-'' x 40, "/n";
}
}
Las respuestas de scripting de su pregunta vinculada también se aplican aquí.
Pruebe el siguiente comando git desde la raíz de su repositorio de git.
git ls-tree -r HEAD
Esto genera una lista recursiva de todos los ''blobs'' en el HEAD actual, incluyendo su ruta y su id. Sha1.
git no mantiene los enlaces de atrás de un blob en un árbol, entonces sería una tarea de scripting (perl, python?) analizar un resultado de git ls-tree -r
y crear un informe de resumen de todos los sha1 que aparecen más de una vez en el lista.
Acabo de hacer una sola línea que resalte los duplicados renderizados por git ls-tree
.
Puede ser útil
git ls-tree -r HEAD |
sort -t '' '' -k 3 |
perl -ne ''$1 && / $1/t/ && print "/e[0;31m" ; / ([0-9a-f]{40})/t/; print "$_/e[0m"''
[alias]
# find duplicate files from root
alldupes = !"git ls-tree -r HEAD | cut -c 13- | sort | uniq -D -w 40"
# find duplicate files from the current folder (can also be root)
dupes = !"cd `pwd`/$GIT_PREFIX && git ls-tree -r HEAD | cut -c 13- | sort | uniq -D -w 40"
Mas general:
( for f in `find .`; do test -f $f && echo $(wc -c <$f) $(md5 -q $f) ; done ) |sort |uniq -c |grep -vE ''^/s*1/b'' |sed ''s/.* //'' > ~/dup.md5 ; /
( for f in `find .`; do test -f $f && echo $(wc -c <$f) $(md5 -q $f) $f; done ) |fgrep -f ~/dup.md5 |sort