如何检索和更新文件 >在 c# 中使用 Octokit.Net Git 数据 API 从/到掌握 GitHub 的 1MB [英] How to retrieve and update a file > 1MB from/to master GitHub using Octokit.Net Git Data API within c#

查看:15
本文介绍了如何检索和更新文件 >在 c# 中使用 Octokit.Net Git 数据 API 从/到掌握 GitHub 的 1MB的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用 Octokit.Net 读取和更新我的存储库中的单个文件.

I am trying to read and update a single file in my repository using Octokit.Net.

我尝试读取/更新的特定文件的大小约为 2.1MB,因此当我尝试使用以下代码读取此文件时...

The particular file I am trying to read/update is about 2.1MB in size so when I attempt to read this file using the following code...

var currentFileText = "";

            var contents = await client.Repository.Content.GetAllContentsByRef("jkears", "NextWare.ProductPortal", "domainModel.ddd", "master");
            var targetFile = contents[0];
            if (targetFile.EncodedContent != null)
            {
                currentFileText = Encoding.UTF8.GetString(Convert.FromBase64String(targetFile.EncodedContent));
            }
            else
            {
                currentFileText = targetFile.Content;
            }

我收到此异常..

Octokit.ForbiddenException
  HResult=0x80131500
  Message=This API returns blobs up to 1 MB in size. The requested blob is too large to fetch via the API, but you can use the Git Data API to request blobs up to 100 MB in size.

我的问题是如何在 c# 中使用 Git Data API 来读取这个大文件的内容,以及如何将对此文件的更改更新回同一个存储库?

My question is how to use Git Data API within c# to read the contents of this large file, and further how would I update changes on this file back into the same repository?

推荐答案

不难但也不那么明显.

我试图读取/更新的文件是 2.4 Mb,虽然我能够将此文件压缩到 512K(使用 SevenZip),这允许我在 repo 上读取/更新我想读取/更新超过 1Mb 的文件.

My file that I was trying to read/update was 2.4 Mb and while I was able to compress this file down to 512K (using SevenZip) which allowed me to read/update on repo I wanted to read/update files over 1Mb.

为了实现这一点,我不得不使用 GitHub 的 GraphQL API.为了检索我有兴趣阅读/更新的特定文件的 SHA1,我需要这样做.

To accomplish this I had to use GitHub's GraphQL API. I required that in order to retrieve the SHA1 for the particular file that I was interested in reading/updating.

从未使用过 Git API 或 GraphQL,我选择使用 GraphQL 客户端(GraphQL.Client 和 GraphQL.Client.Serializer.Newtonsoft).

Having never worked with Git API or for that matter GraphQL I chose to utilize a GraphQL client (GraphQL.Client and GraphQL.Client.Serializer.Newtonsoft).

使用 GraphQL,我能够在我的 GitHub 存储库中检索现有文件/blob 的 SHA-1 id.获得 blob 的 SHA-1 后,我可以轻松地通过 GIT 数据 API 拉取相关文件.

With GraphQL I was able to retrieve the SHA-1 id for the existing file/blob in my GitHub Repo. Once I had the SHA-1 for the blob I was easily able to pull down the file in question via the GIT Data API.

然后我能够更改内容并将更改通过 Octokit.Net 推送回 GitHub.

I was then able to alter the content and push the changes back to GitHub via Octokit.Net.

虽然这并没有以任何方式完善,但我想用一些东西来结束它,供其他尝试这样做的人使用.

While this is not polished by any means, I wanted to close this with something for anyone else who is attempting to do this.

归功于以下 stackover 流线程.

public async Task<string> GetSha1(string owner, string personalToken, string repositoryName,  string pathName, string branch = "master")
        {
            string basicValue = Convert.ToBase64String(Encoding.UTF8.GetBytes($"{owner}:{personalToken}"));

            var graphQLClient = new GraphQLHttpClient("https://api.github.com/graphql", new NewtonsoftJsonSerializer());
            graphQLClient.HttpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", basicValue);

            var getShaRequest = new GraphQLRequest
            {
                Query = @"
                    query {
                      repository(owner: """+owner+@""", name: """+ repositoryName +@""") {
                        object(expression: """ + branch + @":" + pathName +@""") {
                                            ... on Blob {
                                            oid
                                        }
                                    }
                                }
                            }",
                    
                    Variables = new
                    {
                    }
            };

            var graphQLResponse = await graphQLClient.SendQueryAsync<ResponseType>(getShaRequest, cancellationToken: CancellationToken.None);
            return graphQLResponse.Data.Repository.Object.Oid;
        }

