Git रिपॉजिटरी में एक विशिष्ट लेखक द्वारा बदली गई कुल पंक्तियों को कैसे गिना जाए?


458

क्या कोई ऐसा आदेश है जो मैं आह्वान कर सकता हूं, जो एक विशिष्ट लेखक द्वारा गिट रिपॉजिटरी में परिवर्तित लाइनों की गणना करेगा? मुझे पता है कि कमिट की संख्या गिनने के तरीके होने चाहिए क्योंकि गितुब अपने इम्पैक्ट ग्राफ के लिए ऐसा करता है।


1
आप प्रसिद्ध उपकरण पर विचार कर सकते हैं जो लिनक्स कर्नेल विकास के लिए आंकड़े इकट्ठा करता है, उदाहरण के लिए, रिपॉजिटरी यहां है git://git.lwn.net/gitdm.git
--ंद्री

जवाबों:


310

निम्न कमांड का आउटपुट योग को स्क्रिप्ट में भेजने के लिए यथोचित रूप से आसान होना चाहिए:

git log --author="<authorname>" --oneline --shortstat

यह वर्तमान हेड पर सभी कमिट्स के लिए आँकड़े देता है। यदि आप अन्य शाखाओं में आँकड़े जोड़ना चाहते हैं, तो आपको उन्हें तर्क के रूप में आपूर्ति करनी होगी git log

एक स्क्रिप्ट को पास करने के लिए, यहां तक ​​कि "ऑनलाइन" प्रारूप को हटाकर एक खाली लॉग प्रारूप के साथ किया जा सकता है, और जैसा कि जैकब नारबस्की द्वारा टिप्पणी की गई है, --numstatएक और विकल्प है। यह प्रति-लाइन आँकड़ों के बजाय प्रति-फ़ाइल जनरेट करता है लेकिन पार्स करना और भी आसान है।

git log --author="<authorname>" --pretty=tformat: --numstat

2
मेरे स्वीकृत उत्तर को बदल दिया क्योंकि इससे मुझे अपेक्षित तरीके से आउटपुट मिलता है, और इसे प्राप्त करने की तलाश में अन्य आगंतुकों के लिए अधिक उपयोगी होगा।
गाव

14
आप --numstatइसके बजाय इस्तेमाल कर सकते हैं --shortstatयदि आप आँकड़ों को थोड़ा आसान जोड़ना चाहते हैं।
जैकब नार

8
वहां भी "--नो-मर्ज" जोड़ना चाहते हैं।
योयो

9
इस सवाल के लिए खेद है, लेकिन मुझे क्या संख्या बता रहे हैं? दो पंक्तियाँ हैं और मुझे नहीं पता कि वे मुझे क्या बता रहे हैं। लाइनों chenged और जोड़ा?
Informatic0re

2
@ Informatic0re git help logमुझे बताता है कि पहली लाइनें जोड़ी गई हैं, दूसरी लाइनें हटा दी गई हैं।
थॉमस

599

यह लेखक के बारे में कुछ आंकड़े देता है, आवश्यकतानुसार संशोधित करता है।

Gawk का उपयोग करना:

git log --author="_Your_Name_Here_" --pretty=tformat: --numstat \
| gawk '{ add += $1; subs += $2; loc += $1 - $2 } END { printf "added lines: %s removed lines: %s total lines: %s\n", add, subs, loc }' -

मैक OSX पर Awk का उपयोग करना:

git log --author="_Your_Name_Here_" --pretty=tformat: --numstat | awk '{ add += $1; subs += $2; loc += $1 - $2 } END { printf "added lines: %s, removed lines: %s, total lines: %s\n", add, subs, loc }' -

EDIT (2017)

गितुब पर एक नया पैकेज है जो स्लीक दिखता है और बैश पर निर्भरता (लिनक्स पर परीक्षण किया गया) के रूप में उपयोग करता है। यह स्क्रिप्ट के बजाय सीधे उपयोग के लिए अधिक उपयुक्त है।

यह गिट-क्विक-स्टैटिस्टिक्स (github लिंक) है

प्रतिलिपि git-quick-statsएक फ़ोल्डर में और पथ में फ़ोल्डर जोड़ें।

mkdir ~/source
cd ~/source
git clone git@github.com:arzzen/git-quick-stats.git
mkdir ~/bin
ln -s ~/source/git-quick-stats/git-quick-stats ~/bin/git-quick-stats
chmod +x ~/bin/git-quick-stats
export PATH=${PATH}:~/bin

उपयोग:

git-quick-stats

यहाँ छवि विवरण दर्ज करें


18
इस सुंदर लंबे लाइनर के लिए धन्यवाद! जाग का यह स्थान हर किसी के डेक (सटीक, तेज, कोई अतिरिक्त अजीब आउटपुट) को नहीं झाड़ता। आश्चर्य की बात नहीं है, यह देखते हुए कि इस तरह की चीज़ के लिए डिज़ाइन किया गया है ... बहुत बुरा आप पार्टी के लिए बहुत देर हो चुकी थी।
zxq9

4
@ zxq9: जब प्रश्न पूछा गया था तब मैं भी स्टैकओवरफ्लो में नहीं था और मैं यहाँ उत्तरों से प्रेरित था। चलो आशा करते हैं कि मैं धीरे-धीरे यहां से आगे निकल जाऊंगा क्योंकि लोग इसकी जरूरत महसूस करते रहेंगे।
एलेक्स

9
यह कमाल का काम करता है, लेकिन मुझे इसे OSX टर्मिनल में काम gawkकरने के लिए बदलना पड़ाawk
Zach Lysobey

1
@samthebest, क्योंकि चलती फ़ाइल एक उचित आंकड़े को प्रतिबिंबित नहीं कर रही है। लाइनें नहीं बदली हैं। एलेक्स के लिए: मैं Git के बारे में बात कर रहा हूँ। Btw, मूल प्रश्न के लिए मेरी टिप्पणी देखें।
--ंद्रिय

