导入 Git 存储库

Azure DevOps Services | Azure DevOps Server 2022 - Azure DevOps Server 2019

本文介绍如何将现有 Git 存储库从 GitHub、Bitbucket、GitLab 或其他位置导入 Azure DevOps 项目中的新存储库或现有空存储库。

先决条件

类别 要求
项目访问权限 项目的成员。
权限 - 查看私有项目中的代码:至少要具有基本访问权限。
- 克隆或贡献专用项目中的代码:必须是参与者安全组的成员或者具有项目中的相应权限。
- 设置分支或存储库权限:管理分支或存储库的权限 权限。
- 更改默认分支:对存储库具有编辑策略权限。
- 导入存储库:必须是项目管理员安全组的成员,或者将 Git 项目级别创建存储库权限设置为允许。 有关详细信息,请参阅设置 Git 存储库权限
服务 已启用存储库
工具 可选。 使用 az repos 命令:Azure DevOps CLI

注意

在公共项目中,具有 利益干系人 访问权限的用户具有对 Azure Repos 的完全访问权限,包括查看、克隆和参与代码。

类别 要求
项目访问权限 项目的成员。
权限 - 查看代码:至少需要具有基本访问权限。
- 克隆或贡献代码:贡献者安全组的成员或项目中的相应权限。
服务 已启用存储库

注意

完成存储库导入后,Azure DevOps 将为该导入的存储库设置默认分支。 如果导入的存储库包含一 main个名为的分支,则会将其设置为默认分支,否则导入存储库的第一个分支(按字母顺序)设置为 Default

导入到新存储库

  1. 依次选择存储库文件

    查看分支

  2. 在存储库下拉列表中,选择“导入存储库”。

    管理存储库

  3. 如果源存储库公开可用,只需输入源存储库的克隆 URL 和新 Git 存储库的名称。

    如果源存储库是专用存储库,但可以使用基本身份验证(用户名-密码、个人访问令牌等)进行访问,请选择“需要授权”并输入凭据。 不支持 SSH 身份验证,但可以按照 Git CLI 手动导入存储库中的步骤,手动导入使用 SSH 身份验证的存储库。

    导入存储库对话框

::: moniker-end

导入到现有空存储库

在空 Git 存储库的“文件”页上,选择“导入”并输入克隆 URL。 如果源存储库需要身份验证,请提供凭据。

将存储库导入到现有存储库

注意

导入功能禁用提交注释中提到的工作项的自动链接,因为目标项目中的工作项 ID 可能与源项目中的工作项 ID 不同。 可以通过导航到“设置”、“版本控制”,选择存储库并选择“选项”来重新启用提交中提到的工作项的自动链接。 有关将提交与工作项链接的详细信息,请参阅将工作项链接到提交

使用 az repos CLI 手动导入存储库

可以使用 az repos import 将存储库导入 Azure DevOps 项目。

注意

必须先在 Azure DevOps 中创建存储库,然后才能导入 Git 存储库。 此外,创建的存储库必须为空。 若要创建存储库,请参阅在 Azure Repos 中创建 Git 存储库

az repos import create --git-source-url
                       [--detect {false, true}]
                       [--git-service-endpoint-id]
                       [--org]
                       [--project]
                       [--repository]
                       [--requires-authorization]
                       [--subscription]
                       [--user-name]

参数

参数 说明
git-source-url 必填。 要导入的源 git 存储库的 URL。
detect 可选。 自动检测组织结构。 接受的值:falsetrue
git-service-endpoint-id 可选。 用于连接到外部终结点的服务终结点。
org, organization Azure DevOps 组织 URL。 可以使用 az devops configure -d organization=<ORG_URL> 配置默认组织。 如果未配置为默认或未通过 git 配置选取,则为必需。示例:https://dev.azure.com/MyOrganizationName/
project, p 项目的名称或 ID。 可以使用 az devops configure -d project=<NAME_OR_ID> 配置默认项目。 如果未配置为默认或通过 git 配置进行选取,则为必需
repository 要在其中创建导入请求的存储库的名称或 ID。
requires-authorization 指示源 git 存储库是否为专用存储库的标志。 如果需要身份验证,则在源存储库上生成身份验证令牌,并将环境变量 AZURE_DEVOPS_EXT_GIT_SOURCE_PASSWORD_OR_PAT 设置为该令牌的值。 然后,导入请求包括身份验证。
subscription 订阅的名称或 ID。 可以使用 az account set -s <NAME_OR_ID> 配置默认订阅。
user-name 指定用于访问私人 git 存储库的用户名。

