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

查看:60
本文介绍了如何检索和更新文件>在c#中使用Octokit.Net Git Data API从主GitHub到主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?

推荐答案

不是很难,但不是很明显.

Well not hard but not so obvious.

我尝试读取/更新的文件为2.4 Mb,而我能够将该文件压缩至512K(使用SevenZip),这使我可以在回购中读取/更新,我想读取/更新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 Repo中检索现有文件/blob的SHA-1 ID.有了Blob的SHA-1之后,我就可以轻松地通过GIT Data 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 Data API从主GitHub到主GitHub的1MB的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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