这是我的助手类

public class ContentResponseType
        {
            public string content { get; set; }
            public string encoding { get; set; }
            public string url { get; set; }
            public string sha { get; set; }
            public long size { get; set; }
        }

        public class DataObject
        {
            public string Oid;
        }

        public class Repository
        {
            public DataObject Object;
        }

        public class ResponseType
        {
            public Repository Repository { get; set; }
        }

这是使用上述方法提供的 SHA-1 检索内容的文件..

Here is the file that retrieves the content with the SHA-1 as provided to by method above..

 public async Task<ContentResponseType> RetrieveFileAsync(string owner, string personalToken, string repositoryName, string pathName, string branch = "master")
        {
            var sha1 = await this.GetSha1(owner: owner, personalToken: personalToken, repositoryName: repositoryName, pathName: pathName, branch: branch);
            var url = this.GetBlobUrl(owner, repositoryName, sha1);
            var req = this.BuildRequestMessage(url, personalToken);
            using (var httpClient = new HttpClient())
            {
                var resp = await httpClient.SendAsync(req);
                if (resp.StatusCode != System.Net.HttpStatusCode.OK)
                {
                    throw new Exception($"error happens when downloading the {req.RequestUri}, statusCode={resp.StatusCode}");
                }
                using (var ms = new MemoryStream())
                {
                    await resp.Content.CopyToAsync(ms);
                    ms.Seek(0, SeekOrigin.Begin);
                    StreamReader reader = new StreamReader(ms);
                    var jsonString =  reader.ReadToEnd();
                    return System.Text.Json.JsonSerializer.Deserialize<ContentResponseType>(jsonString);
                }
            }
        }

这是我的控制台测试应用...

Here is my console test app...

    static async Task Main(string[] args)
    {

        // GitHub variables
        var owner = "{Put Owner Name here}";
        var personalGitHubToken = "{Put your Token here}";
        var repo = "{Put Repo Name Here}";
        var branch = "master";
        var referencePath = "{Put path and filename here}";

        // Get the existing Domain Model file
        var api = new GitHubRepoApi();
        var response = await api.RetrieveFileAsync(owner:owner, personalToken: personalGitHubToken, repositoryName: repo, pathName: referencePath, branch:branch);
        var currentFileText = Encoding.UTF8.GetString(Convert.FromBase64String(response.content));

        // Change the description of the JSON Domain Model
        currentFileText = currentFileText.Replace(@"""description"":""SubDomain", @"""description"":""Domain");
        
        // Update the changes back to GitHub repo using Octokit
        var client = new GitHubClient(new Octokit.ProductHeaderValue(repo));
        var tokenAuth = new Credentials(personalGitHubToken);
        client.Credentials = tokenAuth;
        
        // Read back the changes to confirm all works
        var updateChangeSet = await client.Repository.Content.UpdateFile(owner, repo, referencePath,
                                    new UpdateFileRequest("Domain Model was updated via automation", currentFileText, response.sha, branch));
         
        response = await api.RetrieveFileAsync(owner: owner, personalToken: personalGitHubToken, repositoryName: repo, pathName: referencePath, branch: branch);
        currentFileText = Encoding.UTF8.GetString(Convert.FromBase64String(response.content));
    }

我确信还有很多其他方法可以实现这一点,但这对我有用,我希望这有助于让其他人的生活更轻松.

I am certain there are many other ways to accomplish this but this is what worked for me and I hope this helps to make someone else's life a bit easier.

干杯约翰

这篇关于如何检索和更新文件 &gt;在 c# 中使用 Octokit.Net Git 数据 API 从/到掌握 GitHub 的 1MB的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