示例

以下命令将公共存储库 fabrikam-open-source 导入到空的 Git 存储库 fabrikam-open-source 以用于默认配置

az repos import create --git-source-url https://github.com/fabrikamprime/fabrikam-open-source --repository fabrikam-open-source
{
  "detailedStatus": {
    "allSteps": [
      "Processing request",
      "Analyzing repository objects",
      "Storing objects",
      "Storing index file",
      "Updating references",
      "Import completed successfully"
    ],
    "currentStep": 6,
    "errorMessage": null
  },
  "importRequestId": 8,
  "parameters": {
    "deleteServiceEndpointAfterImportIsDone": null,
    "gitSource": {
      "overwrite": false,
      "url": "https://github.com/fabrikamprime/fabrikam-open-source"
    },
    "serviceEndpointId": null,
    "tfvcSource": null
  },
  "repository": {
    "defaultBranch": null,
    "id": "0f6919cd-a4db-4f34-a73f-2354114a66c4",
    "isDisabled": false,
    "isFork": null,
    "name": "new-empty-repo",
    "parentRepository": null,
    "project": {
      "abbreviation": null,
      "defaultTeamImageUrl": null,
      "description": "Guidance and source control to foster a vibrant ecosystem for Fabrikam Fiber applications and extensions.",
      "id": "56af920d-393b-4236-9a07-24439ccaa85c",
      "lastUpdateTime": "2021-05-24T21:52:14.95Z",
      "name": "Fabrikam Fiber",
      "revision": 438023732,
      "state": "wellFormed",
      "url": "https://dev.azure.com/fabrikamprime/_apis/projects/56af920d-393b-4236-9a07-24439ccaa85c",
      "visibility": "private"
    },
    "remoteUrl": "https://fabrikamprime@dev.azure.com/fabrikamprime/Fabrikam%20Fiber/_git/fabrikam-open-source",
    "size": 12477,
    "sshUrl": "git@ssh.dev.azure.com:v3/kelliott/Fabrikam%20Fiber/new-empty-repo",
    "url": "https://dev.azure.com/fabrikamprime/56af920d-393b-4236-9a07-24439ccaa85c/_apis/git/repositories/0f6919cd-a4db-4f34-a73f-2354114a66c4",
    "validRemoteUrls": null,
    "webUrl": "https://dev.azure.com/fabrikamprime/Fabrikam%20Fiber/_git/fabrikam-open-source"
  },
  "status": "completed",
  "url": "https://dev.azure.com/fabrikamprime/Fabrikam%20Fiber/_apis/git/repositories/0f6919cd-a4db-4f34-a73f-2354114a66c4/importRequests/8"
}

使用 git CLI 手动导入存储库

2017 Update 1 中引入了导入存储库功能。 还可以按照以下步骤将存储库手动导入到 Azure DevOps Services 存储库中,将“TFS”替换为 Azure Repos。

  1. 使用 bare 选项将源存储库克隆到计算机上的临时文件夹,如以下命令行示例所示,然后导航到存储库的文件夹。 使用 bare 选项进行克隆时,文件夹名称包含 .git 后缀。 在此示例中,https://github.com/contoso/old-contoso-repo.git 是要手动导入的源存储库。

    git clone --bare https://github.com/contoso/old-contoso-repo.git
    cd old-contoso-repo.git
    
  2. 创建目标存储库 并记下克隆 URL。 在此示例中,https://dev.azure.com/contoso-ltd/MyFirstProject/_git/new-contoso-repo 是新目标存储库的 URL。

  3. 运行以下命令,将源存储库复制到目标存储库。

    git push --mirror https://dev.azure.com/contoso-ltd/MyFirstProject/_git/new-contoso-repo
    

    警告

    使用 --mirror 会覆盖目标存储库中的所有分支,包括删除目标存储库中任何不在源存储库中的分支。

  4. 如果源存储库包含 LFS 对象,则提取这些对象,并将其从源存储库复制到目标存储库。

    git lfs fetch origin --all
    git lfs push --all https://dev.azure.com/contoso-ltd/MyFirstProject/_git/new-contoso-repo
    
  5. 通过运行以下命令删除临时文件夹。

    cd ..
    rm -rf old-contoso-repo.git
    

