VSTS级联合并

时间:2018-04-09 22:34:11

标签: git azure-devops

VSTS是否支持级联合并?我们的团队正在寻求从Stash切换到VSTS,但我们广泛使用的功能之一是VSTS似乎不支持的级联合并。

例如,假设我有分支版本Release_1,Release_2和Develop。我从Release_1分支并创建一个拉取请求以将我的分支与Release_1合并。在Stash中,可以使用语义分支名称使其自动与较新的版本和Develop合并。在这种情况下,合并到Release_1将自动触发合并到Release_2和Develop。

这可以在VSTS中设置还是需要某种git钩子?

2 个答案:

答案 0 :(得分:1)

最近,VSTS无法进行级联合并。

但是有一个用户语音Cascading Merge可以为VSTS提供此功能,您可以投票和跟进。

现在的解决方法是使用Web钩子或CI构建顺序合并其他分支,如jessehouwing所述。

答案 1 :(得分:0)

内联Powershell任务

有点在这里犯下我自己的问题,但我想在一段时间之前发布,但只是忘了它。

以下是我最后编写的内联Powershell任务,用于在VSTS的构建步骤中使用。确保"不要同步来源"非常重要。在"获取来源"中检查步。您还应该将CI触发器设置为包含基于语义通配符的分支。在我们的例子中,它是rc / *。您还需要确保"允许脚本访问OAuth令牌"检查。

我想我会在这里发布我的解决方案,万一有人碰巧从Google搜索中发现了这个问题。它绝对不是完美的,并没有真正好的错误处理,但它完成了工作。

# Change the output of the git commands so that the output doesn't cause the builds to fail even when there are no errors.
$env:GIT_REDIRECT_STDERR = '2>&1'

# Flag that gets set to true if a merge has conflicts
$mergeConflict = $false

# Initialize the empty repository
git init

git config --global user.email "buildAgent@nobody.com"
git config --global user.name "BuildAgent"

# Clone the repository
git clone https://buildAgent:$($env:SYSTEM_ACCESSTOKEN)@YOURDOMAINHERE.visualstudio.com/YOUR/REPO/HERE

cd YOURREPOHERE

# Get the branches that we want to cascade merges through
$versionList = git branch -r --list '*/rc/*'

$versionArray = @()

# Fix up the branch names so they are easier to work with
foreach ($branch in $versionList) {
   $versionArray += $branch.Replace('origin/','').Trim()
}

# Add the Sprint branch to the end of the array
$versionArray += 'Sprint'

# Get the branch that triggered the cascade
$currentBranch = $env:BUILD_SOURCEBRANCH

# Fix up the branch name so it is easier to work with
$currentBranch= $currentBranch.Replace('refs/heads/','')

# Checkout the branch that triggered the cascade
git checkout $currentBranch

# Find the branch in our list of branches that we want to cascade through so that we skip any that we don't want to cascade to.
$currentBranchIndex = $versionArray.indexof($currentBranch)

# For each branch in the array checkout the next version and merge the previous version into it. Add ***NO_CI*** to the commit message so that the push to VSTS does not trigger
# another build which would trigger another cascade. If there is a conflict abort otherwise push the branch after merging.
for ($i=$currentBranchIndex; $i -lt $versionArray.length-1; $i++) 
{ 
    git checkout $versionArray[$i+1]; git merge $versionArray[$i] --no-ff -m "Merge $($versionArray[$i]) to $($versionArray[$i+1]) ***NO_CI***"
    if($LastExitCode -ne 0){
      'conflict merging:  ' + $versionArray[$i] + ' into ' + $versionArray[$i+1]
      $mergeConflict = $true
      break
    }
    else{
      git push origin $versionArray[$i+1]
    }
}


# There was a merge conflict. Create a pull request with the appropriate source and target so that we can resolve the merge conflict.
if($mergeConflict){
      $uri = 'https://YOURDOMAINHERE.visualstudio.com/YOURPROJECTHERE/_apis/git/repositories/REPOIDHERE/pullrequests?api-version=4.1'
      $user = "buildAgent"
      $Base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $User,$env:SYSTEM_ACCESSTOKEN)))
      $params = @{"sourceRefName"="refs/heads/$($versionArray[$i])";
                            "targetRefName"="refs/heads/$($versionArray[$i+1])";
                            "title" = "Automatic Merge Failure";
                            "description" = "There was a merge conflict merging $($versionArray[$i]) into $($versionArray[$i+1])";
                          }
    try{
          Invoke-RestMethod -uri $uri -body ($params|ConvertTo-Json) -method 'Post' -contentType "application/json" -Headers @{Authorization=("Basic {0}" -f 
          $Base64AuthInfo)}
     }
    catch{
        $result = $_.Exception.Response.GetResponseStream()
        $reader = New-Object System.IO.StreamReader($result)
        $reader.BaseStream.Position = 0
        $reader.DiscardBufferedData()
        $responseBody = $reader.ReadToEnd();
        $responseBody
    }

    "##vso[task.complete result=Failed;]DONE"
}