Reputation: 677
I want to find the number of commits done to specific github projects, and within them to specific files. I checked the github api docs but only found an API for actually returning all commits. This would be very inefficient since I have to do multiple api calls for paging thru all commits.
Anyone has a better idea?
Upvotes: 18
Views: 11251
Reputation: 45352
With GraphQL API v4, you can get total commit count per branch with totalCount
for each branch:
{
repository(owner: "google", name: "gson") {
name
refs(first: 100, refPrefix: "refs/heads/") {
edges {
node {
name
target {
... on Commit {
id
history(first: 0) {
totalCount
}
}
}
}
}
}
}
}
Upvotes: 6
Reputation: 10157
0penBrain found a clever way to obtain this information and detailed it in the following Gist : https://gist.github.com/0penBrain/7be59a48aba778c955d992aa69e524c5
Here's the relevant snippet with curl
:
curl -I -k "https://api.github.com/repos/:owner/:repo/commits?per_page=1" | sed -n '/^[Ll]ink:/ s/.*"next".*page=\([0-9]*\).*"last".*/\1/p'
The trick is to enable a 1 commit per page pagination, as can be seen in the query-string. Then the focus must shift from the response JSON body to the HTTP headers where the following entry can be found :
link: <https://api.github.com/repositories/27193779/commits?per_page=1&page=2>; rel="next", <https://api.github.com/repositories/27193779/commits?per_page=1&page=37949>; rel="last"
The sed
expression is then in charge of extracting the 37949
number (in this example)
Upvotes: 1
Reputation: 311
Pure JS Implementation
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);
Credits - https://gist.github.com/yershalom/a7c08f9441d1aadb13777bce4c7cdc3b
Upvotes: 0
Reputation: 1323145
Update May 2013: see "File CRUD and repository statistics now available in the API"
You now can Get the last year of commit activity data
GET /repos/:owner/:repo/stats/commit_activity
Returns the last year of commit activity grouped by week. The days array is a group of commits per day, starting on Sunday.
Not completely what you are looking for, but closer.
Original answer (April 2010)
No, the current API doesn't support a 'log --all
' for listing all commmits from all branches.
The only alternative is presented in "Github API: Retrieve all commits for all branches for a repo", and list through all pages of all commits, branch after branch.
This seems so cumbersome than another alternative would actually to clone the Github repo and apply git commands on that local clone!
(mainly git shortlog
)
Note: you can also checkout that python script created by Arcsector.
Upvotes: 13