2
यदि url आपके लिए काम नहीं करता है, तो यह कोशिश करें:git clone https://github.com/arzzen/git-quick-stats.git
निकोलस

226

यदि कोई अपने कोडबस में प्रत्येक उपयोगकर्ता के आँकड़े देखना चाहता है , तो मेरे कुछ सहकर्मी हाल ही में इस भयानक वन-लाइनर के साथ आए:

git log --shortstat --pretty="%cE" | sed 's/\(.*\)@.*/\1/' | grep -v "^$" | awk 'BEGIN { line=""; } !/^ / { if (line=="" || !match(line, $0)) {line = $0 "," line }} /^ / { print line " # " $0; line=""}' | sort | sed -E 's/# //;s/ files? changed,//;s/([0-9]+) ([0-9]+ deletion)/\1 0 insertions\(+\), \2/;s/\(\+\)$/\(\+\), 0 deletions\(-\)/;s/insertions?\(\+\), //;s/ deletions?\(-\)//' | awk 'BEGIN {name=""; files=0; insertions=0; deletions=0;} {if ($1 != name && name != "") { print name ": " files " files changed, " insertions " insertions(+), " deletions " deletions(-), " insertions-deletions " net"; files=0; insertions=0; deletions=0; name=$1; } name=$1; files+=$2; insertions+=$3; deletions+=$4} END {print name ": " files " files changed, " insertions " insertions(+), " deletions " deletions(-), " insertions-deletions " net";}'

(हमारे रेपो के माध्यम से क्रंच करने के लिए कुछ मिनट लगते हैं, जो लगभग 10-15k है।)


12
वह तो कमाल है! michael,: 6057 files changed, 854902 insertions(+), 26973 deletions(-), 827929 net
माइकल जे। काल्किंस

1
@EugenKonkov कोड में इसे सम्मिलन - विलोपन के रूप में परिभाषित किया गया है।
दान

13
यह एकमात्र आदेश है जो एक रिपॉजिटरी के लिए कुल परिणाम देता है और बिना किसी प्लगइन के चलता है।
मर फारुक अल्मलि

1
मुझे एक साथ सूचीबद्ध उपयोगकर्ताओं का एक समूह मिल रहा है, डेवलपर्स के लगभग हर संभव संयोजन वापस आ रहे हैं। मेरे अंत पर अजीबता?
डेमन

2
@BenSewards आप लिनक्स पर विंडोज सबसिस्टम का उपयोग करके विंडोज पर बैश का उपयोग कर सकते हैं, यहां
mjsr

152

गिट फेम https://github.com/oleander/git-fame-rb

एक अच्छा उपकरण है, जिसमें सभी लेखकों के लिए एक ही बार में गणना की जा सकती है, जिसमें प्रतिबद्ध और संशोधित फाइलें शामिल हैं:

sudo apt-get install ruby-dev
sudo gem install git_fame
cd /path/to/gitdir && git fame

Https://github.com/casperdcl/git-fame पर पायथन संस्करण भी है (@fracz द्वारा उल्लिखित):

sudo apt-get install python-pip python-dev build-essential 
pip install --user git-fame
cd /path/to/gitdir && git fame

नमूना उत्पादन:

Total number of files: 2,053
Total number of lines: 63,132
Total number of commits: 4,330

+------------------------+--------+---------+-------+--------------------+
| name                   | loc    | commits | files | percent            |
+------------------------+--------+---------+-------+--------------------+
| Johan Sørensen         | 22,272 | 1,814   | 414   | 35.3 / 41.9 / 20.2 |
| Marius Mathiesen       | 10,387 | 502     | 229   | 16.5 / 11.6 / 11.2 |
| Jesper Josefsson       | 9,689  | 519     | 191   | 15.3 / 12.0 / 9.3  |
| Ole Martin Kristiansen | 6,632  | 24      | 60    | 10.5 / 0.6 / 2.9   |
| Linus Oleander         | 5,769  | 705     | 277   | 9.1 / 16.3 / 13.5  |
| Fabio Akita            | 2,122  | 24      | 60    | 3.4 / 0.6 / 2.9    |
| August Lilleaas        | 1,572  | 123     | 63    | 2.5 / 2.8 / 3.1    |
| David A. Cuadrado      | 731    | 111     | 35    | 1.2 / 2.6 / 1.7    |
| Jonas Ängeslevä        | 705    | 148     | 51    | 1.1 / 3.4 / 2.5    |
| Diego Algorta          | 650    | 6       | 5     | 1.0 / 0.1 / 0.2    |
| Arash Rouhani          | 629    | 95      | 31    | 1.0 / 2.2 / 1.5    |
| Sofia Larsson          | 595    | 70      | 77    | 0.9 / 1.6 / 3.8    |
| Tor Arne Vestbø        | 527    | 51      | 97    | 0.8 / 1.2 / 4.7    |
| spontus                | 339    | 18      | 42    | 0.5 / 0.4 / 2.0    |
| Pontus                 | 225    | 49      | 34    | 0.4 / 1.1 / 1.7    |
+------------------------+--------+---------+-------+--------------------+

लेकिन चेतावनी दी जाए: जैसा कि जेरेड ने टिप्पणी में बताया है, बहुत बड़े भंडार पर करने में घंटों लगेंगे। निश्चित नहीं है कि अगर इसमें सुधार किया जा सकता है, तो यह देखते हुए कि यह इतना Git डेटा संसाधित करना चाहिए।


1
यह भयानक है लेकिन इतना धीमा है
जेरेड बुरो

