2013-04-10 23 views
12

O ile rozumiem, wiadomości są powiązane z zatwierdzeniami. Ale kiedy patrzysz na repozytorium na GitHubie, to pomocnie wyświetla listę wiadomości dla każdego pliku, dla którego była ostatnio zmieniana.W interfejsie API GitHub - jaki jest najlepszy sposób uzyskania ostatniego komunikatu zatwierdzenia związanego z każdym plikiem?

Chciałbym to powtórzyć w widoku sieciowym repo, które mam. Patrząc na apik GitHub wygląda na to, że jedynym sposobem, aby uzyskać te informacje, jest pobranie wszystkich zatwierdzeń (które mogą być stronicowane), i pracy od najnowszych przypisywanie wiadomości commit do plików w lokalnej pamięci podręcznej, idąc coraz dalej i dalej, dopóki nie otrzymasz wiadomości dla każdego pliku, potencjalnie do pierwszego zatwierdzenia, jeśli któryś z plików nie został zmieniony od czasu pierwszego zatwierdzenia, czy to jest właściwy sposób, aby to zrobić? ? Czy to nie zabije nawet kwoty 5000/hr?

+0

Nie jestem pewien, czy w pełni rozumiem, co chcesz osiągnąć. Czy chcesz uzyskać (1) najnowszy komentarz do pliku, bez względu na to, z którym komentarzem jest powiązany ten komentarz? Czy chcesz uzyskać (2) najnowszy komentarz w ostatnim zatwierdzeniu pliku? Różnica polega na tym, że plik może mieć przypisane komentarze w kilku zatwierdzeniach, a ostatni komentarz może nie być ostatnim zatwierdzeniem, ponieważ ktoś może skomentować plik w poprzednim zatwierdzeniu. A więc, która z tych opcji jest tym, czego chcesz? –

+0

Chcę opcji 1, proszę :) Tak jak pokazuje się w widoku internetowym na GitHub się. –

+0

Gdzie to pokazuje, że w widoku sieciowym na GitHub? Czy możesz podać dokładny adres URL jako przykład? Kiedy wchodzisz do strony projektu na GitHub, pokazuje ci wiadomości do zatwierdzenia dla plików (np. Listę plików, kiedy wchodzisz na https://github.com/github/developer.github.com), a nie komentarze do commitów . Zaakceptuj wiadomości i komentarze do commitów to dwie różne rzeczy. Przepraszam, jeśli źle cię zrozumiałem, chcę tylko wyjaśnić, czego dokładnie potrzebujesz. :) –

Odpowiedz

26

Po ustaleniu, że potrzebna jest najnowsza wiadomość zatwierdzenia dla każdego pliku, oto, co możesz zrobić.

Najpierw zdobądź listę plików w repozytorium. Aby to zrobić, trzeba:

1) fetch the reference object oddziału, że chcesz do listy plików do:

GET https://api.github.com/repos/:owner/:repo/git/refs/heads/:branch 

prawdopodobnie chcesz oddziału głównego, więc jest to przykład żądania Ci będzie Marka:

https://api.github.com/repos/izuzak/pmrpc/git/refs/heads/master 

odpowiedzi dostaniesz będzie wyglądać następująco:

{ 
    "ref": "refs/heads/master", 
    "url": "https://api.github.com/repos/izuzak/pmrpc/git/refs/heads/master", 
    "object": { 
    "sha": "fd6973f430a3367ad718ff049f1b075843913d6f", 
    "type": "commit", 
    "url": "https://api.github.com/repos/izuzak/pmrpc/git/commits/fd6973f430a3367ad718ff049f1b075843913d6f" 
    } 
} 

2) fetch the commit object że punkty referencyjne, stosując własność odpowiedzi otrzymanej w poprzednim etapie object.url:

GET https://api.github.com/repos/izuzak/pmrpc/git/commits/fd6973f430a3367ad718ff049f1b075843913d6f 

Odpowiedź dostaniesz będzie wyglądać następująco:

