Github API - retrieve user commits?

teenybreeny picture teenybreeny · Feb 19, 2014 · Viewed 8.5k times · Source

I'm trying build a method in which I can access a Github user name, and publish either all commits or at least a number of commits from that user.

Is there a call to GET user/repo/commit association or a direct user/commit?

Right now, I think what it will take is the following:

  1. Obtain repos associated with a particular name: api.github.com/users/:name/repos.

  2. From feed obtain repo name.

  3. Place repo names in an array, such as:

    api.github.com/repos/:user/:repo1/commits
    api.github.com/repos/:user/:repo2/commits
    api.github.com/repos/:user/:repo3/commits
  1. From feeds, obtain number count of shas?

Answer

Phil Booth picture Phil Booth · May 31, 2016

Iterating through a user's repositories is sub-optimal because it misses any commits they make in other repositories. A better way is to use the Events API instead.

The first step is to get the user's events:

GET /users/:username/events

Next you need to iterate through the returned events, checking for items where result.type is set to PushEvent. Each one of these corresponds to a git push by the user and the commits from that push are available (in reverse chronological order) as result.payload.commits.

You can filter those to ignore any commits made by other users, by checking that commit.author.email matches what you expect. You also have access to properties like sha, message and url on that object, and you can eliminate duplicate commits across multiple pushes using the distinct property.

Overall there is more legwork involved, but it also gives you a far more accurate representation of what a user has actually committed.

In case it helps, here's some example code taken from my website, which uses the above approach to fetch the last commit for a user (implemented using Node.js and the octokat npm module):

const USER = 'TODO: your GitHub user name'
const EMAIL = 'TODO: your GitHub email address'

const github = require('octokat')({ token: 'TODO: your GitHub API token' })

return github.fromUrl(`https://api.github.com/users/${USER}/events`)
  .fetch()
  .then(events => {
    let lastCommit

    events.some(event => {
      return event.type === 'PushEvent' && event.payload.commits.reverse().some(commit => {
        if (commit.author.email === EMAIL) {
          lastCommit = {
            repo: event.repo.name,
            sha: commit.sha,
            time: new Date(event.createdAt),
            message: commit.message,
            url: commit.url
          }

          return true
        }

        return false
      })
    })

    return lastCommit
  })