48

V2 のドキュメントによると、ブランチのすべてのコミットを次のように一覧表示できます。

commits/list/:user_id/:repository/:branch

V3 のドキュメントには同じ機能がありません。

次のようなものを使用してすべてのブランチを収集したいと思います。

https://api.github.com/repos/:user/:repo/branches

そして、それらを繰り返し処理し、それぞれのすべてのコミットをプルします。または、リポジトリのすべてのブランチのすべてのコミットを直接プルする方法があれば、それはうまくいかないにしても同様に機能します。何か案は?

更新:次のように、ブランチ :sha をパラメーターとして渡してみました:

params = {:page => 1, :per_page => 100, :sha => b}

問題は、これを行うと、結果が適切にページングされないことです。私たちはこれに間違ったアプローチをしているように感じます。何かご意見は?

4

4 に答える 4

43

私はまったく同じ問題に遭遇しました。リポジトリ内のすべてのブランチのすべてのコミットを取得することができました (おそらくAPI のために効率的ではありません)。

リポジトリ内のすべてのブランチのすべてのコミットを取得するアプローチ

あなたが言ったように、最初にすべてのブランチを集めます:

# https://api.github.com/repos/:user/:repo/branches
https://api.github.com/repos/twitter/bootstrap/branches

見逃している重要な点は、コミットを取得するための APIv3 が参照コミット (リポジトリshaでコミットを一覧表示するための API 呼び出しのパラメーター) を使用して動作することです。そのため、ブランチを収集するときに、最新の sha も取得するようにする必要があります。

twitter/bootstrap のブランチ API 呼び出しのトリミング結果

[
  {
    "commit": {
      "url": "https://api.github.com/repos/twitter/bootstrap/commits/8b19016c3bec59acb74d95a50efce70af2117382",
      "sha": "8b19016c3bec59acb74d95a50efce70af2117382"
    },
    "name": "gh-pages"
  },
  {
    "commit": {
      "url": "https://api.github.com/repos/twitter/bootstrap/commits/d335adf644b213a5ebc9cee3f37f781ad55194ef",
      "sha": "d335adf644b213a5ebc9cee3f37f781ad55194ef"
    },
    "name": "master"
  }
]

最後のコミットの sha の操作

ここで 2 つのブランチが異なる sha を持っていることがわかるように、これらはそれらのブランチの最新のコミット sha です。今できることは、最新の sha から各ブランチを反復処理することです。

# With sha parameter of the branch's lastest sha
# https://api.github.com/repos/:user/:repo/commits
https://api.github.com/repos/twitter/bootstrap/commits?per_page=100&sha=d335adf644b213a5ebc9cee3f37f781ad55194ef

したがって、上記の API 呼び出しは、 twitter/bootstrapのマスターブランチの最新の 100 件のコミットを一覧表示します。API を使用して、次の 100 件のコミットを取得するには、次のコミットの sha を指定する必要があります。次の API 呼び出しの入力として、最後のコミットの sha (現在の例では7a8d6b19767a92b1c4ea45d88d4eedc2b29bf1fa ) を使用できます。

# Next API call for commits (use the last commit's sha)
# https://api.github.com/repos/:user/:repo/commits
https://api.github.com/repos/twitter/bootstrap/commits?per_page=100&sha=7a8d6b19767a92b1c4ea45d88d4eedc2b29bf1fa

このプロセスは、最後のコミットの sha が API の call sha パラメータと同じになるまで繰り返されます。

次のブランチ

これで 1 つのブランチは終了です。ここで、他のブランチに同じアプローチを適用します (最新の sha から作業します)。


このアプローチには大きな問題があります...ブランチはいくつかの同一のコミットを共有するため、別のブランチに移動すると、同じコミットが何度も何度も表示されます。

これを達成するためのはるかに効率的な方法があると想像できますが、これは私にとってはうまくいきました。

于 2012-04-01T20:54:30.120 に答える
32

GitHub サポートに同じ質問をしたところ、次のような回答がありました。

/repos/:owner/:repo/commitsを取得するとうまくいくはずです。パラメータでブランチ名を渡すことができshaます。たとえば、twitter/bootstrap リポジトリの「3.0.0-wip」ブランチからコミットの最初のページを取得するには、次の curl リクエストを使用します。

curl https://api.github.com/repos/twitter/bootstrap/commits?sha=3.0.0-wip

このドキュメントでは、ページネーションを使用してこのブランチの残りのコミットを取得する方法についても説明しています。

認証済みのリクエストを作成している限り、1 時間あたり最大 5,000 件のリクエストを作成できます。

次のようにアプリで Rails github-api を使用しました ( https://github.com/peter-murach/github gem を使用):

github_connection = Github.new :client_id => 'your_id', :client_secret => 'your_secret', :oauth_token => 'your_oath_token'
branches_info = {}
all_branches = git_connection.repos.list_branches owner,repo_name
all_branches.body.each do |branch|
    branches_info["#{branch.name}".to_s] = "#{branch.commit.url}"
end
branches_info.keys.each do |branch|
    commits_list.push (git_connection.repos.commits.list owner,repo_name, start_date,      end_date, :sha => "branch_name")
end
于 2013-05-28T00:46:12.723 に答える
0

アクセストークンなしのピュアJS実装(不正利用)

const base_url = 'https://api.github.com';

    function httpGet(theUrl, return_headers) {
        var xmlHttp = new XMLHttpRequest();
        xmlHttp.open("GET", theUrl, false); // false for synchronous request
        xmlHttp.send(null);
        if (return_headers) {
            return xmlHttp
        }
        return xmlHttp.responseText;
    }

    function get_all_commits_count(owner, repo, sha) {
        let first_commit = get_first_commit(owner, repo);
        let compare_url = base_url + '/repos/' + owner + '/' + repo + '/compare/' + first_commit + '...' + sha;
        let commit_req = httpGet(compare_url);
        let commit_count = JSON.parse(commit_req)['total_commits'] + 1;
        console.log('Commit Count: ', commit_count);
        return commit_count
    }

    function get_first_commit(owner, repo) {
        let url = base_url + '/repos/' + owner + '/' + repo + '/commits';
        let req = httpGet(url, true);
        let first_commit_hash = '';
        if (req.getResponseHeader('Link')) {
            let page_url = req.getResponseHeader('Link').split(',')[1].split(';')[0].split('<')[1].split('>')[0];
            let req_last_commit = httpGet(page_url);
            let first_commit = JSON.parse(req_last_commit);
            first_commit_hash = first_commit[first_commit.length - 1]['sha']
        } else {
            let first_commit = JSON.parse(req.responseText);
            first_commit_hash = first_commit[first_commit.length - 1]['sha'];
        }
        return first_commit_hash;
    }

    let owner = 'getredash';
    let repo = 'redash';
    let sha = 'master';
    get_all_commits_count(owner, repo, sha);

クレジット - https://gist.github.com/yershalom/a7c08f9441d1aadb13777bce4c7cdc3b

于 2020-05-01T18:13:12.460 に答える