{ 
    "sha": "fd6973f430a3367ad718ff049f1b075843913d6f", 
    "url": "https://api.github.com/repos/izuzak/pmrpc/git/commits/fd6973f430a3367ad718ff049f1b075843913d6f", 
    "html_url": "https://github.com/izuzak/pmrpc/commits/fd6973f430a3367ad718ff049f1b075843913d6f", 
    "author": { 
    "name": "Ivan Zuzak", 
    "email": "[email protected]", 
    "date": "2013-04-09T08:55:45Z" 
    }, 
    "committer": { 
    "name": "Ivan Zuzak", 
    "email": "[email protected]l.com", 
    "date": "2013-04-09T08:55:45Z" 
    }, 
    "tree": { 
    "sha": "f5f5de80f67dd794ffbd4abb855fb7d1a573660e", 
    "url": "https://api.github.com/repos/izuzak/pmrpc/git/trees/f5f5de80f67dd794ffbd4abb855fb7d1a573660e" 
    }, 
    "message": "fix typos", 
    "parents": [ 
    { 
     "sha": "d3617ae56dda793131e743b2ff394984bbab6ca3", 
     "url": "https://api.github.com/repos/izuzak/pmrpc/git/commits/d3617ae56dda793131e743b2ff394984bbab6ca3", 
     "html_url": "https://github.com/izuzak/pmrpc/commits/d3617ae56dda793131e743b2ff394984bbab6ca3" 
    } 
    ] 
} 

3) fetch the tree object obiektu zatwierdzenia pobranego w poprzednim kroku. Można to zrobić klikając link tree.url zawartych w odpowiedzi z poprzedniego etapu:

GET https://api.github.com/repos/izuzak/pmrpc/git/trees/f5f5de80f67dd794ffbd4abb855fb7d1a573660e 

Odpowiedź będzie wyglądać następująco:

{ 
    "sha": "f5f5de80f67dd794ffbd4abb855fb7d1a573660e", 
    "url": "https://api.github.com/repos/izuzak/pmrpc/git/trees/f5f5de80f67dd794ffbd4abb855fb7d1a573660e", 
    "tree": [ 
    { 
     "mode": "100644", 
     "type": "blob", 
     "sha": "726f21a4adec8c24c2fab6cf5b455d094a8b21bf", 
     "path": "LICENSE.markdown", 
     "size": 568, 
     "url": "https://api.github.com/repos/izuzak/pmrpc/git/blobs/726f21a4adec8c24c2fab6cf5b455d094a8b21bf" 
    }, 
    { 
     "mode": "100644", 
     "type": "blob", 
     "sha": "eb94760b81441b34a73d1b085d9f153ae48b0e63", 
     "path": "README.markdown", 
     "size": 5772, 
     "url": "https://api.github.com/repos/izuzak/pmrpc/git/blobs/eb94760b81441b34a73d1b085d9f153ae48b0e63" 
    }, 
    { 
     "mode": "040000", 
     "type": "tree", 
     "sha": "2e72b217b8644ce6874cda03387a7ab2d8eee55e", 
     "path": "examples", 
     "url": "https://api.github.com/repos/izuzak/pmrpc/git/trees/2e72b217b8644ce6874cda03387a7ab2d8eee55e" 
    }, 
    { 
     "mode": "100644", 
     "type": "blob", 
     "sha": "64b0dbe4981759c0f9640c8e882c97c7324fc798", 
     "path": "pmrpc.js", 
     "size": 24546, 
     "url": "https://api.github.com/repos/izuzak/pmrpc/git/blobs/64b0dbe4981759c0f9640c8e882c97c7324fc798" 
    } 
    ] 
} 

Są to wszystkie pliki i foldery w repozytorium. Zauważ jednak, że w przypadku folderów będziesz musiał rekurencyjnie pobrać obiekt drzewa folderów, aby uzyskać listę plików w folderze. W powyższej odpowiedzi examples jest folderem, który można zobaczyć po wartości drzewa właściwości type. Tak więc, byś się do innego żądania GET na URL wyposażonego w folderze:

GET https://api.github.com/repos/izuzak/pmrpc/git/trees/2e72b217b8644ce6874cda03387a7ab2d8eee55e 

Alternatywnym podejściem jest uzyskać listę wszystkich plików (we wszystkich folderach) z tylko jedną prośbę, używając parametru recursive=1 , jak opisano here. Proponuję użyć tego podejścia, ponieważ wymaga tylko jednego żądania HTTP.

Następnie, po wybraniu listy plików i folderów w repozytorium, get the last commit zmieni wszystkie pliki/foldery. Aby to zrobić, należy ten wniosek

GET https://api.github.com/repos/:user/:repo/commits?path=FILE_OR_FOLDER_PATH 

Tak więc, na przykład, jest to żądanie do sprowadzenia zobowiązuje do folderu examples wymienionych powyżej:

GET https://api.github.com/repos/izuzak/pmrpc/commits?path=examples 

odpowiedź otrzymasz jest lista popełnić obiekt i należy patrzeć tylko na pierwszy obiekt w tym wykazie (ponieważ jesteś zainteresowany w ostatnim zobowiązać do pliku) i odzyskać własność commit.message dostać wiadomość, czego potrzebujesz:

