2013-01-19 7 views
9

Ich versuche, die GitHub v3 API zu verwenden, um die vollständige Liste der Commits zwischen zwei SHAs zu erhalten, the comparison API (/repos/:owner/:repo/compare/:base...:head), aber es gibt nur die ersten 250 commits und Ich muss alle von ihnen bekommen.GitHub v3 API: Vollständige Commitliste für großen Vergleich erhalten

Ich fand the API pagination docs, aber der Vergleich API scheint nicht entweder die page oder per_page Parameter, entweder mit Zählungen oder Schas zu unterstützen (EDIT: Die last_sha Parameter funktionieren auch nicht). Und im Gegensatz zur Commits-API scheint die Vergleichs-API keinen Link HTTP-Header zurückzugeben.

Gibt es eine Möglichkeit, entweder das Commit Count Limit auf der Compare-API zu erhöhen oder eine zweite Commit-Seite zu holen?

+3

Ich habe GitHub Unterstützung für Sie kontaktiert. Als Autor eines API-Wrappers bin ich selbst neugierig darauf. Ich poste zurück mit dem, was sie antworten, wenn sie sich nicht selbst beantworten. –

+0

Danke, @ sigmavirus24! – etlovett

+1

Ja, sie kamen nie zurück zu mir ... sorry –

Antwort

0

Verwenden Sie den Parameter last_sha. Die Commits-API scheint das für Paginierung zu verwenden, anstatt page

+0

Leider scheint die Commit-Vergleichs-API den Parameter last_sha einfach zu ignorieren. die Ausgabe ist identisch mit und ohne es. – etlovett

+0

Funktioniert nicht, und "Last_sha" ist in diesen Tagen sowieso veraltet. – Nakedible

1

Es ist relativ einfach. Hier ein Beispiel:

import requests 
next_url = 'https://api.github.com/repos/pydanny/django-admin2/commits' 
while next_url: 
    response = requests.get(next_url) 
    # DO something with response 
    # ... 
    # ... 
    if 'next' in response.links: 
     next_url = response.links['next']['url'] 
    else: 
     next_url = '' 

UPDATE:

takie daran, dass neben Urls anders ist als Anfang ab: Initial url:

https://api.github.com/repos/pydanny/django-admin2/commits

nächster url:

https://api.github.com/repositories/10054295/commits?top=develop&last_sha=eb204104bd40d2eaaf983a5a556e38dc9134f74e

So ist es völlig neue URL-Struktur.

+2

Dank dieser Antwort kann Django Packages nun eine Reihe von Commits wiederherstellen, die nach der letzten Änderung der GitHub API verloren gegangen sind. Danke @galuszkak! – pydanny

+0

Danke @pydanny – galuszkak

+1

Ich würde bemerken, dass dies nicht "relativ einfach" ist. Die Dokumentation ist ziemlich unklar, wie das funktioniert. Während die Implementierung "einfach" ist, wie bei vielen Herausforderungen beim Programmieren, ist es schwierig, die Implementierung zu bestimmen. – pydanny

0

Von: https://developer.github.com/v3/repos/commits/#working-with-large-comparisons

mit großen Vergleiche Arbeiten

Die Antwort wird ein Vergleich von bis zu 250 Commits umfassen. Wenn Sie mit einem größeren Commit-Bereich arbeiten, können Sie die Commit-Liste-API verwenden, um alle Commits im Bereich aufzuzählen.

Bei Vergleichen mit extrem großen Diffs erhalten Sie möglicherweise eine Fehlerantwort, die darauf hinweist, dass der Vergleich zu lange gedauert hat. Sie können in der Regel diese Fehler beheben, indem Bereich eines kleinen begehen mit

+1

Das sagt Ihnen eigentlich nicht, wie es geht, weil die Verwendung der Commit-Liste-API definitiv nicht klar ist! – Nakedible

2

Fordern Sie den Parameter sha, zum Beispiel mit:

https://api.github.com/repos/junit-team/junit/commits?sha=XXX, wo die XXX das SKH der letzten zurückgegeben in der aktuellen Runde der Abfrage begehen. Dann iteriere diesen Prozess, bis du die End-SHA erreichst.

Beispiel Python-Code:

startSHA = '' 
endSHA = '' 
while True: 
    url = 'https://api.github.com/repos/junit-team/junit/commits?sha=' + startSHA 
    r = requests.get(url) 
    data = json.loads(r.text) 
    for i in range(len(data)): 
     commit = data[i]['sha'] 
     if commit == endSHA: 
      #reach the ending SHA, stop here 
     startSHA = commit 
+0

Verwenden von Paging ist besser. Die Git-Historie enthält möglicherweise Zusammenführungen, bei denen nur die letzte sha-Datei nur einem Elternteil der Zusammenführung folgt.Beim Paging geschieht dies nicht, da die Commits aller Eltern zurückgegeben werden. – Nakedible

1

