2015-01-13 12 views
10

मैं एपीआई का उपयोग करके कई बड़े गीथब रिपोज के लिए काम करने की कोशिश कर रहा हूं, इसलिए मैं काम की पूरी सूची प्राप्त करने से बचाना चाहता हूं (इस तरह एक उदाहरण के रूप में: api.github.com/repos/jasonrudolph/keyboard/ काम करता है) और उन्हें गिनती है।रेपो के लिए प्रतिबद्धता प्राप्त करने के लिए गिटहब वी 3 एपीआई का उपयोग कैसे करें?

अगर मेरे पास पहली (प्रारंभिक) प्रतिबद्धता का हैश था, तो मैं use this technique to compare the first commit to the latest कर सकता था और यह खुशी से कुल_commits को रिपोर्ट करता है (इसलिए मुझे एक जोड़ना होगा)। दुर्भाग्य से, मैं नहीं देख सकता कि एपीआई का उपयोग करके पहली प्रतिबद्धता कैसे प्राप्त करें।

बेस रेपो यूआरएल मुझे create_at देता है (यह यूआरएल एक उदाहरण है: api.github.com/repos/jasonrudolph/keyboard), इसलिए मैं कमेटी को सीमित करने तक सीमित कर सकता हूं तिथि (यह यूआरएल एक उदाहरण है: api.github.com/repos/jasonrudolph/keyboard/commits?until=2013-03-30T16:01:43Z) और सबसे शुरुआती (हमेशा आखिरी सूचीबद्ध?) या शायद एक वाला एक खाली माता-पिता (निश्चित नहीं है कि फोर्क किए गए प्रोजेक्ट्स के प्रारंभिक माता-पिता क्या करते हैं)।

रेपो के लिए पहली प्रतिबद्ध हैश प्राप्त करने का कोई बेहतर तरीका?

अभी तक बेहतर है, यह पूरी बात एक साधारण आंकड़े के लिए दृढ़ दिखती है, और मुझे आश्चर्य है कि मुझे कुछ याद आ रहा है। रेपो प्रतिबद्धता प्राप्त करने के लिए एपीआई का उपयोग करने के लिए कोई बेहतर विचार?

संपादित करें: यह somewhat similar question कुछ फ़ाइलों ("और उनके भीतर विशिष्ट फ़ाइलों के लिए") द्वारा फ़िल्टर करने का प्रयास कर रहा है, इसलिए इसका एक अलग उत्तर है।

+0