常见问题 (FAQ)

虽然导入通常成功,但以下条件可能会导致问题。

问:如果源存储库位于双重身份验证后面,该怎么办?

答:导入服务使用 REST API 来验证和触发导入,不能直接使用需要双重身份验证的存储库。 GitHubAzure DevOps Services 等大多数 Git 托管提供程序都支持可以提供给导入服务的个人令牌。

问:如果源存储库不支持multi_ack,该怎么办?

答:导入服务在导入过程中使用 Git 协议的 multi_ack 功能。 如果源存储库不提供此功能,则导入服务可能无法从给定源导入。 创建导入请求时或正在进行导入时,可能会发生此故障。

问:是否可以从以前的版本导入?

答:如果源 Git 存储库位于 TFS 2017 RTM 之前的 TFS 版本中,则导入失败。 这是因为最新的 Azure DevOps 和以前的版本之间存在协定不匹配。

问:是否可以使用基于 MSA 的凭据?

答:遗憾的是,基于 MSA (Microsoft 帐户(以前是 Live ID)的凭据不起作用。 导入服务依赖于基本身份验证来与源存储库通信。 如果使用的用户名/密码不是基本身份验证,身份验证和导入会失败。 检查使用的用户名/密码是否为基本身份验证的一种方法是尝试使用 Git 使用以下格式克隆存储库

git clone https://<<username>>:<<password>>@<<remaining clone Url>>

问:是否可以从 TFVC 导入?

答:可以将代码从现有 TFVC 存储库迁移到同一帐户中的新 Git 存储库。 迁移到 Git 虽然有许多好处,但对于大型 TFVC 存储库和团队而言,这是一个复杂的过程。 TFVC 等集中式版本控制系统在基本方面与 Git 有所不同。 切换涉及的不仅仅是学习新命令。 这是一项中断性变更,需要仔细规划。 有关详细信息,请参阅从 TFVC 导入到 Git

问:如果源存储库包含 Git LFS 对象,该怎么办?

答:Git 导入不导入 Git LFS 对象。

可以使用以下步骤移动 LFS 对象:

  • 使用导入存储库功能将存储库导入 Azure DevOps。 此作会将源中的所有 Git 对象复制到 Azure DevOps,后者还会导入作为 Git 对象的 LFS 指针,但不会导入 LFS 文件

若要迁移 LFS 文件,您需要将 Git.exe 和 LFS 客户端置于同一环境中,并同时能够访问源存储库和目标存储库。

  • 将导入的存储库从 Azure DevOps 克隆到本地系统。 克隆能够正常完成,但在执行 LFS 文件的签出时失败
  • 将源存储库添加为远程存储库,例如“source”
  • 执行 git lfs fetch source --all,它将源中的所有 LFS 文件引入本地存储库
  • 假设目标 VSTS 存储库是“目标”远程库
  • 执行 git lfs push target --all

问:如果源以后更改,是否可以导入更新?

答:导入服务最初用于导入整个存储库。 若要镜像以后的更改,需要存储库的本地克隆,并将远程库设置为源和目标。

可以使用以下命令同步更改。 我们将 Azure Repos 的导入视为origin,将原始存储库视为upstream

git clone --bare <Azure-Repos-clone-URL>.git
cd <name-of-repo>
git remote add --mirror=fetch upstream <original-repo-URL>
git fetch upstream --tags
git push origin --all

后续步骤