1
2015 की मैकबुक और मध्यम बड़े एंड्रॉइड प्रोजेक्ट (127k एलओसी ') पर अच्छी तरह से काम किया गया है। कुछ देर।
अधिकतम

2
@ वर्तमान उपयोगकर्ता के लिए inal loc / commits / files का प्रतिशत।
सिरो सेंटिल्ली 郝海东 i iro i 法轮功 '

1
एक शाखा बदलें, समय समाप्त करें, और एक फ़ोल्डर को बाहर करें:git fame --branch=dev --timeout=-1 --exclude=Pods/*
jonmecer

1
@AlexanderMills मैं यह अनुमान लगा रहा हूं क्योंकि आप सार्थक रूप से
ब्लब्स

103

मुझे यह देखने के लिए उपयोगी पाया गया कि कोड बेस में वर्तमान में सबसे अधिक लाइनें किसकी थीं:

git ls-files -z | xargs -0n1 git blame -w | ruby -n -e '$_ =~ /^.*\((.*?)\s[\d]{4}/; puts $1.strip' | sort -f | uniq -c | sort -n

अन्य उत्तरों में अधिकतर कमिट्स में बदली गई लाइनों पर ध्यान केंद्रित किया गया है, लेकिन यदि कमिट्स जीवित नहीं हैं और ओवरराइट किए गए हैं, तो वे केवल मंथन किए जा सकते हैं। उपरोक्त भस्मारती भी आपको एक बार में केवल एक के बजाय लाइनों द्वारा हल किए गए सभी कमिटर्स को मिलती है। आप कुछ बेहतर नंबरों को प्राप्त करने के लिए git blame (-C -M) में कुछ विकल्प जोड़ सकते हैं जो फाइलों के बीच फाइल मूवमेंट और लाइन मूवमेंट को ध्यान में रखते हैं, लेकिन यदि आप करते हैं तो कमांड बहुत लंबे समय तक चल सकती है।

इसके अलावा, यदि आप सभी कमिटर्स के लिए सभी कमिट में बदली गई लाइनों की तलाश कर रहे हैं, तो लिपि का अनुसरण करना मददगार है:

http://git-wt-commit.rubyforge.org/#git-rank-contributors


31
मैं एक +1 देने वाला था, लेकिन तब मुझे महसूस हुआ कि समाधान माणिक्य पर निर्भर करता है ... :(
mac

3
आप इसे बहुत आसानी से रूबी का उपयोग नहीं करने के लिए संशोधित कर सकते हैं क्योंकि मैं सिर्फ स्ट्रिंग प्रतिस्थापन के लिए रूबी का उपयोग करता हूं। आप perl, sed, python, आदि का उपयोग कर सकते हैं
mmrobins

21
मेरे लिए काम नहीं करता है: -e: 1: `<मुख्य> 'में: UTF-8 (तर्क-वितर्क) में अमान्य बाइट अनुक्रम
1948 में मिशाल डोबस्की

1
/^.*\((.*?)\s[\d]{4}//^.*?\((.*?)\s[\d]{4}/एक लेखक के रूप में स्रोत में मेल खाते हुए कोष्ठकों को रोकने के लिए होना चाहिए ।
टिमोथी गु

1
mmm मेरे निष्पादन में बहुत सारे उपयोगकर्ता हैं जो खराब पार्सिंग के कारण भी मौजूद नहीं हैं। मुझे लगता है कि यह एक विश्वसनीय जवाब नहीं है।
mjsr

92

किसी दिए गए शाखा पर किसी दिए गए लेखक (या सभी लेखकों) द्वारा कमिट की संख्या की गणना करने के लिए आप गिट-शॉर्टलॉग का उपयोग कर सकते हैं ; विशेष रूप से इसके विकल्प --numberedऔर --summaryविकल्प देखें, जैसे git रिपॉजिटरी पर चलने पर:

$ git shortlog v1.6.4 --numbered --summary
  6904  Junio C Hamano
  1320  Shawn O. Pearce
  1065  Linus Torvalds
    692  Johannes Schindelin
    443  Eric Wong

2
ध्यान दें कि v1.6.4आउटपुट निर्धारक बनाने के लिए इस उदाहरण में यहां है: यह वही कोई बात नहीं होगी जब आपने क्लोन और / या गिट रिपॉजिटरी से प्राप्त किया था।
जकूब नारबस्की

सहित v1.6.4मुझे देता है:fatal: ambiguous argument 'v1.6.4': unknown revision or path not in the working tree.
व्लाद द इम्पेला

5
आह, नहीं, मुझे याद आया "जब गिट रिपॉजिटरी पर चलाया जाता है"। निष्पक्ष होना करने के लिए, ज्यादातर लोगों को नहीं होते Git रेपो पर इस आदेश को चलाते हैं। एक बहुत बड़े अंतर से, वास्तव में।
व्लाद इम्पाला

4
git shortlog -sneया, यदि आप मर्ज को शामिल नहीं करेंगेgit shortlog -sne --no-merges
मार्क स्वार्डस्ट्रॉम

1
@Swards: -sहै --summary, -nहै --numbered, और [नई] -eहै --emailलेखकों के ईमेल को दिखाने के लिए (और अलग से भिन्न ईमेल पते के साथ एक ही लेखक गिनती ध्यान में रखते हुए .mailmapसुधार)। के बारे में अच्छा फोन --no-merges
जकुब नारबस्की

75

को देखने के बाद एलेक्स के और Gerty3000 के जवाब है, मैं एक लाइनर को छोटा करने की कोशिश की है:

असल में, git log numstat का उपयोग करना और फाइलों की संख्या पर नज़र रखना बदले गए ।

मैक OSX पर गेट संस्करण 2.1.0:

git log --format='%aN' | sort -u | while read name; do echo -en "$name\t"; git log --author="$name" --pretty=tformat: --numstat | awk '{ add += $1; subs += $2; loc += $1 - $2 } END { printf "added lines: %s, removed lines: %s, total lines: %s\n", add, subs, loc }' -; done

उदाहरण:

Jared Burrows   added lines: 6826, removed lines: 2825, total lines: 4001

खिचड़ी भाषा इसका एक उपनाम है :-(
ब्राट

33

उत्तर से AaronM खोल एक लाइनर का उपयोग कर अच्छा है, लेकिन वास्तव में, वहाँ अभी तक एक और बग है, जहां रिक्त स्थान होगा भ्रष्ट उपयोगकर्ता नाम अगर कोई उपयोगकर्ता नाम और तारीख के बीच सफेद रिक्त स्थान से अलग-अलग हैं। दूषित उपयोगकर्ता नाम उपयोगकर्ता गणना के लिए कई पंक्तियाँ देगा और आपको उन्हें स्वयं योग करना होगा।

इस छोटे से परिवर्तन ने मेरे लिए समस्या तय कर दी:

git ls-files -z | xargs -0n1 git blame -w --show-email | perl -n -e '/^.*?\((.*?)\s+[\d]{4}/; print $1,"\n"' | sort -f | uniq -c | sort -n

सूचना + के बाद \ _ जो कि नाम से तारीख तक सभी व्हाट्सएप का उपभोग करेगा।

वास्तव में इस उत्तर को अपने स्वयं के स्मरण के लिए उतना ही जोड़ना जितना किसी और की मदद करने के लिए, क्योंकि यह कम से कम दूसरी बार मैं विषय को गूगल करता हूं :)

  • संपादित करें 2019-01-23 को ईमेल पर एग्रीगेट --show-emailकरने के git blame -wलिए जोड़ा गया , क्योंकि कुछ लोग Nameविभिन्न कंप्यूटरों पर विभिन्न स्वरूपों का उपयोग करते हैं, और कभी-कभी एक ही नाम वाले दो लोग एक ही काम कर रहे होते हैं।

पर्ल का उपयोग करने वाला यह उत्तर माणिक आधारित लोगों की तुलना में थोड़ा बेहतर दिखाई दिया। रूबी ने लाइनों पर चिपकाया था जो वास्तविक यूटीएफ -8 पाठ नहीं थे, पर्ल ने शिकायत नहीं की। लेकिन क्या पर्ल ने सही काम किया? मुझे नहीं पता।
स्टीफन गौरीचॉन

सबमॉड्यूल्स में परिणाम होता है, unsupported file typeलेकिन अन्यथा यह उनके साथ भी ठीक काम करने लगता है (यह उन्हें छोड़ देता है)।
व्लादिमीर 18unát

24

यहाँ एक छोटा-सा लाइनर है जो सभी लेखकों के लिए आँकड़े तैयार करता है। यह https://stackoverflow.com/a/20414465/1102119 पर डैन के समाधान की तुलना में बहुत तेज़ है (मेरा समय O (NM) के बजाय O (NM) है जहाँ N कमिट की संख्या है, और M की संख्या लेखकों की संख्या है )।

git log --no-merges --pretty=format:%an --numstat | awk '/./ && !author { author = $0; next } author { ins[author] += $1; del[author] += $2 } /^$/ { author = ""; next } END { for (a in ins) { printf "%10d %10d %10d %s\n", ins[a] - del[a], ins[a], del[a], a } }' | sort -rn

4
अच्छा है लेकिन आउटपुट का क्या मतलब है?
गैरी

आपको जोड़ना चाहिए --no-show-signature, अन्यथा पीजीपी पर हस्ताक्षर करने वाले लोग गिने जाने वाले नहीं हैं।
फिलाहॉप बुस्बी

2
ins [a] - del [a], ins [a], del [a], इसलिए यदि मैं सही सम्मिलन-विलोपन, सम्मिलन, विलोपन, नाम
०५:०१ पर MrKekson

मैं इस कमांड को अपने git config में कैसे जोड़ सकता हूं ताकि मैं इसे "git count-lines" कह सकूं?
टेकानुवा १५

कोई बात नहीं, मैं समझ गया count-lines = "!f() { git log --no-merges --pretty=format:%an --numstat | awk '/./ && !author { author = $0; next } author { ins[author] += $1; del[author] += $2 } /^$/ { author = \"\"; next } END { for (a in ins) { printf \"%10d %10d %10d %s\\n\", ins[a] - del[a], ins[a], del[a], a } }' | sort -rn; }; f":। (नोट मैं विंडोज़ पर हूँ; आपको विभिन्न प्रकार के उद्धरणों का उपयोग करने की आवश्यकता हो सकती है)
takanuva15

21

@mmrobins @AaronM @ErikZ @JamesMishra ने वैरिएंट उपलब्ध करवाए जो सभी में एक समस्या है: वे स्क्रिप्ट के उपभोग के लिए जानकारी के मिश्रण का उत्पादन करने के लिए गिट से पूछते हैं, एक ही लाइन पर रिपॉजिटरी से लाइन सामग्री सहित, फिर एक rexxp के साथ गड़बड़ का मिलान करें ।

यह एक समस्या है जब कुछ पंक्तियाँ UTF-8 पाठ मान्य नहीं होती हैं, और जब कुछ पंक्तियाँ regexp से मेल खाती हैं (तो यह यहाँ है)।

यहां एक संशोधित रेखा है जिसमें ये समस्याएं नहीं हैं। यह डेटा को अलग-अलग लाइनों पर सफाई से आउटपुट करने का अनुरोध करता है, जो कि हम जो चाहते हैं उसे फ़िल्टर करना आसान बनाता है:

git ls-files -z | xargs -0n1 git blame -w --line-porcelain | grep -a "^author " | sort -f | uniq -c | sort -n

आप अन्य स्ट्रिंग्स के लिए grep कर सकते हैं, जैसे लेखक-मेल, कमिटर आदि।

बाइट-लेवल प्रोसेसिंग को बाध्य करने के लिए शायद पहले export LC_ALL=C(मान लें bash) (यह UTF-8-आधारित स्थानों से जबरदस्त रूप से गति बढ़ाने के लिए भी होता है)।


वहां बहुत अच्छी लाइन, बहुत अच्छी, कि आप इसे आसानी से मिला सकते हैं, हालांकि यह करने में विफल रहता है कि मूल पोस्टर ने क्या अनुरोध किया है, लेखक द्वारा एक गिनती प्रदान करें। सुनिश्चित करें कि आप इसे चला सकते हैं और wc-l, आदि कर सकते हैं, लेकिन फिर आपको रिपॉजिटरी में प्रत्येक लेखक के लिए दोहराना होगा।
एरोनम

1
@AaronM मुझे आपकी आलोचना समझ में नहीं आती है। यह लाइन AFAIK आपके समान ही आंकड़े का उत्पादन करती है, केवल अधिक मजबूत। इसलिए, यदि मेरा उत्तर "मूल पोस्टर से अनुरोध करने के लिए क्या करने में विफल रहता है, लेखक द्वारा एक गिनती प्रदान करें", तो आपका और भी। कृपया मुझे ज्ञान दो।
स्टीफन गौरिचोन

खेद है कि मैंने गलत समझा, मुझे लगा कि प्रत्येक अलग-अलग लेखकों के नाम के लिए कमांड को संशोधित करना होगा। अन्य तार के लिए grep के बारे में आपकी टिप्पणी ने मुझे वहां पहुंचा दिया लेकिन यह मेरी गलतफहमी थी।
एरोनम

यह तो कमाल है। धन्यवाद!
टेक

16

बीच में रूबी के साथ एक समाधान दिया गया था, पर्ल डिफ़ॉल्ट रूप से थोड़ा अधिक उपलब्ध है यहां लेखक द्वारा वर्तमान लाइनों के लिए पर्ल का उपयोग कर एक विकल्प है।

git ls-files -z | xargs -0n1 git blame -w | perl -n -e '/^.*\((.*?)\s*[\d]{4}/; print $1,"\n"' | sort -f | uniq -c | sort -n

5
अद्यतित रेगेक्स कोई सार्थक अंतर नहीं करता है, और यह टूट गया है क्योंकि आप पहले पराग से बच नहीं पाए थे। हालाँकि, मैं कुछ मामलों को देख सकता हूँ जहाँ मेरे पिछले कोड को कुंडी लगाने के लिए कोड की लाइन में कुछ बिट्स मिल सकते हैं। यह अधिक मज़बूती से काम करेगा: git ls-files -z | xargs -0n1 git दोष -w | पर्ल -n -e '/^.*?\((.*?)\s[\d]{4}/; $ 1, "\ n" प्रिंट' | तरह -f | uniq -c | तरह -n
आरोनम

एक और अधिक विश्वसनीय regexp बनाने की कोशिश करने के लिए धन्यवाद। एक अधिक मजबूत संस्करण stackoverflow.com/a/36090245/1429390 के
स्टीफन गौरीचॉन

13

चार्ल्स बेली के जवाब के अलावा , आप -Cकमांड में पैरामीटर जोड़ना चाह सकते हैं । अन्यथा फ़ाइल का नाम बहुत सारे परिवर्धन और निष्कासन के रूप में गिना जाता है (क्योंकि फ़ाइल में कई लाइनें हैं), भले ही फ़ाइल सामग्री को संशोधित नहीं किया गया हो।

इसे समझने के लिए, यहाँ है एक प्रतिबद्ध फ़ाइलों के बहुत सारे अपनी परियोजनाओं, का उपयोग करते समय से एक से चारों ओर ले जाया जा रहा है के साथ git log --oneline --shortstatआदेश:

9052459 Reorganized project structure
 43 files changed, 1049 insertions(+), 1000 deletions(-)

और यहां git log --oneline --shortstat -Cकमांड का उपयोग करते हुए एक ही प्रतिबद्ध है जो फाइल कॉपी और नाम का पता लगाता है:

9052459 Reorganized project structure
 27 files changed, 134 insertions(+), 85 deletions(-)

मेरी राय में उत्तरार्द्ध इस बात का अधिक यथार्थवादी दृष्टिकोण देता है कि किसी व्यक्ति ने परियोजना पर कितना प्रभाव डाला है, क्योंकि एक फ़ाइल का नामकरण खरोंच से फ़ाइल लिखने की तुलना में बहुत छोटा ऑपरेशन है।


2
जब मैं "git log --online --shortstat" निष्पादित करता हूं, तो मुझे आपका परिणाम प्राप्त नहीं होता है। मेरे पास संस्करणों की संख्या के साथ प्रतिबद्ध होने की सूची है, लेकिन कुल संख्या नहीं। मैं सभी गिट रिपॉजिटरी में संपादित लाइनों की कुल संख्या कैसे प्राप्त कर सकता हूं?
मेहंदी

12

आप व्होडिड ( https://www.npmjs.com/package/whodid ) का उपयोग कर सकते हैं

$ npm install whodid -g
$ cd your-project-dir

तथा

$ whodid author --include-merge=false --path=./ --valid-threshold=1000 --since=1.week

या सिर्फ टाइप करें

$ whodid

तो आप इस तरह से परिणाम देख सकते हैं

Contribution state
=====================================================
 score  | author
-----------------------------------------------------
 3059   | someguy <someguy@tensorflow.org>
 585    | somelady <somelady@tensorflow.org>
 212    | niceguy <nice@google.com>
 173    | coolguy <coolgay@google.com>
=====================================================

'स्कोर' का क्या अर्थ है?
14:11 पर user11171

@Volte npm i, npm install के लिए सिर्फ एक शॉर्टकट है
Michiel

हां, मैं जागरूक हूं। मुझे -gपैकेज के नाम से पहले आना था macOS। बस मदद करने की कोशिश कर रहा है।
वोल्टे

11

यहां एक त्वरित रूबी स्क्रिप्ट है जो किसी दिए गए लॉग क्वेरी के खिलाफ प्रति उपयोगकर्ता प्रभाव को बढ़ाती है।

उदाहरण के लिए, रूबिनियस के लिए :

Brian Ford: 4410668
Evan Phoenix: 1906343
Ryan Davis: 855674
Shane Becker: 242904
Alexander Kellett: 167600
Eric Hodel: 132986
Dirkjan Bussink: 113756
...

लिपी:

#!/usr/bin/env ruby

impact = Hash.new(0)

IO.popen("git log --pretty=format:\"%an\" --shortstat #{ARGV.join(' ')}") do |f|
  prev_line = ''
  while line = f.gets
    changes = /(\d+) insertions.*(\d+) deletions/.match(line)

    if changes
      impact[prev_line] += changes[1].to_i + changes[2].to_i
    end

    prev_line = line # Names are on a line of their own, just before the stats
  end
end

impact.sort_by { |a,i| -i }.each do |author, impact|
  puts "#{author.strip}: #{impact}"
end

2
यह स्क्रिप्ट बहुत बढ़िया है, लेकिन उन लेखकों को बाहर करती है, जिनके पास केवल एकल-पंक्ति है! ठीक करने के लिए, निम्नानुसार परिवर्तन करें: परिवर्तन = / (\ d +) सम्मिलन। * (\ d +) विलोपन / .match (लाइन)
लैरी ग्रिट्ज

9

यह सबसे अच्छा तरीका है और यह आपको सभी उपयोगकर्ता द्वारा कुल कमिट की स्पष्ट तस्वीर भी देता है

git shortlog -s -n

2
उपयोगी है, लेकिन यह कुल संख्या पंक्तियों की संख्या नहीं है
डाइनर

5

मैंने ऊपर एक छोटे से उत्तर का एक संशोधन प्रदान किया, लेकिन यह मेरी जरूरतों के लिए पर्याप्त नहीं था। मुझे अंतिम कोड में प्रतिबद्ध लाइनों और लाइनों को वर्गीकृत करने में सक्षम होने की आवश्यकता है। मैं भी फ़ाइल से एक ब्रेक डाउन चाहता था। यह कोड पुनरावृत्ति नहीं करता है, यह केवल एकल निर्देशिका के लिए परिणाम लौटाएगा, लेकिन यह एक अच्छी शुरुआत है अगर कोई आगे जाना चाहता था। एक फ़ाइल में कॉपी और पेस्ट करें और निष्पादन योग्य बनाएं या इसे पर्ल के साथ चलाएं।

#!/usr/bin/perl

use strict;
use warnings;
use Data::Dumper;

my $dir = shift;

die "Please provide a directory name to check\n"
    unless $dir;

chdir $dir
    or die "Failed to enter the specified directory '$dir': $!\n";

if ( ! open(GIT_LS,'-|','git ls-files') ) {
    die "Failed to process 'git ls-files': $!\n";
}
my %stats;
while (my $file = <GIT_LS>) {
    chomp $file;
    if ( ! open(GIT_LOG,'-|',"git log --numstat $file") ) {
        die "Failed to process 'git log --numstat $file': $!\n";
    }
    my $author;
    while (my $log_line = <GIT_LOG>) {
        if ( $log_line =~ m{^Author:\s*([^<]*?)\s*<([^>]*)>} ) {
            $author = lc($1);
        }
        elsif ( $log_line =~ m{^(\d+)\s+(\d+)\s+(.*)} ) {
            my $added = $1;
            my $removed = $2;
            my $file = $3;
            $stats{total}{by_author}{$author}{added}        += $added;
            $stats{total}{by_author}{$author}{removed}      += $removed;
            $stats{total}{by_author}{total}{added}          += $added;
            $stats{total}{by_author}{total}{removed}        += $removed;

            $stats{total}{by_file}{$file}{$author}{added}   += $added;
            $stats{total}{by_file}{$file}{$author}{removed} += $removed;
            $stats{total}{by_file}{$file}{total}{added}     += $added;
            $stats{total}{by_file}{$file}{total}{removed}   += $removed;
        }
    }
    close GIT_LOG;

    if ( ! open(GIT_BLAME,'-|',"git blame -w $file") ) {
        die "Failed to process 'git blame -w $file': $!\n";
    }
    while (my $log_line = <GIT_BLAME>) {
        if ( $log_line =~ m{\((.*?)\s+\d{4}} ) {
            my $author = $1;
            $stats{final}{by_author}{$author}     ++;
            $stats{final}{by_file}{$file}{$author}++;

            $stats{final}{by_author}{total}       ++;
            $stats{final}{by_file}{$file}{total}  ++;
            $stats{final}{by_file}{$file}{total}  ++;
        }
    }
    close GIT_BLAME;
}
close GIT_LS;

print "Total lines committed by author by file\n";
printf "%25s %25s %8s %8s %9s\n",'file','author','added','removed','pct add';
foreach my $file (sort keys %{$stats{total}{by_file}}) {
    printf "%25s %4.0f%%\n",$file
            ,100*$stats{total}{by_file}{$file}{total}{added}/$stats{total}{by_author}{total}{added};
    foreach my $author (sort keys %{$stats{total}{by_file}{$file}}) {
        next if $author eq 'total';
        if ( $stats{total}{by_file}{$file}{total}{added} ) {
            printf "%25s %25s %8d %8d %8.0f%%\n",'', $author,@{$stats{total}{by_file}{$file}{$author}}{qw{added removed}}
            ,100*$stats{total}{by_file}{$file}{$author}{added}/$stats{total}{by_file}{$file}{total}{added};
        } else {
            printf "%25s %25s %8d %8d\n",'', $author,@{$stats{total}{by_file}{$file}{$author}}{qw{added removed}} ;
        }
    }
}
print "\n";

print "Total lines in the final project by author by file\n";
printf "%25s %25s %8s %9s %9s\n",'file','author','final','percent', '% of all';
foreach my $file (sort keys %{$stats{final}{by_file}}) {
    printf "%25s %4.0f%%\n",$file
            ,100*$stats{final}{by_file}{$file}{total}/$stats{final}{by_author}{total};
    foreach my $author (sort keys %{$stats{final}{by_file}{$file}}) {
        next if $author eq 'total';
        printf "%25s %25s %8d %8.0f%% %8.0f%%\n",'', $author,$stats{final}{by_file}{$file}{$author}
            ,100*$stats{final}{by_file}{$file}{$author}/$stats{final}{by_file}{$file}{total}
            ,100*$stats{final}{by_file}{$file}{$author}/$stats{final}{by_author}{total}
        ;
    }
}
print "\n";


print "Total lines committed by author\n";
printf "%25s %8s %8s %9s\n",'author','added','removed','pct add';
foreach my $author (sort keys %{$stats{total}{by_author}}) {
    next if $author eq 'total';
    printf "%25s %8d %8d %8.0f%%\n",$author,@{$stats{total}{by_author}{$author}}{qw{added removed}}
        ,100*$stats{total}{by_author}{$author}{added}/$stats{total}{by_author}{total}{added};
};
print "\n";


print "Total lines in the final project by author\n";
printf "%25s %8s %9s\n",'author','final','percent';
foreach my $author (sort keys %{$stats{final}{by_author}}) {
    printf "%25s %8d %8.0f%%\n",$author,$stats{final}{by_author}{$author}
        ,100*$stats{final}{by_author}{$author}/$stats{final}{by_author}{total};
}

मुझे यह त्रुटि मिल रही है: x.pl लाइन 71 पर शून्य से अवैध विभाजन।
विवेक झा

लाइन 71 पर शून्य से अवैध विभाजन को संबोधित किया। सोचें कि अगर कोई संपादन नहीं होता है, लेकिन यह कुछ समय पहले मैंने इसे लिखा था।
एरोनम

2

विंडोज़ उपयोगकर्ताओं के लिए आप निम्नलिखित स्क्रिप्ट का उपयोग कर सकते हैं जो निर्दिष्ट लेखक के लिए जोड़े गए / हटाए गए लाइनों को गिनता है

@echo off

set added=0
set removed=0

for /f "tokens=1-3 delims= " %%A in ('git log --pretty^=tformat: --numstat --author^=%1') do call :Count %%A %%B %%C

@echo added=%added%
@echo removed=%removed%
goto :eof

:Count
  if NOT "%1" == "-" set /a added=%added% + %1
  if NOT "%2" == "-" set /a removed=%removed% + %2
goto :eof

https://gist.github.com/zVolodymyr/62e78a744d99d414d56646a5e8a1ff4f


2

यहां एक शानदार रेपो है जो आपके जीवन को आसान बनाता है

git-quick-stats

एक मैक पर स्थापित काढ़ा के साथ

brew install git-quick-stats

Daud

git-quick-stats

बस सूचीबद्ध और संख्या दर्ज करके इस सूची में से आप कौन सा विकल्प चुनना चाहते हैं।

 Generate:
    1) Contribution stats (by author)
    2) Contribution stats (by author) on a specific branch
    3) Git changelogs (last 10 days)
    4) Git changelogs by author
    5) My daily status
    6) Save git log output in JSON format

 List:
    7) Branch tree view (last 10)
    8) All branches (sorted by most recent commit)
    9) All contributors (sorted by name)
   10) Git commits per author
   11) Git commits per date
   12) Git commits per month
   13) Git commits per weekday
   14) Git commits per hour
   15) Git commits by author per hour

 Suggest:
   16) Code reviewers (based on git history)


1

यह स्क्रिप्ट यहां करेगी। इसे authorhip.sh में डालें, chmod + x इसे, और आप सभी सेट हैं।

#!/bin/sh
declare -A map
while read line; do
    if grep "^[a-zA-Z]" <<< "$line" > /dev/null; then
        current="$line"
        if [ -z "${map[$current]}" ]; then 
            map[$current]=0
        fi
    elif grep "^[0-9]" <<<"$line" >/dev/null; then
        for i in $(cut -f 1,2 <<< "$line"); do
            map[$current]=$((map[$current] + $i))
        done
    fi
done <<< "$(git log --numstat --pretty="%aN")"

for i in "${!map[@]}"; do
    echo -e "$i:${map[$i]}"
done | sort -nr -t ":" -k 2 | column -t -s ":"

1
नहीं, यह नहीं है, आप इसे कहीं और पोस्ट करते हैं, यह macs और linux पर त्रुटियों को उत्पन्न करता है, आप जानते हैं कि किस प्रकार के कंप्यूटर पर गिट बनाया गया था!
पिज़ाओला गोर्गोन्जोला

1

अपने लॉग इन का उपयोग करके फ़ाइल में सहेजें:

git log --author="<authorname>" --oneline --shortstat > logs.txt

पायथन प्रेमियों के लिए:

with open(r".\logs.txt", "r", encoding="utf8") as f:
    files = insertions = deletions = 0
    for line in f:
        if ' changed' in line:
            line = line.strip()
            spl = line.split(', ')
            if len(spl) > 0:
                files += int(spl[0].split(' ')[0])
            if len(spl) > 1:
                insertions += int(spl[1].split(' ')[0])
            if len(spl) > 2:
                deletions += int(spl[2].split(' ')[0])

    print(str(files).ljust(10) + ' files changed')
    print(str(insertions).ljust(10) + ' insertions')
    print(str(deletions).ljust(10) + ' deletions')

आपके आउटपुट निम्न होंगे:

225        files changed
6751       insertions
1379       deletions

0

आप गिट दोष चाहते हैं ।

कुछ - अच्छी तरह से, आँकड़े मुद्रित करने के लिए एक -show- आँकड़े विकल्प है।


मैंने कोशिश की blame, लेकिन यह वास्तव में आँकड़े मुझे नहीं लगा कि ओपी की आवश्यकता होगी?
सीबी बेली

धन्यवाद, इससे मुझे भी मदद मिली।
गाव

0

प्रश्न एक विशिष्ट लेखक पर जानकारी के लिए पूछा गया था , लेकिन कई जवाब ऐसे समाधान थे जो कोड की अपनी लाइनों के आधार पर लेखकों की क्रमबद्ध सूची लौटाते थे।

यह वही था जो मैं खोज रहा था, लेकिन मौजूदा समाधान बिल्कुल सही नहीं थे। उन लोगों के हित में, जो Google के माध्यम से यह प्रश्न खोज सकते हैं, मैंने उन पर कुछ सुधार किए हैं और उन्हें एक शेल स्क्रिप्ट में बनाया है, जिसे मैं नीचे प्रदर्शित करता हूं। एक एनोटेट एक (जिसे मैं बनाए रखना जारी रखूंगा ) मेरे जीथूब पर पाया जा सकता है

Perl या Ruby पर कोई निर्भरता नहीं हैं । इसके अलावा, व्हॉट्सएप, नाम, और लाइन आंदोलनों को लाइन चेंज काउंट में ध्यान में रखा जाता है। बस इसे एक फ़ाइल में डालें और पहले पैरामीटर के रूप में अपनी गिट रिपॉजिटरी पास करें।

#!/bin/bash
git --git-dir="$1/.git" log > /dev/null 2> /dev/null
if [ $? -eq 128 ]
then
    echo "Not a git repository!"
    exit 128
else
    echo -e "Lines  | Name\nChanged|"
    git --work-tree="$1" --git-dir="$1/.git" ls-files -z |\
    xargs -0n1 git --work-tree="$1" --git-dir="$1/.git" blame -C -M  -w |\
    cut -d'(' -f2 |\
    cut -d2 -f1 |\
    sed -e "s/ \{1,\}$//" |\
    sort |\
    uniq -c |\
    sort -nr
fi

0

अब तक मैंने पहचाना सबसे अच्छा उपकरण gitinspector है। यह प्रति उपयोगकर्ता प्रति सप्ताह आदि रिपोर्ट देता है, आप नीचे npm के साथ की तरह स्थापित कर सकते हैं

npm स्थापित -g gitinspector

अधिक विवरण प्राप्त करने के लिए लिंक

https://www.npmjs.com/package/gitinspector

https://github.com/ejwa/gitinspector/wiki/Documentation

https://github.com/ejwa/gitinspector

उदाहरण के आदेश हैं

gitinspector -lmrTw 
gitinspector --since=1-1-2017 etc

0

मैंने उस कार्य को पूरा करने के लिए यह पर्ल स्क्रिप्ट लिखी।

#!/usr/bin/env perl

use strict;
use warnings;

# save the args to pass to the git log command
my $ARGS = join(' ', @ARGV);

#get the repo slug
my $NAME = _get_repo_slug();

#get list of authors
my @authors = _get_authors();
my ($projectFiles, $projectInsertions, $projectDeletions) = (0,0,0);
#for each author
foreach my $author (@authors) {
  my $command = qq{git log $ARGS --author="$author" --oneline --shortstat --no-merges};
  my ($files, $insertions, $deletions) = (0,0,0);
  my @lines = `$command`;
  foreach my $line (@lines) {
    if ($line =~ m/^\s(\d+)\s\w+\s\w+,\s(\d+)\s\w+\([\+|\-]\),\s(\d+)\s\w+\([\+|\-]\)$|^\s(\d+)\s\w+\s\w+,\s(\d+)\s\w+\(([\+|\-])\)$/) {
      my $lineFiles = $1 ? $1 : $4;
      my $lineInsertions = (defined $6 && $6 eq '+') ? $5 : (defined $2) ? $2 : 0;
      my $lineDeletions = (defined $6 && $6 eq '-') ? $5 : (defined $3) ? $3 : 0;
      $files += $lineFiles;
      $insertions += $lineInsertions;
      $deletions += $lineDeletions;
      $projectFiles += $lineFiles;
      $projectInsertions += $lineInsertions;
      $projectDeletions += $lineDeletions;
    }
  }
  if ($files || $insertions || $deletions) {
    printf(
      "%s,%s,%s,+%s,-%s,%s\n",
      $NAME,
      $author,
      $files,
      $insertions,
      $deletions,
      $insertions - $deletions
    );
  }
}

printf(
  "%s,%s,%s,+%s,-%s,%s\n",
  $NAME,
  'PROJECT_TOTAL',
  $projectFiles,
  $projectInsertions,
  $projectDeletions,
  $projectInsertions - $projectDeletions
);

exit 0;

#get the remote.origin.url joins that last two pieces (project and repo folder)
#and removes any .git from the results. 
sub _get_repo_slug {
  my $get_remote_url = "git config --get remote.origin.url";
  my $remote_url = `$get_remote_url`;
  chomp $remote_url;

  my @parts = split('/', $remote_url);

  my $slug = join('-', @parts[-2..-1]);
  $slug =~ s/\.git//;

  return $slug;
}

sub _get_authors {
  my $git_authors = 'git shortlog -s | cut -c8-';
  my @authors = `$git_authors`;
  chomp @authors;

  return @authors;
}

मैंने इसे नाम दिया git-line-changes-by-authorऔर डाल दिया /usr/local/bin। क्योंकि यह मेरे पथ में सहेजा गया है, मैं git line-changes-by-author --before 2018-12-31 --after 2020-01-012019 वर्ष के लिए रिपोर्ट प्राप्त करने के लिए आदेश जारी कर सकता हूं । उदहारण के लिए। और अगर मैं नाम को याद कर लेता तो git उचित वर्तनी का सुझाव देता।

आप _get_repo_slugउप को केवल समायोजित करना चाहते हैं, remote.origin.urlक्योंकि मेरे रेपो के अंतिम भाग को भी शामिल किया गया है project/repoऔर आपका नहीं हो सकता है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.