项目导入导出 API
- Tier: Free, Premium, Ultimate
- Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated
使用项目导入导出 API 通过文件传输来导入和导出项目。
在使用项目导入导出 API 之前,你可能需要先使用 组导入导出 API。
在使用项目导入导出 API 之后,你可能需要使用 项目级 CI/CD 变量 API。
你仍需要通过一系列的 Docker 拉取和推送操作来迁移你的 容器镜像仓库。 重新运行任何 CI/CD 管道以获取构建产物。
前置条件
有关项目导入导出 API 的前置条件,请参见:
安排导出
启动新的导出。
该端点还接受一个 upload 哈希参数。它包含将导出的项目上传到 Web 服务器或任何 S3 兼容平台的所有必要信息。对于导出,GitLab:
- 仅支持将二进制数据文件上传到最终服务器。
- 在上传请求中发送
Content-Type: application/gzip头。确保你的预签名 URL 将此包含在签名中。 - 完成项目导出过程可能需要一些时间。确保上传 URL 没有过短的过期时间,并且在导出过程中始终可用。
- 管理员可以修改最大导出文件大小。默认情况下,最大值为无限制(
0)。要更改此设置,请使用以下任一方式编辑max_export_size: - 在 GitLab.com 上,最大导入文件大小有固定限制。有关更多信息,请参阅 账户和限制设置。
如果存在 upload 参数,则 upload[url] 参数是必需的。
对于上传到 Amazon S3,请参阅 为上传对象生成预签名 URL
文档脚本来生成 upload[url]。
由于一个已知问题,你只能将最大 5 GB 的文件上传到 Amazon S3。
POST /projects/:id/export| 属性 | 类型 | 必需 | 描述 |
|---|---|---|---|
id |
integer or string | yes | 项目的 ID 或 URL 编码路径。 |
upload[url] |
string | yes | 上传项目的 URL。 |
description |
string | no | 覆盖项目描述。 |
upload |
hash | no | 包含将导出的项目上传到 Web 服务器信息的哈希。 |
upload[http_method] |
string | no | 上传导出项目的 HTTP 方法。仅允许 PUT 和 POST 方法。默认为 PUT。 |
curl --request POST \
--header "PRIVATE-TOKEN: <your_access_token>" \
--url "https://gitlab.example.com/api/v4/projects/1/export" \
--data "upload[http_method]=PUT" \
--data-urlencode "upload[url]=https://example-bucket.s3.eu-west-3.amazonaws.com/backup?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=<your_access_token>%2F20180312%2Feu-west-3%2Fs3%2Faws4_request&X-Amz-Date=20180312T110328Z&X-Amz-Expires=900&X-Amz-SignedHeaders=host&X-Amz-Signature=8413facb20ff33a49a147a0b4abcff4c8487cc33ee1f7e450c46e8f695569dbd"{
"message": "202 Accepted"
}导出状态
获取导出状态。
GET /projects/:id/export| 属性 | 类型 | 必需 | 描述 |
|---|---|---|---|
id |
integer or string | yes | 项目的 ID 或 URL 编码路径。 |
curl --request GET \
--header "PRIVATE-TOKEN: <your_access_token>" \
--url "https://gitlab.example.com/api/v4/projects/1/export"状态可能是以下之一:
none:没有排队、开始、完成或正在重新生成的导出。queued:已收到导出请求,并在队列中等待处理。started:导出过程已开始并正在进行中。它包括:- 导出过程。
- 对结果文件执行的操作,例如发送邮件通知用户下载文件,或将导出的文件上传到 Web 服务器。
finished:导出过程完成后,用户已收到通知。regeneration_in_progress:导出文件可供下载,并且正在处理生成新导出的请求。
_links 仅在导出完成后存在。
created_at 是项目创建时间戳,不是导出开始时间。
{
"id": 1,
"description": "Itaque perspiciatis minima aspernatur corporis consequatur.",
"name": "Gitlab Test",
"name_with_namespace": "Gitlab Org / Gitlab Test",
"path": "gitlab-test",
"path_with_namespace": "gitlab-org/gitlab-test",
"created_at": "2017-08-29T04:36:44.383Z",
"export_status": "finished",
"_links": {
"api_url": "https://gitlab.example.com/api/v4/projects/1/export/download",
"web_url": "https://gitlab.example.com/gitlab-org/gitlab-test/download_export"
}
}导出下载
下载已完成的导出。
GET /projects/:id/export/download| 属性 | 类型 | 必需 | 描述 |
|---|---|---|---|
id |
integer or string | yes | 项目的 ID 或 URL 编码路径。 |
curl --request GET \
--header "PRIVATE-TOKEN: <your_access_token>" \
--remote-header-name \
--remote-name \
--url "https://gitlab.example.com/api/v4/projects/5/export/download"ls *export.tar.gz
2017-12-05_22-11-148_namespace_project_export.tar.gz导入文件
POST /projects/import| 属性 | 类型 | 必需 | 描述 |
|---|---|---|---|
file |
string | yes | 要上传的文件。 |
path |
string | yes | 新项目的名称和路径。 |
name |
string | no | 要导入的项目名称。如果未提供,默认为项目路径。 |
namespace |
integer or string | no | 要将项目导入到的命名空间的 ID 或路径。默认为当前用户的命名空间。 需要在目标组上至少具有维护者角色才能导入。 |
override_params |
Hash | no | 支持在 项目 API 中定义的所有字段。 |
overwrite |
boolean | no | 如果存在相同路径的项目,导入会覆盖它。默认为 false。 |
传递的覆盖参数优先于导出文件中定义的所有值。
要从你的文件系统上传文件,使用 --form 参数。这会导致
cURL 使用头 Content-Type: multipart/form-data 发布数据。
file= 参数必须指向你文件系统上的文件,并以 @ 开头。例如:
curl --request POST \
--header "PRIVATE-TOKEN: <your_access_token>" \
--form "path=api-project" \
--form "file=@/path/to/file" \
--url "https://gitlab.example.com/api/v4/projects/import"cURL 不支持从远程服务器发布文件。此示例使用 Python 的 open 方法导入项目:
import requests
url = 'https://gitlab.example.com/api/v4/projects/import'
files = { "file": open("project_export.tar.gz", "rb") }
data = {
"path": "example-project",
"namespace": "example-group"
}
headers = {
'Private-Token': "<your_access_token>"
}
requests.post(url, headers=headers, data=data, files=files){
"id": 1,
"description": null,
"name": "api-project",
"name_with_namespace": "Administrator / api-project",
"path": "api-project",
"path_with_namespace": "root/api-project",
"created_at": "2018-02-13T09:05:58.023Z",
"import_status": "scheduled",
"correlation_id": "mezklWso3Za",
"failed_relations": []
}从远程对象存储导入文件
- 状态:Beta
在 GitLab 自托管版中,默认情况下此功能可用。要隐藏此功能,管理员可以 禁用功能标志 import_project_from_remote_file。
在 GitLab.com 和 GitLab Dedicated 中,此功能可用。
POST /projects/remote-import| 属性 | 类型 | 必需 | 描述 |
|---|---|---|---|
path |
string | yes | 新项目的名称和路径。 |
url |
string | yes | 要导入的文件的 URL。 |
name |
string | no | 要导入的项目名称。如果未提供,默认为项目路径。 |
namespace |
integer or string | no | 要将项目导入到的命名空间的 ID 或路径。默认为当前用户的命名空间。 |
overwrite |
boolean | no | 导入时是否覆盖相同路径的项目。默认为 false。 |
override_params |
Hash | no | 支持在 项目 API 中定义的所有字段。 |
传递的覆盖参数优先于导出文件中定义的所有值。
curl --request POST \
--header "PRIVATE-TOKEN: <your_access_token>" \
--header "Content-Type: application/json" \
--url "https://gitlab.example.com/api/v4/projects/remote-import" \
--data '{"url":"https://remoteobject/file?token=123123","path":"remote-project"}'{
"id": 1,
"description": null,
"name": "remote-project",
"name_with_namespace": "Administrator / remote-project",
"path": "remote-project",
"path_with_namespace": "root/remote-project",
"created_at": "2018-02-13T09:05:58.023Z",
"import_status": "scheduled",
"correlation_id": "mezklWso3Za",
"failed_relations": [],
"import_error": null
}Content-Length 头必须返回有效的数字。最大文件大小为 10 GB。
Content-Type 头必须是 application/gzip。
导入单个关系
此端点接受项目导出存档和命名关系(问题、合并请求、管道或里程碑),并重新导入该关系,跳过已导入的项目。
所需的项目导出文件遵循在 导入文件 中描述的相同结构和大小要求。
- 提取的文件必须遵循 GitLab 项目导出的结构。
- 存档不得超过管理员配置的最大导入文件大小。
POST /projects/import-relation| 属性 | 类型 | 必需 | 描述 |
|---|---|---|---|
file |
string | yes | 要上传的文件。 |
path |
string | yes | 新项目的名称和路径。 |
relation |
string | yes | 要导入的关系名称。必须是 issues、milestones、ci_pipelines 或 merge_requests 之一。 |
要从你的文件系统上传文件,使用 --form 选项,这会导致
cURL 使用头 Content-Type: multipart/form-data 发布数据。
file= 参数必须指向你文件系统上的文件,并以 @ 开头。例如:
curl --request POST \
--header "PRIVATE-TOKEN: <your_access_token>" \
--form "path=api-project" \
--form "file=@/path/to/file" \
--form "relation=issues" \
--url "https://gitlab.example.com/api/v4/projects/import-relation"{
"id": 9,
"project_path": "namespace1/project1",
"relation": "issues",
"status": "finished"
}检查关系导入状态
此端点获取与项目关联的任何关系导入的状态。因为 一次只能安排一个关系导入,你可以使用此端点检查前一个导入是否成功完成。
GET /projects/:id/relation-imports| 属性 | 类型 | 必需 | 描述 |
|---|---|---|---|
id |
integer or string | yes | 项目的 ID 或 URL 编码路径。 |
curl --request GET \
--header "PRIVATE-TOKEN: <your_access_token>" \
--url "https://gitlab.example.com/api/v4/projects/18/relation-imports"[
{
"id": 1,
"project_path": "namespace1/project1",
"relation": "issues",
"status": "created",
"created_at": "2024-03-25T11:03:48.074Z",
"updated_at": "2024-03-25T11:03:48.074Z"
}
]状态可能是以下之一:
created:导入已安排,但尚未开始。started:导入正在处理中。finished:导入已完成。failed:导入未能完成。
从 AWS S3 导入文件
POST /projects/remote-import-s3| 属性 | 类型 | 必需 | 描述 |
|---|---|---|---|
access_key_id |
string | yes | AWS S3 访问密钥 ID。 |
bucket_name |
string | yes | AWS S3 存储桶名称,文件存储于此。 |
file_key |
string | yes | AWS S3 文件键,用于标识文件。 |
path |
string | yes | 新项目的完整路径。 |
region |
string | yes | AWS S3 区域名称,文件存储于此。 |
secret_access_key |
string | yes | AWS S3 秘密访问密钥。 |
name |
string | no | 要导入的项目名称。如果未提供,默认为项目路径。 |
namespace |
integer or string | no | 要将项目导入到的命名空间的 ID 或路径。默认为当前用户的命名空间。 |
传递的覆盖参数优先于导出文件中定义的所有值。
curl --request POST \
--url "https://gitlab.example.com/api/v4/projects/remote-import-s3" \
--header "PRIVATE-TOKEN: <your gitlab access key>" \
--header 'Content-Type: application/json' \
--data '{
"name": "Sample Project",
"path": "sample-project",
"region": "<Your S3 region name>",
"bucket_name": "<Your S3 bucket name>",
"file_key": "<Your S3 file key>",
"access_key_id": "<Your AWS access key id>",
"secret_access_key": "<Your AWS secret access key>"
}'此示例使用连接到 Amazon S3 的模块从 Amazon S3 存储桶导入:
import requests
from io import BytesIO
s3_file = requests.get(presigned_url)
url = 'https://gitlab.example.com/api/v4/projects/import'
files = {'file': ('file.tar.gz', BytesIO(s3_file.content))}
data = {
"path": "example-project",
"namespace": "example-group"
}
headers = {
'Private-Token': "<your_access_token>"
}
requests.post(url, headers=headers, data=data, files=files){
"id": 1,
"description": null,
"name": "Sample project",
"name_with_namespace": "Administrator / sample-project",
"path": "sample-project",
"path_with_namespace": "root/sample-project",
"created_at": "2018-02-13T09:05:58.023Z",
"import_status": "scheduled",
"correlation_id": "mezklWso3Za",
"failed_relations": [],
"import_error": null
}导入状态
获取导入状态。
GET /projects/:id/import| 属性 | 类型 | 必需 | 描述 |
|---|---|---|---|
id |
integer or string | yes | 项目的 ID 或 URL 编码路径。 |
curl --request GET \
--header "PRIVATE-TOKEN: <your_access_token>" \
--url "https://gitlab.example.com/api/v4/projects/1/import"状态可能是以下之一:
nonescheduledfailedstartedfinished
如果状态为 failed,它会在 import_error 下包含导入错误消息。
如果状态为 failed、started 或 finished,failed_relations 数组可能会填充由于以下原因导致的关系导入失败:
- 不可恢复的错误。
- 重试次数已耗尽。典型示例:查询超时。
failed_relations 中元素的 id 字段引用的是失败记录,而不是关系。
failed_relations 数组限制为 100 个项目。
{
"id": 1,
"description": "Itaque perspiciatis minima aspernatur corporis consequatur.",
"name": "Gitlab Test",
"name_with_namespace": "Gitlab Org / Gitlab Test",
"path": "gitlab-test",
"path_with_namespace": "gitlab-org/gitlab-test",
"created_at": "2017-08-29T04:36:44.383Z",
"import_status": "started",
"import_type": "github",
"correlation_id": "mezklWso3Za",
"failed_relations": [
{
"id": 42,
"created_at": "2020-04-02T14:48:59.526Z",
"exception_class": "RuntimeError",
"exception_message": "A failure occurred",
"source": "custom error context",
"relation_name": "merge_requests",
"line_number": 0
}
]
}从 GitHub 导入时,stats 字段列出了已从 GitHub 获取的对象数量和已导入的对象数量:
{
"id": 1,
"description": "Itaque perspiciatis minima aspernatur corporis consequatur.",
"name": "Gitlab Test",
"name_with_namespace": "Gitlab Org / Gitlab Test",
"path": "gitlab-test",
"path_with_namespace": "gitlab-org/gitlab-test",
"created_at": "2017-08-29T04:36:44.383Z",
"import_status": "started",
"import_type": "github",
"correlation_id": "mezklWso3Za",
"failed_relations": [
{
"id": 42,
"created_at": "2020-04-02T14:48:59.526Z",
"exception_class": "RuntimeError",
"exception_message": "A failure occurred",
"source": "custom error context",
"relation_name": "merge_requests",
"line_number": 0
}
],
"stats": {
"fetched": {
"diff_note": 19,
"issue": 3,
"label": 1,
"note": 3,
"pull_request": 2,
"pull_request_merged_by": 1,
"pull_request_review": 16
},
"imported": {
"diff_note": 19,
"issue": 3,
"label": 1,
"note": 3,
"pull_request": 2,
"pull_request_merged_by": 1,
"pull_request_review": 16
}
}
}