[ 
    { 
    "sha": "3437f015257683a86e3b973b3279754df9ac2b24", 
    "commit": { 
     "author": { ... }, 
     "committer": { ... }, 
     "message": "change mode", 
     "tree": { ... }, 
     "url": "https://api.github.com/repos/izuzak/pmrpc/git/commits/3437f015257683a86e3b973b3279754df9ac2b24", 
     "comment_count": 0 
    }, 
    ... 
    }, 
    { 
    ... 
    } 
] 

W tym przypadku, komunikat o ostatnim zatwierdzeniu, który zmienił folder examples, to "tryb zmiany".

Zasadniczo należy wykonać 3 żądania HTTP, aby pobrać listę plików, a następnie 1 żądanie HTTP dla każdego pliku i folderu. Złą wiadomością jest to, że jeśli masz dużo plików - będziesz robił dużo żądań HTTP. Dobrą wiadomością jest to, że możesz buforować odpowiedzi, aby nie było potrzeby zgłaszania żądań, jeśli nic się nie zmieni (więcej informacji znajdziesz w artykule here). Ponadto nie będziesz pobierać wszystkich komunikatów commit na raz, pobierzesz je, gdy użytkownik przejdzie przez foldery (tak jak w GitHub, gdy klikasz foldery). Dzięki temu powinieneś być w stanie łatwo utrzymać w granicach 5000 żądań.

Mam nadzieję, że to pomoże! Daj mi znać, jeśli znajdziesz łatwiejszy sposób na zrobienie tego :). Nie wiem, czy istnieje sposób, aby osiągnąć ten cel za pomocą 1-2 zapytań, czego prawdopodobnie oczekiwałeś.

+1

Wybrane jako odpowiedź, ponieważ jest bardzo wszechstronne, dziękuję. Jednak jest to wezwanie do pobrania ostatniego zatwierdzenia dla każdego pliku, którego miałem nadzieję uniknąć. Myślę, że to, co zrobię, to mieć cronową pracę, która dostaje kilka razy tak często, ograniczając stawkę, którą robi. Nie jest to ważna informacja, ale jest przydatna, myślę, że –

+0

@MarcosScriven Thanks! I tak, rozumiem, dlaczego to jest dla ciebie problem. Idea pracy cron brzmi jednak świetnie. Miły! –

+4

Nice! Jeśli chcesz tylko ostatnie zatwierdzenie, które wpłynęło na plik, możesz użyć funkcji podziału na strony, aby działała tak, jak: 'GET https: //api.github.com/repos/izuzak/pmrpc/commits? Ścieżka = przykłady & page = 1 & per_page = 1' – novemberkilo

2

mam wystawianie zobowiązuje w repozytorium i niż chwytając pierwszy i czytanie to SHA i działa świetnie:

https://developer.github.com/v3/repos/commits/#list-commits-on-a-repository

W Go to wygląda mniej więcej tak:

func GetLatestCommit(owner, repo string, sgc *github.Client) (string, error) { 
    commits, res, err := sgc.Repositories.ListCommits(owner, repo, &github.CommitsListOptions{}) 

    if err != nil { 
     log.Printf("err: %s res: %s", err, res) 
     return "", err 
    } 

    log.Printf("last commit: %s", *commits[0].SHA) 

    return *commits[0].SHA, nil 
} 
0

W poszukiwaniu budowania trwałych linków, znalazłem jeden z najprostszych sposobów pobrania commit sha to faktycznie parsować stronę html.

Korzyści:

  • wszystkich stron pliku/folderu w repozytorium ma, nawet korzeń
  • pojedynczego połączenia HTTP
  • bez uwierzytelniania login potrzebne
  • użyje właściwego oddziału (niektóre don Domyślnie używany jest master)
  • działa również na oddziałach

Na każdej stronie pliku znajduje się łącze o nazwie Permalink. Jeśli szukasz sposobów na zidentyfikowanie tego linku: , istnieje klasa .js-permalink-shortcut, a także atrybut data-hotkey="y", zgodnie z opisem w Getting permanent links to files - Github.

<a href="/luckydonald/JavaPipBoyServer/blob/a6f4038336ff41463ad527b4ff4fda45642ebc6d/PROTOCOL.md" class="d-none js-permalink-shortcut" data-hotkey="y">Permalink</a> 

W tym przykładzie sha to a6f4038336ff41463ad527b4ff4fda45642ebc6d.

Uwaga, zawsze będzie renderowany, nawet jeśli już jesteś na tym zatwierdzeniu.

W przypadku, gdy ktoś lubi budować z niego link bezpośredni, hash adresu URL (na przykład odniesienia do wierszy, takie jak #L437-L441) musi być przechowywany (dołączany) ręcznie.

Powiązane problemy