Git दोष कमिट सांख्यिकी


198

मैं "दुरुपयोग" (या कुछ बेहतर अनुकूल कार्य, और / या शेल कमांड के साथ संयोजन में) कैसे कर सकता हूं कि मुझे प्रत्येक कॉमिटर से उत्पन्न रिपॉजिटरी में कितनी पंक्तियाँ (कोड की) हैं?

उदाहरण आउटपुट:

Committer 1: 8046 Lines
Committer 2: 4378 Lines

11
वास्तव में इसके लिए एक अंतर्निहित कमांड होनी चाहिए ... बहुत कम सामान्य उपयोग के मामलों के लिए कमांड हैं।
सिरो सेंटिल्ली 郝海东 冠状 iro i 法轮功 '

@CiroSantilli लेकिन यह एक गोले जोड़ने के लिए आसान है जो गिट से अदृश्य है।
एलेक्स

Git रिपॉजिटरी में किसी विशिष्ट लेखक द्वारा बदली गई कुल पंक्तियों को कैसे गिनना संभव है? क्योंकि यह आसानी से उस एक तक कम किया जा सकता है: बस सभी लेखकों पर पाश
Ciro Santilli be reduced reduced reduced 六四 六四

1
यह काफी भयानक code.google.com/p/gitinspector है खासकर यदि आप छात्रों की टीमों द्वारा असाइनमेंट कर रहे हैं (बड़ी परियोजनाओं को लागू करने की आवश्यकता नहीं है ... यह धीमा है क्योंकि यह प्रत्येक व्यक्तिगत फ़ाइल को दोष देता है)
sehe

जवाबों:


166

अपडेट करें

git ls-tree -r -z --name-only HEAD -- */*.c | xargs -0 -n1 git blame \
--line-porcelain HEAD |grep  "^author "|sort|uniq -c|sort -nr

मैंने रास्ते में कुछ चीजें अपडेट कीं।

सुविधा के लिए, आप इसे अपने कमांड में भी डाल सकते हैं:

#!/bin/bash

# save as i.e.: git-authors and set the executable flag
git ls-tree -r -z --name-only HEAD -- $1 | xargs -0 -n1 git blame \
 --line-porcelain HEAD |grep  "^author "|sort|uniq -c|sort -nr

इसे अपने पथ में कहीं स्टोर करें या अपने पथ को संशोधित करें और इसका उपयोग करें

  • git authors '*/*.c' # look for all files recursively ending in .c
  • git authors '*/*.[ch]' # look for all files recursively ending in .c or .h
  • git authors 'Makefile' # just count lines of authors in the Makefile

मूल उत्तर

जबकि स्वीकृत जवाब यह काम बहुत धीमी गति से करता है।

$ git ls-tree --name-only -z -r HEAD|egrep -z -Z -E '\.(cc|h|cpp|hpp|c|txt)$' \
  |xargs -0 -n1 git blame --line-porcelain|grep "^author "|sort|uniq -c|sort -nr

लगभग तात्कालिक है।

वर्तमान में ट्रैक की गई फ़ाइलों की सूची प्राप्त करने के लिए आप उपयोग कर सकते हैं

git ls-tree --name-only -r HEAD

यह समाधान फिलाटाइप fileको निर्धारित करने के लिए कॉल करने से बचता है और प्रदर्शन कारणों से वांछित विस्तार से मिलान करने के लिए grep का उपयोग करता है। यदि सभी फ़ाइलों को शामिल किया जाना चाहिए, तो इसे लाइन से हटा दें।

grep -E '\.(cc|h|cpp|hpp|c)$' # for C/C++ files
grep -E '\.py$'               # for Python files

यदि फ़ाइलों में स्थान हो सकते हैं, जो आपके द्वारा उपयोग किए जाने वाले गोले के लिए खराब हैं:

git ls-tree -z --name-only -r HEAD | egrep -Z -z '\.py'|xargs -0 ... # passes newlines as '\0'

