2008-10-22 9 views
16

यह this question पर अनुवर्ती प्रकार है।गिट: इस पेड़ में डुप्लिकेट ब्लब्स (फाइलें) पाएं

यदि एक ही सामग्री के साथ कई ब्लब्स हैं, तो वे केवल गिट भंडार में संग्रहीत होते हैं क्योंकि उनके SHA-1 समान होंगे। किसी दिए गए पेड़ के लिए सभी डुप्लिकेट फ़ाइलों को खोजने के बारे में कैसे जाना होगा?

क्या आपको पेड़ चलना होगा और डुप्लिकेट हैंश की तलाश करनी होगी, या क्या गिट प्रत्येक ब्लॉब से बैकलिंक प्रदान करता है जो उस पेड़ में सभी फाइलों को संदर्भित करता है?

उत्तर

9

जिस पर मैं काम करता हूं उस कोडबेस पर इसे चलाने वाला एक आंख खोलने वाला मैं आपको बता सकता हूं!

#!/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"; 
    } 
} 
+0

आप सही हैं ... परिणाम बहुत दिलचस्प हैं! – Readonly

+0

अपने पथों में रिक्त स्थान का समर्थन करने के लिए थोड़ा सुधार: "\ s + (\ S +) \ z" से "\ s + (। +) \ Z" से regex के अंत को बदलें। –

4

आपके लिंक किए गए प्रश्न से स्क्रिप्टिंग उत्तर बहुत अधिक यहां भी लागू होते हैं।

अपने गिट भंडार की जड़ से निम्न गिट कमांड आज़माएं।

git ls-tree -r HEAD 

यह सभी मौजूदा प्रमुख में 'धब्बे', उनके रास्ते और उनके SHA1 आईडी सहित एक पुनरावर्ती सूची बनाता है।

गिट एक ब्लॉब से पेड़ से लिंक को वापस नहीं रखता है, इसलिए यह git ls-tree -r आउटपुट को पार्स करने के लिए एक स्क्रिप्टिंग कार्य (पर्ल, पायथन?) होगा और सूची में एक से अधिक बार दिखाई देने वाले सभी sha1s की सारांश रिपोर्ट तैयार करेगा ।

7

बस एक एक लाइनर कि डुप्लिकेट Git ls-tree द्वारा प्रदान की गई पर प्रकाश डाला गया बनाया है।
उपयोगी हो सकता है

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"' 
+0

इसके लिए धन्यवाद! बेहद सुविधाजनक। –

21
[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" 
+1

लघु और मीठा, धन्यवाद। – sinelaw

0

अधिक सामान्य:

(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 
+0

यह सवाल का जवाब नहीं देता है, जिसमें यह गिट इतिहास में बिल्कुल खोज नहीं करता है। 'Find -type f' और' du' 'के बारे में भी जागरूक रहें; आपका वर्तमान संस्करण बहुत अक्षम है (फाइलों पर कई बार चला जाता है)। डाउनवॉटेड नहीं है क्योंकि यह उपयोगी हो सकता है। – remram

0

विंडोज़/PowerShell उपयोगकर्ताओं के लिए:

git ls-tree -r HEAD | group { $_ -replace '.{12}(.{40}).*', '$1' } | ? { $_.Count -gt 1 } | select -expand Group 

यह आउटपुट कुछ की तरह:

100644 blob 8a49bcbae578c405ba2596c06f46fabbbc331c64 filename1 
100644 blob 8a49bcbae578c405ba2596c06f46fabbbc331c64 filename2 
100644 blob c1720b20bb3ad5761c1afb6a3113fbc2ba94994e filename3 
100644 blob c1720b20bb3ad5761c1afb6a3113fbc2ba94994e filename4