GitHub API's `since` Parameter: A Hidden Pitfall for Git Performance Tracking
Uncovering a GitHub API Blind Spot: Why Your Repository Syncs Might Be Missing Updates
For developers and teams relying on automated systems to track repository activity, an accurate and comprehensive view of updates is crucial for effective software development project plan management and understanding overall git performance. However, a recent discussion in the GitHub Community has brought to light a significant limitation in the GitHub REST API that could lead to silent data loss for many such tools.
The Issue: `GET /user/repos?since` Ignores Non-Default Branch Activity
The core problem lies with the GET /user/repos endpoint, specifically when using the since parameter to fetch repositories updated after a certain timestamp. As reported by 0xMurage, this filter appears to rely solely on the default branch's updated_at timestamp. This means that if a repository's most recent activity is a commit or push to a non-default branch (e.g., a dev or feature-xyz branch), the repository will be entirely omitted from the API response when filtered by since, even though the repository itself has clearly been updated.
Steps to Reproduce the Discrepancy:
- Identify a repository where the last activity on the
mainbranch was days ago. - Push a new commit to a secondary branch (e.g.,
devorfeature-xyz) today. - Query
GET /user/repos?since=[yesterday]. - Observed Result: The repository is missing from the payload.
- Expected Result: The repository should be included due to the recent update on a non-default branch.
The Root Cause: `updated_at` vs. `pushed_at`
As clarified by community member roohan-514, the underlying issue is that GitHub's internal repository.updated_at column, which the since filter queries against, only updates when the default branch receives a commit, a push, or when repository metadata changes. Pushes to non-default branches do not trigger an update to this specific timestamp. This behavior, while consistent for years, contradicts the API documentation's description of since returning repos "updated after the given timestamp," as a push to any branch is indeed an update to the repository.
This limitation can severely impact tools designed for developer activity tracking, such as a Haystack alternative, that need to capture all Git activity for comprehensive insights into team productivity and project progress.
Practical Workarounds for Accurate Repository Synchronization
While GitHub addresses this bug, several workarounds can help ensure your systems capture all repository updates:
- Don't Rely on `since` Alone; Filter Client-Side by `pushed_at`: Instead of using the
sinceparameter, fetch all user repositories (using pagination if necessary) and then filter the results on your end using therepo.pushed_atfield. This timestamp updates on any push to any branch.GET /users/{username}/repos?type=all&per_page=100 - Leverage Webhooks for Real-time Updates: For critical sync systems, subscribing to
pushandcreate(for new branches) events via webhooks provides real-time coverage of all branch activity, offering the most immediate and accurate updates. - Utilize the GraphQL API with `pushedAt`: The GraphQL API offers a more granular filtering option with its
pushedAtfield, which accurately reflects activity across all branches.{ user(login: "username") { repos(first: 100, orderBy: {field: PUSHED_AT, direction: DESC}) { nodes { name pushedAt } } }}
Next Steps for GitHub and the Community
This behavior should be formally recognized as a bug rather than a feature request. The API documentation needs to either be updated to explicitly state that since only considers default branch activity, or, ideally, the API's behavior should be fixed to account for all repository updates. For users, opening support tickets referencing this discussion can add weight to the request for a fix, emphasizing how this limitation causes silent data loss for critical sync tools and impacts the accuracy of software development project plan tracking.