Ich habe versucht, diese wieder zu lösen. Meine Notizen:

  • Vergleichen (oder Pull Request Commits) Liste zeigt nur 250 Einträge. Für die Pull-Anforderung können Sie paginieren, aber Sie erhalten nur maximal 250 Commits, egal was Sie tun.

  • Die Commit-Liste-API kann die gesamte Commit-Kette mit Paging bis zum Anfang des Repositorys durchlaufen.

  • Für eine Pull-Anforderung ist das "Basis" -Commit nicht unbedingt in der Historie, die vom Pull-Request "head" -Commit erreichbar ist. Dies ist zum Vergleich gleich, das "base_commit" ist nicht unbedingt ein Teil der Historie des aktuellen Kopfes.

  • Das "merge_base_commit" ist jedoch ein Teil des Verlaufs, daher ist der richtige Ansatz, mit dem Commit "head" zu beginnen und Commit-Listenabfragen zu iterieren, bis Sie "merge_base_commit" erreichen. Für eine Pull-Anforderung bedeutet dies, dass ein Vergleich zwischen "head" und "base" des Pulls zwingend erforderlich ist.

  • Alternative Ansatz ist „TOTAL_COMMITS“ zurückgeführt, indem vergleichen zu verwenden, und iterieren nur nach hinten, bis die gewünschte Anzahl von Commits zu erreichen. Dies scheint zu funktionieren, aber ich bin nicht 100% sicher, dass dies in allen Eckfällen mit Merges und dergleichen korrekt ist.

  • Also Commit Liste API, Seitenumbruch und "merge_base_commit" löst dieses Dilemma.

    0

    Hier ist ein Beispiel, um alle für einen Pull-Request verpflichtet Geschrieben mit Octokit.NET (https://github.com/octokit/octokit.net)

     var owner = "..."; 
         var repository = "..."; 
         var gitHubClient = new GitHubClient(
           new ProductHeaderValue("MyApp"), 
           new InMemoryCredentialStore(new Credentials("GitHubToken"))); 
         var pullRequest = await gitHubClient.PullRequest.Get(owner, repository, pullRequestNumber); 
         Console.WriteLine("Summarising Pull Request #{0} - {1}", pullRequest.Number, pullRequest.Title); 
         var commits = new List<GitHubCommit>(); 
         var moreToGet = true; 
         var headSha = pullRequest.Head.Sha; 
         while (moreToGet) 
         { 
          var comparison = 
           await 
           gitHubClient.Repository.Commits.Compare(
            owner, 
            repository, 
            pullRequest.Base.Sha, 
            headSha); 
    
          // Because we're working backwards from the head towards the base, but the oldest commits are at the start of the list 
          commits.InsertRange(0, comparison.Commits); 
          moreToGet = comparison.Commits.Count == 250; 
          if (moreToGet) 
          { 
           headSha = commits.First().Sha; 
          } 
         } 
    

    Ich versuchte ursprünglich machte moreToGet auf true gesetzt ein, wenn mit der Basis sha begeht gefunden wurde, aber nie inbegriffen in der Liste der Commits (nicht sicher, warum), so gehe davon aus ich mehr nur zu erhalten, wenn der Vergleich die Grenze von 250

    0

    hit/begeht? per_page = * erhalten Sie alle verpflichtet

    +0

    Dies funktioniert nicht – bert

    0

    das ist mein Lösung mit Octokit.Net

    private async Task<IReadOnlyList<GitHubCommit>> GetCommits(string branch, string baseBranch) 
    { 
        // compare branches and get all commits returned 
        var result = await this.gitHub.Repository.Commit.Compare(this.repoSettings.Owner, this.repoSettings.Name, baseBranch, branch); 
        var commits = result.Commits.ToList(); 
    
        // the commits property on the result only has the first 250 commits 
        if (result.TotalCommits > 250) 
        { 
         var baseCommitId = result.MergeBaseCommit.Sha; 
         var lastCommitLoadedId = commits.First().Sha; 
         var allCommitsLoaded = false; 
         var page = 1; 
    
         while (!allCommitsLoaded) 
         { 
          var missingCommits = await this.gitHub.Repository.Commit.GetAll(this.repoSettings.Owner, this.repoSettings.Name, new CommitRequest 
          { 
           Sha = lastCommitLoadedId // start from the oldest commit returned by compare 
          }, 
          new ApiOptions 
          { 
           PageCount = 1, 
           PageSize = 100, // arbitrary page size - not sure what the limit is here so set it to a reasonably large number 
           StartPage = page 
          }); 
    
          foreach (var missingCommit in missingCommits) 
          { 
           if (missingCommit.Sha == lastCommitLoadedId) 
           { 
            // this is the oldest commit in the compare result so we already have it 
            continue; 
           } 
    
           if (missingCommit.Sha == baseCommitId) 
           { 
            // we don't want to include this commit - its the most recent one on the base branch 
            // we've found all the commits now we can break out of both loops 
            allCommitsLoaded = true; 
            break; 
           } 
    
           commits.Add(missingCommit); 
          } 
    
          page++; 
         } 
        } 
    
        return commits; 
    } 
    
    Verwandte Themen