我正在尝试使用VSTS NET6库编辑一个文件(gitItem)。我总是得到以下错误。
Microsoft.VisualStudio.Services.Common.VssServiceException: TF401028: The reference 'refs/heads/workbench' has already been updated by another client, so you cannot update it. Please try again.
不管我是否创建和使用其他分支,错误都是一样的。这是我的例程代码。我相信我遗漏了一些东西,但真的不知道可能是什么。
主方法是SaveConfigurationFileRepository。我首先获取要编辑的项,以确保它存在并获取其objectId。我使用changeType = edit,因为我想更新现有项的内容。如果代码太长,请原谅。
using Microsoft.Extensions.Configuration;
using Microsoft.TeamFoundation.SourceControl.WebApi;
using Microsoft.VisualStudio.Services.Common;
using Microsoft.VisualStudio.Services.WebApi;
namespace ConfigurationManager.API.Infrastructure.FileSystem.Context
{
public class InfrastructureFileContext : IInfrastructureFileContext
{
public static FileContextConfiguration? contextConfiguration { get; private set; }
public string Url { get; set; }
public string ProjctName { get; set; }
public string RepositoryName { get; set; }
public string WorkingFolder { get; set; }
public InfrastructureFileContext(IConfiguration configuration)
{
contextConfiguration = configuration.GetSection(FileContextConfiguration.SectionName).Get<FileContextConfiguration>();
}
public async Task<int> SaveConfigurationFileRepository(string groupName, string appName, string fileName, string fileContent)
{
// Create instance of VssConnection using Azure AD Credentials for Azure AD backed account
VssConnection connection = new(new Uri(contextConfiguration?.Url), new VssBasicCredential("", contextConfiguration?.AppToken));
// Get a GitHttpClient to talk to the Git endpoints
using (GitHttpClient gitClient = connection.GetClient<GitHttpClient>())
{
// Get data about a specific repository
var gitRepository = gitClient.GetRepositoryAsync(contextConfiguration?.ProjectName, contextConfiguration?.RepositoryName).Result;
GitVersionDescriptor gitDes = new GitVersionDescriptor() { Version = "workbench" };
// Get Item to edit
var gitItemToEdit = gitClient.GetItemAsync(gitRepository.Id, $"{groupName}/{appName}/{fileName}", versionDescriptor: gitDes, includeContent: true).Result;
if (gitItemToEdit is not null)
{
//Create commit objet
GitCommitRef newCommit = GetCommitForFile(gitItemToEdit, $"{groupName}/{appName}/{fileName}", fileContent);
//Create refUpdate using gitItem.ObjectId
GitRefUpdate refUpdate = new()
{
RepositoryId = gitRepository.Id,
Name = "refs/heads/workbench",
OldObjectId = gitItemToEdit.ObjectId
};
GitPush gitChangesToPush = new GitPush()
{
RefUpdates = new GitRefUpdate[] { refUpdate },
Commits = new GitCommitRef[] { newCommit }
};
var gitPush = await gitClient.CreatePushAsync(gitChangesToPush, gitRepository.Id);
return gitPush.PushId;
}
}
return 0;
}
private GitCommitRef GetCommitForFile(GitItem gitItemToEdit, string fileName, string content)
{
//Generate Git Commit
GitCommitRef newCommit = new GitCommitRef
{
Comment = "Update configuration template",
Changes = new GitChange[]
{
new GitChange
{
//Also have tried to use Item = gitItemToEdit
ChangeType = VersionControlChangeType.Edit,
Item = new GitItem { Path = $"{fileName}" },
NewContent = new ItemContent
{
Content = content,
ContentType = ItemContentType.RawText
}
}
}
};
return newCommit;
}
}
}
1条答案
按热度按时间mrfwxfqh1#
好的,我想现在已经解决了。这个问题是在GitRefUpdate. OldObjectId上。我使用的是GitItem id,现在我发现它真的没有任何意义。
GitRefUpdate.OldObjectId必须与GitRef. OldObjectId相符。
GitRef默认分支= gitClient.GetRefsAsync(gitRepository.Id,过滤器:branchName).结果.第一个();
另外,当获取gitItems时,路径和项目名称是不区分大小写的。当推送更改时,'GitItem.Path'是区分大小写的。请注意。
一切都是从这里学到的:Azure DevOps library samples