मैं "दुरुपयोग" (या कुछ बेहतर अनुकूल कार्य, और / या शेल कमांड के साथ संयोजन में) कैसे कर सकता हूं कि मुझे प्रत्येक कॉमिटर से उत्पन्न रिपॉजिटरी में कितनी पंक्तियाँ (कोड की) हैं?
उदाहरण आउटपुट:
Committer 1: 8046 Lines
Committer 2: 4378 Lines
मैं "दुरुपयोग" (या कुछ बेहतर अनुकूल कार्य, और / या शेल कमांड के साथ संयोजन में) कैसे कर सकता हूं कि मुझे प्रत्येक कॉमिटर से उत्पन्न रिपॉजिटरी में कितनी पंक्तियाँ (कोड की) हैं?
उदाहरण आउटपुट:
Committer 1: 8046 Lines
Committer 2: 4378 Lines
जवाबों:
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 .cgit authors '*/*.[ch]' # look for all files recursively ending in .c or .hgit 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#]जिसमें उन लाइनों को भी बाहर रखा जाएगा जहां पहला गैर-व्हाट्सएप चरित्र नहीं है #(कई स्क्रिप्टिंग भाषाओं में टिप्पणी)।
echo "a\nb\nc"|xargs -n1 cmdका विस्तार होगाcmd a; cmd b; cmd d
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
मैंने git-fame नामक रत्न लिखा, जो उपयोगी हो सकता है।
स्थापना और उपयोग:
$ gem install git_fame $ cd /path/to/gitdir$ 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 |
+----------------+-----+---------+-------+---------------------+
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
sedसंस्करण है, मेरा -rझंडा नहीं समझता है और रेगेक्स के साथ समस्या है (असंतुलित परनों के बारे में शिकायत करता है, तब भी जब मैं अधिशेष निकालता हूं ()।
sudo brew install gnu-sedहल कर दिया। एक जादू की तरह काम करता है!
port install gsedMacPorts उपयोगकर्ताओं के लिए।
sudo brew install gnu-sed(जो काम किया), लेकिन मुझे अभी भी ऐसी त्रुटियां मिली हैं, जो कि sed को पहचानती नहीं है -r। :(
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
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%
एरिक का समाधान भयानक था, लेकिन मुझे डायक्ट्रीक्स के साथ कुछ समस्याएं थीं (बावजूद इसके मेरे 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क्योंकि यह बाइनरी होमब्रेव इंस्टॉल है, जिससे सिस्टम सेड बरकरार है।
यहाँ @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 पर ट्रैप करने की आवश्यकता हो सकती है यदि आप चाहते हैं कि उपयोगकर्ता लूप के लिए टूटने में सक्षम हो।
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 व्हॉट्सएप की उपेक्षा करता है।
की जाँच करें gitstats से उपलब्ध कमान http://gitstats.sourceforge.net/
मेरे पास यह समाधान है जो सभी पाठ फ़ाइलों (बाइनरी फ़ाइलों, यहां तक कि संस्करण वाले को छोड़कर) में दोषपूर्ण लाइनों को गिना जाता है:
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
रेपो के स्रोत संरचना के किसी भी निर्देशिका में यह काम करता है, यदि आप एक निश्चित स्रोत मॉड्यूल का निरीक्षण करना चाहते हैं।
find . -name '*.c' | xargs -n1 git blame --line-porcelain | grep "^author "|sort|uniq -c|sort -nr
मैंने पॉवरशेल का शीर्ष उत्तर अपनाया :
(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 के
मेरी अपनी स्क्रिप्ट बनाई जो @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समस्याओं का कारण बन रही थी .... क्या यह सही ढंग से काम करती है?