【问题标题】:How to sync local changes to a SECOND Git repository?如何将本地更改同步到 SECOND Git 存储库?
【发布时间】:2018-11-28 23:52:06
【问题描述】:

我正在为他拥有源代码的客户项目使用本地 TFS 2018 实例。我希望他能够在我意外不可用时完全访问此代码。

我的建议是创建一个 TFS 发布步骤,将我的 TFS origin 与他的 VSTS 帐户中的存储库同步。

我已经能够从我的工作站手动执行此操作,使用 this approach

cd /path/to/local/repo
git remote add tfs url://tfs/git/repo
git push --mirror tfs

但系统提示我输入他的 VSTS 凭据,这显然在 TFS 发布步骤中不起作用。

另外,我在尝试从 TFS 服务器的桌面remote add 时遇到此错误:

D:\Agent\_work\37\s>git remote add Application https://customer.visualstudio.com/Applications/_git/Application
Rename from 'D:/Agent/_work/37/s/.git/config.lock' to 'D:/Agent/_work/37/s/.git/config' failed. Should I try again? (y/n)

我可以在我的工作站上添加它,尽管它不会显示为可以为 push 提交到 TFS 的更改。所以我似乎无法告诉 TFS 远程 VSTS 存储库。

如何在 TFS 发布步骤中完全自动化此任务?

【问题讨论】:

    标签: git tfs azure-devops


    【解决方案1】:

    我能够使用这些答案的组合来完成这项工作:

    1. https://stackoverflow.com/a/45224858/722393
    2. https://stackoverflow.com/a/50925741/722393

    诀窍是使用个人访问令牌 (PAT),它位于 VSTS 用户配置文件的安全部分。

    这是我最终得到的脚本:

    SyncCode.ps1,从构建步骤调用

    [CmdletBinding()]
    param(
        [Parameter(Mandatory)][string] $Application,
        [Parameter(Mandatory)][string] $LocalPath,
        [Parameter(Mandatory)][string] $Token
    )
    
    . \\SERVER\Scripts\TfsBuild\Invoke-Git.ps1 
    
    $RemoteExists = $false
    $AllRemotes = git remote
    
    ForEach($Remote in $AllRemotes) {
        If($Remote = $Application) {
            $RemoteExists = $true
            Break
        }
    }
    
    If($RemoteExists) {
        Invoke-Git -Command "remote remove $Application"
    }
    
    Invoke-Git -Command "remote add $Application https://Personal%20Access%20Token:$Token@customer.visualstudio.com/Applications/_git/$Application"
    Set-Location $LocalPath
    Invoke-Git -Command "push --mirror HydraMonitor"
    

    Invoke-Git.ps1,从 SyncCode.ps1 调用

    <#
    .Synopsis
        Invoke git, handling its quirky stderr that isn't error
    
    .Outputs
        Git messages, and lastly the exit code
    
    .Example
        Invoke-Git push
    
    .Example
        Invoke-Git "add ."
    #>
    Function Invoke-Git
    {
    param(
    [Parameter(Mandatory)]
    [string] $Command )
    
        Write-Output "##[command]. git $Command"
    
        Try {
            $Exit = 0
            $Path = [System.IO.Path]::GetTempFileName()
    
            Invoke-Expression "git $Command 2> $Path"
    
            $Exit = $LASTEXITCODE
    
            If ( $Exit -gt 0 ) {
                Write-Error (Get-Content $Path).ToString()
            }
            Else {
                Get-Content $Path
            }
    
            "Exit code: $Exit"
        }
        Catch {
            Write-Host "Error: $_`n$($_.ScriptStackTrace)"
        }
        Finally {
            If ( Test-Path $Path ) {
                Remove-Item $Path
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2011-09-16
      • 1970-01-01
      • 2014-10-19
      • 2011-12-30
      • 1970-01-01
      • 2014-01-23
      • 2017-01-15
      • 1970-01-01
      • 2015-03-18
      相关资源
      最近更新 更多