Isaac.

How to Get the Total Number of Commits from the GitHub API

The GitHub API does not provide a direct endpoint to fetch the total number of commits for a repository. However, developers can use a workaround by leveraging the pagination information returned in the API's response headers.

The Efficient Method: Using the Link Header

This approach minimizes API calls and is the standard way to get a total count for paginated resources:

  1. Make an API Request: Send a GET request to the repository's commits endpoint with per_page=1.
    /repos/{owner}/{repo}/commits?per_page=1
  2. Inspect the Link Header: The response will include pagination info.
    Link: <https://api.github.com/repos/owner/repo/commits?per_page=1&page=2>; rel="next", <https://api.github.com/repos/owner/repo/commits?per_page=1&page=5000>; rel="last"
  3. Extract the Last Page Number: The page value in the rel="last" URL corresponds to the total commits.

Code Examples

Using curl (Command Line)

For a quick check, you can fetch headers only with the -I flag:

# The -I flag tells curl to fetch headers only
curl -I "https://api.github.com/repos/torvalds/linux/commits?per_page=1"

Using JavaScript (fetch)

async function getTotalCommits(owner, repo) { const accessToken = 'YOUR_GITHUB_ACCESS_TOKEN'; const url = `https://api.github.com/repos/${owner}/${repo}/commits?per_page=1`; try { const response = await fetch(url, { headers: { 'Authorization': `token ${accessToken}` } }); if (!response.ok) throw new Error(`HTTP error! status: ${response.status}`); const linkHeader = response.headers.get('Link'); if (!linkHeader) return 'N/A'; const lastPageMatch = linkHeader.match(/<[^>]+[?&]page=(\d+)[^>]*>;\s*rel="last"/); return lastPageMatch ? parseInt(lastPageMatch[1], 10) : 'N/A'; } catch (error) { console.error('Error fetching commits:', error); } } // Example: getTotalCommits('facebook', 'react');

Using Python (requests)

import requests, re def get_total_commits(owner, repo): access_token = 'YOUR_GITHUB_ACCESS_TOKEN' url = f"https://api.github.com/repos/{owner}/{repo}/commits?per_page=1" headers = {'Authorization': f'token {access_token}'} try: response = requests.get(url, headers=headers) response.raise_for_status() if 'Link' in response.headers: link_header = response.headers['Link'] last_page_search = re.search(r'<[^>]+[?&]page=(\d+)[^>]*>;\s*rel="last"', link_header) if last_page_search: return int(last_page_search.group(1)) # fallback if no Link header response = requests.get(f"https://api.github.com/repos/{owner}/{repo}/commits", headers=headers) response.raise_for_status() return len(response.json()) except requests.exceptions.RequestException as e: print(f"An error occurred: {e}") return None # Example: get_total_commits('git', 'git')

⚠️ Important Considerations

  • Authentication: Without a Personal Access Token, requests are limited to 60 per hour. With a token, you get 5,000 per hour.
  • Large Repositories: GitHub may not provide a rel="last" link for very large repos. In such cases, you'll need to iterate through pages using rel="next".