【问题标题】:Trying to download a file from an Azure DevOps Git repo using Powershell尝试使用 Powershell 从 Azure DevOps Git 存储库下载文件
【发布时间】:2021-07-20 04:46:52
【问题描述】:

所以我在 Azure DevOps 中有一个 Git 存储库,其 URL 类似于

https://[$server]/tfs/[$company]/[$project]/_git/[$repoName]

我可以通过附加如下内容来访问该存储库中的单个文件:

?path=/[$folder]/[$fileName]

我正在尝试使用 Powershell 将特定文件从此 repo 下载到我计算机上的相应位置和文件名,如下所示:

$sourcePath = "https://[$server]/tfs/[$company]/[$project]/_git/[$repoName]?path=/[$folder]/[$fileName]&download=true"
$filePath = "C:\Documents\[$folder]\[$fileName]"
Invoke-RestMethod -Uri $sourcePath -Method Get -Headers @{Authorization=("Basic {0}" -f [$AuthInfo])} -OutFile $filePath

这样做不是用 repo 中的文件替换本地文件,而是用响应正文的内容替换本地文件的内容。我觉得奇怪的是,我一直在做的所有谷歌搜索都说要这样做,尽管 Microsoft article on Invoke-RestMethod 实际上解释说这是 -OutFile 所做的。

注意我也试过Invoke-WebRequest....同样的事情。

那么如何将实际文件从 repo 下载到我想要的本地目标(或将本地目标文件的内容替换为 repo 文件的内容)?

另外,有没有办法指定从哪个分支获取文件?也许我也应该以某种方式使用 Git powershell 命令?我所做的关于从 git repo 下载的所有其他谷歌搜索都提供了关于 GitHub 的结果。

谢谢!

【问题讨论】:

  • 这是 git 解决方案,但我也很想看看如何在 powershell 中执行它-stackoverflow.com/questions/28375418/…
  • 是的,@OwlsSleeping - 这不仅是 Git 的方式,而且看起来是将文件下载到克隆存储库的位置,而不是指定下载位置(我需要能够做到)。谢谢!
  • 这不是真正的 Git 东西。 Git 是关于存储库中包含的提交的全部内容。提交 hold 文件的事实(每个提交部分是每个文件的存档)在这里很有用,但是 get 一个文件 from 的方法具有 Git 存储库的服务器上的提交取决于该服务器。这就是为什么你找到了所有那些 GitHub 特定的答案。您需要 Azure 特定的答案。

标签: git powershell azure-devops


【解决方案1】:

将其余的 api 与以下模板一起使用:

GET https://{tfs_url}/{collection_name}/{project}/_apis/git/repositories/{repositoryId}/items?path={path}

查看文档:Items - GetExample - Download

我使用以下代码在构建管道中复制文件(使用System.Net.WebClient):

$user = ""
$token = $env:SYSTEM_ACCESSTOKEN
$teamProject = $env:SYSTEM_TEAMPROJECT
$orgUrl = $env:SYSTEM_COLLECTIONURI
$repoName = "REPO_NAME"

$base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $user,$token)))

    function InvokeGetFileRequest ($GitFilePath, $OutFilePath)
    {
        Write-Host "Download file" $GitFilePath "to" $OutFilePath
     
        $uriGetFile = "$orgUrl/$teamProject/_apis/git/repositories/$repoName/items?scopePath=$GitFilePath&download=true&api-version=6.1-preview.1"
    
       Write-Host "Url:" $uriGetFile
    
        $wc = New-Object System.Net.WebClient
        $wc.Headers["Authorization"] = "Basic {0}" -f $base64AuthInfo
        $wc.Headers["Content-Type"] = "application/json";
        $wc.DownloadFile($uriGetFile, $OutFilePath)
    }

【讨论】:

  • 嗯...不幸的是,这是在做同样的事情——本地文件的内容被请求的内容所取代。不过,谢谢!
  • 难道真的只是因为我的回购位于“tfs”网址中,而不是您的示例中的那种“储存库”网址吗?就像即使它们在技术上都是 Azure DevOps,但它们在这样的事情上表现不同??
  • @Andy For TFS 应该是相同的$tfs_coolection_url/$team_project_name/_apis/git/repositories/$repoName/items?scopePath=$GitFilePath&download=true&api-version=5.0。检查支持您的 TFS 的 API 版本:docs.microsoft.com/en-us/rest/api/azure/devops/…
  • 所以问题实际上出在我使用的 URL 上,你提示了我。而不是“https://[$server]/tfs/[$company]/[$project]/_git/[$repoName]?path=/[$folder]/[$fileName]”,我将其更改为“ https://[$server]/tfs/[$company]/[$project]/_apis/git/repositories/[$repoName]/items?path=/[$folder]/[$fileName]”。那行得通!如果您想更新答案以指定 URL 的差异,我会将其标记为答案。谢谢!!
【解决方案2】:

我需要这样做,但我在这里看到的没有用,所以我自己写了:

param( 
    [Parameter(Mandatory=$true)] 
    [string] $GitFilePath,
    [Parameter(Mandatory=$true)] 
    [string] $OutFilePath,
    [Parameter(Mandatory=$true)] 
    [string] $RepoName,
    [string] $token,
    [string] $orgUrl,
    [string] $teamProject
)

if([String]::IsNullOrEmpty($token))
{
    if($env:SYSTEM_ACCESSTOKEN -eq $null)
    {
        Write-Error "you must either pass the -token parameter or use the BUILD_TOKEN environment variable"
        exit 1;
    }
    else
    {
        $token = $env:SYSTEM_ACCESSTOKEN;
    }
}


if([string]::IsNullOrEmpty($teamProject)){
    if($env:SYSTEM_TEAMPROJECT -eq $null)
    {
        Write-Error "you must either pass the -teampProject parameter or use the SYSTEM_TEAMPROJECT environment variable"
        exit 1;
    }
    else
    {
        $teamProject = $env:SYSTEM_TEAMPROJECT
    }
}

if([string]::IsNullOrEmpty($orgUrl)){
    if($env:SYSTEM_COLLECTIONURI -eq $null)
    {
        Write-Error "you must either pass the -orgUrl parameter or use the SYSTEM_COLLECTIONURI environment variable"
        exit 1;
    }
    else
    {
        $teamProject = $env:SYSTEM_COLLECTIONURI
    }
}

# Base64-encodes the Personal Access Token (PAT) appropriately  
$User='' 
$base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $User,$token)));  
$header = @{Authorization=("Basic {0}" -f $base64AuthInfo)};  
#---------------------------------------------------------------------- 

Write-Host "Download file" $GitFilePath "to" $OutFilePath
     
$uriGetFile = "$orgUrl/$teamProject/_apis/git/repositories/$repoName/items?scopePath=$GitFilePath&download=true&api-version=6.1-preview.1"
    
Write-Host "Url:" $uriGetFile
    
$filecontent = Invoke-RestMethod -ContentType "application/json" -UseBasicParsing -Headers $header -Uri $uriGetFile
$filecontent | Out-File -Encoding utf8 $OutFilePath

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-03-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-09
    • 2021-05-22
    • 1970-01-01
    相关资源
    最近更新 更多