फाइलों की एक सूची दें (एक पाइप के माध्यम से) एक कमांड को कॉल करने और तर्कों को वितरित करने के लिए xargs का उपयोग कर सकते हैं। आदेश देता है कि एकाधिक फ़ाइलों को संसाधित करने की अनुमति दें -n1। इस स्थिति में हम कॉल करते हैं git blame --line-porcelainऔर प्रत्येक कॉल के लिए हम ठीक 1 तर्क का उपयोग करते हैं।

xargs -n1 git blame --line-porcelain

हम फिर "लेखक" की घटनाओं के लिए आउटपुट को फ़िल्टर करते हैं और सूची को क्रमबद्ध करते हैं और इसके द्वारा डुप्लिकेट लाइनों की गणना करते हैं:

grep "^author "|sort|uniq -c|sort -nr

ध्यान दें

अन्य उत्तर वास्तव में उन लाइनों को फ़िल्टर करते हैं जिनमें केवल व्हाट्सएप होते हैं।

grep -Pzo "author [^\n]*\n([^\n]*\n){10}[\w]*[^\w]"|grep "author "

ऊपर दिया गया कमांड कम से कम एक गैर-व्हाट्सएप चरित्र वाली लाइनों के लेखकों को प्रिंट करेगा। आप मैच का उपयोग भी कर सकते हैं, \w*[^\w#]जिसमें उन लाइनों को भी बाहर रखा जाएगा जहां पहला गैर-व्हाट्सएप चरित्र नहीं है #(कई स्क्रिप्टिंग भाषाओं में टिप्पणी)।


2
@nilbus: आप नहीं कर सकते। echo "a\nb\nc"|xargs -n1 cmdका विस्तार होगाcmd a; cmd b; cmd d
एलेक्स

2
- लाइन-पोर्सिलेन अब और काम नहीं करता है (git 1.7.5.4) इसके बजाय उपयोग करें
isoiphone

4
OSX उपयोगकर्ता, निम्नलिखित का प्रयास करें (अभी भी उनके नाम पर newlines के साथ फ़ाइलों पर काम नहीं करता है):git ls-tree --name-only -r HEAD | grep -E '\.(cc|h|m|hpp|c)$' | xargs -n1 git blame --line-porcelain | grep "^author "|sort|uniq -c|sort -nr
वेन

3
यदि आप वर्तमान पथ के नीचे सब कुछ चाहते हैं, तो किसी भी गहराई तक, "./" पथ फ़िल्टर के रूप में (जहाँ उत्तर डाल " / .c")।
बेन दिल्ट्स

2
हो सकता है कि बेहतर कोड स्वामित्व पाने के लिए "दोष डब्ल्यू" का उपयोग जब कोड केवल पुन: स्वरूपित किया गया था stackoverflow.com/questions/4112410/...
sleeplessnerd

124

मैंने git-fame नामक रत्न लिखा, जो उपयोगी हो सकता है।

स्थापना और उपयोग:

  1. $ gem install git_fame
  2. $ cd /path/to/gitdir
  3. $ git fame

आउटपुट:

Statistics based on master
Active files: 21
Active lines: 967
Total commits: 109

Note: Files matching MIME type image, binary has been ignored

+----------------+-----+---------+-------+---------------------+
| name           | loc | commits | files | distribution (%)    |
+----------------+-----+---------+-------+---------------------+
| Linus Oleander | 914 | 106     | 21    | 94.5 / 97.2 / 100.0 |
| f1yegor        | 47  | 2       | 7     |  4.9 /  1.8 / 33.3  |
| David Selassie | 6   | 1       | 2     |  0.6 /  0.9 /  9.5  |
+----------------+-----+---------+-------+---------------------+

5
+1 आखिरकार 1 काम करता है और ऐसा लगता है कि यह समझदार नंबर देता है, कमांड लाइन के बाकी लोग या तो OSX पर काम नहीं करते हैं, क्योंकि यह असंगतता के कारण OSX पर काम करता है या मेरे रेपो पर नन्हा नंबर देता है। यह OSX और रूबी 1.9.3 (काढ़ा) पर है
कार्तिक टी

9
मूर्ख मत बनो, @tcaswell यह कुछ उपयोगी इंगित करने के लिए स्पैम नहीं है, भले ही आपने ऐसा कुछ लिखने के लिए किया हो।
वेन

5
मेरे अपने प्रश्न का उत्तर: git fame --exclude = paths / to / files, paths / to / other / files
Maciej Swic

2
@ अदम: क्या आपको अभी भी इससे समस्या है? OS X 10.9.5 पर मेरे लिए बहुत अच्छा काम करता है।
सैम डटन

2
किसी भी रेपो के लिए यह मणि काम करने के लिए आवश्यक समय से कुछ बड़ा होता है, यह खगोलीय है
एरिक Aigner

48
git ls-tree -r HEAD|sed -re 's/^.{53}//'|while read filename; do file "$filename"; done|grep -E ': .*text'|sed -r -e 's/: .*//'|while read filename; do git blame -w "$filename"; done|sed -r -e 's/.*\((.*)[0-9]{4}-[0-9]{2}-[0-9]{2} .*/\1/' -e 's/ +$//'|sort|uniq -c

कदम से कदम स्पष्टीकरण:

संस्करण नियंत्रण के अंतर्गत सभी फाइलों को सूचीबद्ध करें

git ls-tree -r HEAD|sed -re 's/^.{53}//'

सूची को केवल पाठ फ़ाइलों के लिए नीचे दें

|while read filename; do file "$filename"; done|grep -E ': .*text'|sed -r -e 's/: .*//'

व्हाट्सएप परिवर्तन को नजरअंदाज करते हुए, सभी पाठ फ़ाइलों को दोष दें

|while read filename; do git blame -w "$filename"; done

लेखक के नाम बाहर खींचो

|sed -r -e 's/.*\((.*)[0-9]{4}-[0-9]{2}-[0-9]{2} .*/\1/' -e 's/ +$//'

लेखकों की सूची को क्रमबद्ध करें, और uniq को लगातार दोहराने वाली रेखाओं की संख्या गिनें

|sort|uniq -c

उदाहरण आउटपुट:

   1334 Maneater
   1924 Another guy
  37195 Brian Ruby
   1482 Anna Lambda

1
लगता है कि मेरे पास एक अलग sedसंस्करण है, मेरा -rझंडा नहीं समझता है और रेगेक्स के साथ समस्या है (असंतुलित परनों के बारे में शिकायत करता है, तब भी जब मैं अधिशेष निकालता हूं ()।
एरिक एगर

7
कोई बात नहीं, sudo brew install gnu-sedहल कर दिया। एक जादू की तरह काम करता है!
एरिक एगर

5
या port install gsedMacPorts उपयोगकर्ताओं के लिए।
गेविन ब्रॉक

मैंने sudo brew install gnu-sed(जो काम किया), लेकिन मुझे अभी भी ऐसी त्रुटियां मिली हैं, जो कि sed को पहचानती नहीं है -r। :(
एडम टटल

1
OSX पर macports के माध्यम से स्थापित करने के बाद मैंने इसे चलाने के लिए इस कमांड को काम करने के लिए चला दिया (gsed के साथ sed प्रतिस्थापित):git ls-tree -r HEAD|gsed -re 's/^.{53}//'|while read filename; do file "$filename"; done|grep -E ': .*text'|gsed -r -e 's/: .*//'|while read filename; do git blame -w "$filename"; done|gsed -r -e 's/.*\((.*)[0-9]{4}-[0-9]{2}-[0-9]{2} .*/\1/' -e 's/ +$//'|sort|uniq -c
nerdherd

38

git summarygit-extras पैकेज द्वारा प्रदान किया गया वही है जो आपको चाहिए। गिट-एक्स्ट्रा में प्रलेखन चेकआउट करें - गिट-सारांश :

git summary --line

इस तरह दिखने वाला आउटपुट देता है:

project  : TestProject
lines    : 13397
authors  :
8927 John Doe            66.6%
4447 Jane Smith          33.2%
  23 Not Committed Yet   0.2%

1
अच्छा लगा, लेकिन यह पथ फ़िल्टर या कम से कम उप-निर्देशिका तर्क का समर्थन नहीं करता है। अच्छा होगा।
स्पिंकस

1
अच्छा और साफ समाधान। @ एलेक्स का जवाब किसी कारण से बहुत छोटी लाइन गिना जाता है। यह सिर्फ बॉक्स से बाहर काम किया। कुछ सौ फाइलों में फैली ~ 200k लाइनों के लिए 30 सेकंड की तरह कुछ लिया।
fgblomqvist

6

एरिक का समाधान भयानक था, लेकिन मुझे डायक्ट्रीक्स के साथ कुछ समस्याएं थीं (बावजूद इसके मेरे LC_*पर्यावरण चर अस्थिरता से सही ढंग से सेट किए गए थे) और कोड की तर्ज पर लीक होने वाले शोर के कारण वास्तव में उनमें तारीखें थीं। मेरा सीड-फू खराब है, इसलिए मैं रूबी के साथ इस फ्रेंकस्टीन स्निपेट के साथ समाप्त हो गया, लेकिन यह मेरे लिए 200,000+ एलओसी पर निर्दोष रूप से काम करता है, और यह परिणामों को हल करता है:

git ls-tree -r HEAD | gsed -re 's/^.{53}//' | \
while read filename; do file "$filename"; done | \
grep -E ': .*text' | gsed -r -e 's/: .*//' | \
while read filename; do git blame "$filename"; done | \
ruby -ne 'puts $1.strip if $_ =~ /^\w{8} \((.*?)\s*\d{4}-\d{2}-\d{2}/' | \
sort | uniq -c | sort -rg

इसके gsedबजाय ध्यान दें sedक्योंकि यह बाइनरी होमब्रेव इंस्टॉल है, जिससे सिस्टम सेड बरकरार है।


4

git shortlog -sn

यह प्रति लेखक कमिट की सूची दिखाएगा।


17
यह प्रति लेखक कमिट की संख्या देता है, लाइनों की संख्या नहीं।
v64

एक परियोजना / निर्देशिका / फ़ाइल के मुख्य योगदानकर्ताओं का निर्धारण करने में बहुत मददगार
एर्स

4

यहाँ @Alex के उत्तर से प्राथमिक स्निपेट है जो वास्तव में दोष लाइनों को एकत्र करने का कार्य करता है। मैंने फ़ाइलों के एक सेट के बजाय एक फ़ाइल पर काम करने के लिए इसे काट दिया है ।

git blame --line-porcelain path/to/file.txt | grep  "^author " | sort | uniq -c | sort -nr

मैं इसे यहां पोस्ट करता हूं क्योंकि मैं अक्सर इस जवाब पर वापस आता हूं और पोस्ट को फिर से पढ़ता हूं और उन हिस्सों को निकालने के लिए उदाहरणों को फिर से पचाता हूं जिनके मूल्य मैं कर रहा हूं। न ही यह मेरे उपयोग के मामले के लिए पर्याप्त सामान्य है; इसका दायरा पूरे सी प्रोजेक्ट के लिए है।


मैं प्रति फ़ाइल आँकड़ों को सूचीबद्ध करना पसंद करता हूँ, जैसे कि मैं इसे xargs कम पढ़ने योग्य और उपयोग करने / याद रखने में कठिन होने के forबजाय bash पुनरावृत्ति के माध्यम से प्राप्त xargsकरता हूँ, लाभ / नुकसान xargs बनाम के लिए कहीं और चर्चा की जानी चाहिए।

यहाँ एक व्यावहारिक स्निपेट है जो प्रत्येक फ़ाइल के लिए अलग-अलग परिणाम दिखाएगा:

for file in $(git ls-files); do \
    echo $file; \
    git blame --line-porcelain $file \
        | grep  "^author " | sort | uniq -c | sort -nr; \
    echo; \
done

और मैंने परीक्षण किया, एक बैश शेल में इस स्ट्रेट को चलाना ctrl + c सुरक्षित है, अगर आपको इसे एक bash स्क्रिप्ट के अंदर रखना है तो आपको SIGINT और SIGTERM पर ट्रैप करने की आवश्यकता हो सकती है यदि आप चाहते हैं कि उपयोगकर्ता लूप के लिए टूटने में सक्षम हो।


1
git blame -w -M -C -C --line-porcelain path/to/file.txt | grep -I '^author ' | sort | uniq -ic | sort -nrमिले करने के लिए एक मामूली ट्वीक git blame यहाँ कि अधिक सही आँकड़े मैं खोज रहा था का चित्रण है। विशेष रूप से, -M और -C विकल्प (वे दो C के उद्देश्यों पर हैं)। -M फ़ाइल के भीतर चालों का पता लगाता है, और -C -C अन्य फ़ाइलों से कॉपी की गई रेखाओं का पता लगाता है। यहां देखें डॉक । पूर्णता के लिए, -w व्हॉट्सएप की उपेक्षा करता है।
जॉन ली


1

मेरे पास यह समाधान है जो सभी पाठ फ़ाइलों (बाइनरी फ़ाइलों, यहां तक ​​कि संस्करण वाले को छोड़कर) में दोषपूर्ण लाइनों को गिना जाता है:

IFS=$'\n'
for file in $(git ls-files); do
    git blame `git symbolic-ref --short HEAD` --line-porcelain "$file" | \
        grep  "^author " | \
        grep -v "Binary file (standard input) matches" | \
        grep -v "Not Committed Yet" | \
        cut -d " " -f 2-
    done | \
        sort | \
        uniq -c | \
        sort -nr

1

रेपो के स्रोत संरचना के किसी भी निर्देशिका में यह काम करता है, यदि आप एक निश्चित स्रोत मॉड्यूल का निरीक्षण करना चाहते हैं।

find . -name '*.c' | xargs -n1 git blame --line-porcelain | grep "^author "|sort|uniq -c|sort -nr

0

मैंने पॉवरशेल का शीर्ष उत्तर अपनाया :

(git ls-tree -rz --name-only HEAD).Split(0x00) | where {$_ -Match '.*\.py'} |%{git blame -w --line-porcelain HEAD $_} | Select-String -Pattern '^author ' | Group-Object | Select-Object -Property Count, Name | Sort-Object -Property Count -Descending

यह वैकल्पिक है कि क्या आप स्विच के git blameसाथ चलते हैं -w, मैंने इसे जोड़ा क्योंकि यह व्हाट्सएप परिवर्तनों को अनदेखा करता है।

मेरी मशीन पर प्रदर्शन पॉवरशेल (एक ही रेपो के लिए ~ ५० से ६५ के बीच) के पक्ष में था, हालांकि बैश समाधान के तहत चल रहा था WSL2 के


-1

मेरी अपनी स्क्रिप्ट बनाई जो @nilbus और @ एलेक्स का संयोजन है

#!/bin/sh

for f in $(git ls-tree -r  --name-only HEAD --);
do
    j=$(file "$f" | grep -E ': .*text'| sed -r -e 's/: .*//');
    if [ "$f" != "$j" ]; then
        continue;
    fi
    git blame -w --line-porcelain HEAD "$f" | grep  "^author " | sed 's/author //'`enter code here`
done | sort | uniq -c | sort -nr

मेरे लिए, आपकी बात enter code hereसमस्याओं का कारण बन रही थी .... क्या यह सही ढंग से काम करती है?
मेनिओस

-1

मैश पर चलने वाले एकल स्रोत फ़ाइल को लक्षित करने वाले बैश फ़ंक्शन।

function glac {
    # git_line_author_counts
    git blame -w "$1" |  sed -E "s/.*\((.*) +[0-9]{4}-[0-9]{2}.*/\1/g" | sort | uniq -c | sort -nr
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.