[github api का संभावित डुप्लिकेट: भंडार के लिए काम करने की संख्या को कुशलतापूर्वक कैसे प्राप्त करें?] (Http://stackoverflow.com/questions/15919539/github-api-how-to- कुशलतापूर्वक- ढूँढें -ज-ऑफ-ऑफ-ऑफ-ए-रिपोजिटरी) –

+0

वास्तव में वही प्रश्न नहीं है। हालांकि धन्यवाद! – SteveCoffman

उत्तर

4

आप का उपयोग कर कई रिपॉजिटरीज़ के लिए प्रतिबद्ध गणना करने के लिए GraphQL API v4 का उपयोग करने पर विचार कर सकते हैं। निम्नलिखित लाने 3 अलग खजाने की सभी शाखाओं के लिए निर्धारित संख्या जाएगा (रेपो प्रति 100 शाखाओं तक):

{ 
    gson: repository(owner: "google", name: "gson") { 
    ...RepoFragment 
    } 
    martian: repository(owner: "google", name: "martian") { 
    ...RepoFragment 
    } 
    keyboard: repository(owner: "jasonrudolph", name: "keyboard") { 
    ...RepoFragment 
    } 
} 

fragment RepoFragment on Repository { 
    name 
    refs(first: 100, refPrefix: "refs/heads/") { 
    edges { 
     node { 
     name 
     target { 
      ... on Commit { 
      id 
      history(first: 0) { 
       totalCount 
      } 
      } 
     } 
     } 
    } 
    } 
} 

Try it in the explorer

RepoFragment एक fragment जो उन में से प्रत्येक के लिए डुप्लिकेट क्वेरी क्षेत्रों बचने में मदद करता है रेपो

आप केवल डिफ़ॉल्ट शाखा पर निर्धारित संख्या की जरूरत है, यह और अधिक सरल है:

{ 
    gson: repository(owner: "google", name: "gson") { 
    ...RepoFragment 
    } 
    martian: repository(owner: "google", name: "martian") { 
    ...RepoFragment 
    } 
    keyboard: repository(owner: "jasonrudolph", name: "keyboard") { 
    ...RepoFragment 
    } 
} 

fragment RepoFragment on Repository { 
    name 
    defaultBranchRef { 
    name 
    target { 
     ... on Commit { 
     id 
     history(first: 0) { 
      totalCount 
     } 
     } 
    } 
    } 
} 

Try it in the explorer

4

यदि आप डिफ़ॉल्ट शाखा में काम करने की कुल संख्या की तलाश में हैं, तो आप एक अलग दृष्टिकोण पर विचार कर सकते हैं।

सभी योगदानकर्ताओं की एक सूची लाने के लिए रेपो योगदानकर्ता एपीआई का उपयोग करें:

https://developer.github.com/v3/repos/#list-contributors

सूची का प्रत्येक आइटम एक contributions क्षेत्र है जो आपको बताता है कि कितने उपयोगकर्ता डिफ़ॉल्ट शाखा में लेखक करता है शामिल होंगे। उन सभी क्षेत्रों में उन योगदानकर्ताओं को समझाएं और आपको डिफ़ॉल्ट शाखा में कुल संख्या में काम करना चाहिए।

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

+0

धन्यवाद। जब मैंने [इस तरह का एक लिंक] इस्तेमाल किया [https://api.github.com/repos/jquery/jquery/contributors?anon=true) यह 30 आइटम तक सीमित प्रतीत होता है। मैंने पाया कि कई आइटम लौटने वाले अनुरोध डिफ़ॉल्ट रूप से 30 आइटम पर अंकनित किए जाएंगे। आप 'पेज' पैरामीटर के साथ और पेज निर्दिष्ट कर सकते हैं। तो यदि आपको 30 मिलते हैं, तो आपको यह जांचने की ज़रूरत है कि क्या अधिक पृष्ठ हैं, और उन्हें प्रारंभिक परिणामों में जोड़ें। – SteveCoffman

+0

@SteveCoffman हाँ, यह अपेक्षित व्यवहार है: https://developer.github.com/v3/#pagination –

+0

ऐसा लगता है कि दोनों दृष्टिकोणों में से एक (आपका और मेरा) व्यवहार्य है, और न ही सुरुचिपूर्ण है। मैं तुम्हारा जवाब उत्तर के रूप में स्वीकार करने जा रहा हूं जब तक कि कोई और कुछ न आए जो हमने दोनों को अनदेखा कर दिया है। धन्यवाद। – SteveCoffman

3

मैंने अभी ऐसा करने के लिए एक छोटी सी लिपि बनाई है। यह बड़े भंडारों के साथ काम नहीं कर सकता है क्योंकि यह गिटहब की दर सीमा को संभाल नहीं करता है। इसके अलावा इसे पायथन requests पैकेज की आवश्यकता है।

#!/bin/env python3.4 
import requests 

GITHUB_API_BRANCHES = 'https://%(token)[email protected]/repos/%(namespace)s/%(repository)s/branches' 
GUTHUB_API_COMMITS = 'https://%(token)[email protected]/repos/%(namespace)s/%(repository)s/commits?sha=%(sha)s&page=%(page)i' 


def github_commit_counter(namespace, repository, access_token=''): 
    commit_store = list() 

    branches = requests.get(GITHUB_API_BRANCHES % { 
     'token': access_token, 
     'namespace': namespace, 
     'repository': repository, 
    }).json() 

    print('Branch'.ljust(47), 'Commits') 
    print('-' * 55) 

    for branch in branches: 
     page = 1 
     branch_commits = 0 

     while True: 
      commits = requests.get(GUTHUB_API_COMMITS % { 
       'token': access_token, 
       'namespace': namespace, 
       'repository': repository, 
       'sha': branch['name'], 
       'page': page 
      }).json() 

      page_commits = len(commits) 

      for commit in commits: 
       commit_store.append(commit['sha']) 

      branch_commits += page_commits 

      if page_commits == 0: 
       break 

      page += 1 

     print(branch['name'].ljust(45), str(branch_commits).rjust(9)) 

    commit_store = set(commit_store) 
    print('-' * 55) 
    print('Total'.ljust(42), str(len(commit_store)).rjust(12)) 

# for private repositories, get your own token from 
# https://github.com/settings/tokens 
# github_commit_counter('github', 'gitignore', access_token='fnkr:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx') 
github_commit_counter('github', 'gitignore') 
+0

कुछ बदल गया है और अब कोड github_commit_counter: commit_store.append में प्रतिबद्धता 'लाइन 36 दिखा रहा है: प्रतिबद्ध [' sha ']) ' – Whitecat

+0

मैं गलत था। लिपि काम करता है। मैंने बस अपनी दर_लिमिट को मारा। – Whitecat

0

सरल समाधान: पृष्ठ संख्या देखें। आपके लिए गिथब पेजिनेट्स। ताकि आप लिंक हेडर से अंतिम पृष्ठ संख्या प्राप्त करके आसानी से काम की संख्या की गणना कर सकें, एक को घटाकर (आपको मैन्युअल रूप से अंतिम पृष्ठ जोड़ना होगा), पृष्ठ के आकार से गुणा करना, परिणामों के अंतिम पृष्ठ को पकड़ना और उस सरणी का आकार प्राप्त करना और दो संख्याओं को एक साथ जोड़ना। यह अधिकतम दो एपीआई कॉल है!

यहाँ एक पूरे संगठन के लिए प्रतिबद्ध की कुल संख्या हथियाने माणिक में octokit मणि का उपयोग कर के अपने कार्यान्वयन है:

@github = Octokit::Client.new access_token: key, auto_traversal: true, per_page: 100 

Octokit.auto_paginate = true 
repos = @github.org_repos('my_company', per_page: 100) 

# * take the pagination number 
# * get the last page 
# * see how many items are on it 
# * multiply the number of pages - 1 by the page size 
# * and add the two together. Boom. Commit count in 2 api calls 
def calc_total_commits(repos) 
    total_sum_commits = 0 

    repos.each do |e| 
     repo = Octokit::Repository.from_url(e.url) 
     number_of_commits_in_first_page = @github.commits(repo).size 
     repo_sum = 0 
     if number_of_commits_in_first_page >= 100 
      links = @github.last_response.rels 

      unless links.empty? 
       last_page_url = links[:last].href 

       /.*page=(?<page_num>\d+)/ =~ last_page_url 
       repo_sum += (page_num.to_i - 1) * 100 # we add the last page manually 
       repo_sum += links[:last].get.data.size 
      end 
     else 
      repo_sum += number_of_commits_in_first_page 
     end 
     puts "Commits for #{e.name} : #{repo_sum}" 
     total_sum_commits += repo_sum 
    end 
    puts "TOTAL COMMITS #{total_sum_commits}" 
end 

और हाँ मैं जानता हूँ कि कोड गंदा है, यह बस कुछ ही में एक साथ फेंक दिया गया था मिनट।

संबंधित मुद्दे