There does not seem to be a way to retrieve all of the actually existing commits in a repository
Summary
There does not seem to be a way to return only real commits in a repository using the commits endpoint. On the one hand, if you simply request the commits you get only the commits on the default branch. On the other hand, if you pass ´?all=true` then you get commits from all branches, including commits that have been deleted.
Steps to reproduce
Create a merge request on a repository, force push a change, and then request all of the commits back via
curl https://$gitlab_url/api/v4/projects/$project_id/repository/commits?all=true
You will find the deleted commits listed there. If you drop the ?all=true
then you do not get the commits on the side branch.
Example Project
Example project: https://gitlab.com/simon.cfr/deleted_commits
What is the current bug behavior?
Consider then
$ curl "https://gitlab.com/api/v4/projects/48531827/repository/commits?all=true" | jq '.[].short_id'
"f5e7dc0e"
"600d756a"
"5a645fb2"
"0d796363"
"f229eaa2"
vs
$ curl "https://gitlab.com/api/v4/projects/48531827/repository/commits?ref_name=foo" | jq '.[].short_id'
"0d796363"
"f5e7dc0e"
Note that several of those commits do not actually exist in the repository; it is not possible to check them out.
What is the expected correct behavior?
There should be a way to request only the commits that actually exist and are possible to check out; in this case I would expect it to be
- 0d796363
- f5e7dc0e
@vyaklushin)
Investigation (byThese commits are kept in special references: refs/merge-requests/*
and refs/keep-around/*
. git log --all
command also picks them and returns in the response.
To solve that we can update Commit API to add a new filter option.
I tested several versions and these two options worked for me:
git log --branches --tags
or
git log --exclude="refs/merge-requests/*" --exclude="refs/keep-around/*" --all