我正在尝试使用VSTS gitItem库编辑一个文件( NET6 )。我总是得到以下错误。
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。我让项目首先编辑,以确保它存在一个get它的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;
}
}
}发布于 2022-11-28 17:51:56
好吧,我想现在已经解决了。这个问题出现在GitRefUpdate.OldObjectId上。我当时使用的是GitItem id,现在我看到它真的没有任何意义。
GitRefUpdate.OldObjectId必须与GitRef.OldObjectId相匹配。
GitRef defaultBranch = gitClient.GetRefsAsync(gitRepository.Id,filter: branchName).Result.First();
此外,在获取gitItems时,路径和项名称不区分大小写。当推送更改时,'GitItem.Path‘是区分大小写的。要注意这一点。
从这里学到的一切:Azure DevOps library samples
https://stackoverflow.com/questions/74566439
复制相似问题