Commit ddf22f7e authored by Jan Beckmann's avatar Jan Beckmann

Support path parameter for repository download via API

This adds support for only downloading parts of a repository using the API.

Changelog: added

Closes https://gitlab.com/gitlab-org/gitlab/-/issues/28827
parent 4fc19f2b
......@@ -126,6 +126,7 @@ Supported attributes:
## Get file archive
> Support for [including Git LFS blobs](../topics/git/lfs/index.md#lfs-objects-in-project-archives) was [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/15079) in GitLab 13.5.
> Support for downloading a subfolder was [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/28827) in GitLab 14.4.
Get an archive of the repository. This endpoint can be accessed without
authentication if the repository is publicly accessible.
......@@ -147,11 +148,12 @@ Supported attributes:
|:------------|:---------------|:---------|:----------------------|
| `id` | integer/string | yes | The ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user. |
| `sha` | string | no | The commit SHA to download. A tag, branch reference, or SHA can be used. This defaults to the tip of the default branch if not specified. |
| `path` | string | no | The subpath of the repository to download. This defaults to the whole repository (empty string). |
Example request:
```shell
curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.com/api/v4/projects/<project_id>/repository/archive?sha=<commit_sha>"
curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.com/api/v4/projects/<project_id>/repository/archive?sha=<commit_sha>&path=<path>"
```
## Compare branches, tags or commits
......
......@@ -101,6 +101,7 @@ module API
params do
optional :sha, type: String, desc: 'The commit sha of the archive to be downloaded'
optional :format, type: String, desc: 'The archive format'
optional :path, type: String, desc: 'Subfolder of the repository to be downloaded'
end
get ':id/repository/archive', requirements: { format: Gitlab::PathRegex.archive_formats_regex } do
if archive_rate_limit_reached?(current_user, user_project)
......@@ -109,7 +110,7 @@ module API
not_acceptable! if Gitlab::HotlinkingDetector.intercept_hotlinking?(request)
send_git_archive user_project.repository, ref: params[:sha], format: params[:format], append_sha: true
send_git_archive user_project.repository, ref: params[:sha], format: params[:format], append_sha: true, path: params[:path]
rescue StandardError
not_found!('File')
end
......
......@@ -305,6 +305,18 @@ RSpec.describe API::Repositories do
end
end
it 'returns only a part of the repository with path set' do
path = 'bar'
get api("#{route}?path=#{path}", current_user)
expect(response).to have_gitlab_http_status(:ok)
type, params = workhorse_send_data
expect(type).to eq('git-archive')
expect(params['ArchivePath']).to match(/#{project.path}\-[^\.]+\-#{path}\.tar.gz/)
end
it 'rate limits user when thresholds hit' do
allow(::Gitlab::ApplicationRateLimiter).to receive(:throttled?).and_return(true)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment