首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用octokit.net库更新github中的子模块提交沙

使用octokit.net库更新github中的子模块提交沙
EN

Stack Overflow用户
提问于 2017-06-26 05:17:52
回答 1查看 922关注 0票数 1

当另一个项目更改了某些文件时,我正在尝试自动更新子模块的提交id。我有一个.net网络钩子,我正在使用octokit.net库。

我可以在github文档(https://developer.github.com/v3/git/trees/#create-a-tree)中看到,在创建一个允许您添加提交和路径的新树时,有一个子模块选项,但我无法让它工作。Octokit还为NewTreeItem/TreeItem对象提供了子模块类型,但没有示例或文档。

我的当前代码就在这里--目前我把提交沙作为sha参数传递,但是我可以看到这是错误的,我需要在回购上创建一个commit并使用它,只是在树创建之前我不知道如何去做,也没有任何文档可以找到:

代码语言:javascript
复制
    public static async Task UpdateSubmoduleInBranch(string repo, string branchName, string submodulePath, string sha, string commitComment, GitHubClient github = null)
    {
        //hoping this will update the sha of a submodule

        // url encode branch name for github operations
        branchName = HttpUtility.UrlEncode(branchName);

        if (github == null) github = GetClient();

        var repoId = (await github.Repository.Get(Settings.GitHub.OrgName, repo)).Id;

        RepositoriesClient rClient = new RepositoriesClient(new ApiConnection(github.Connection));

        var branch = await rClient.Branch.Get(repoId, branchName);

        var tree = await github.Git.Tree.Get(repoId, branchName);

        var newTree = new NewTree { BaseTree = tree.Sha };
        newTree.Tree.Add(new NewTreeItem
        {
            Mode = Octokit.FileMode.Submodule,
            Path = submodulePath,
            Type = TreeType.Commit,
            Sha = sha
        });

        var createdTree = await github.Git.Tree.Create(repoId, newTree);

        var newCommit = new NewCommit(commitComment, createdTree.Sha, new[] { branch.Commit.Sha });
        newCommit.Committer = Settings.GitHub.Committer;

        var createdCommit = await github.Git.Commit.Create(Settings.GitHub.OrgName, Settings.GitHub.AppName, newCommit);

        var updateRef = new ReferenceUpdate(createdCommit.Sha, false);
        await github.Git.Reference.Update(repoId, "heads/" + branchName, updateRef);
    }

编辑

如果其他人正在寻找这一点,我解决了这个问题-- octokit api不支持这个操作,即使它看起来是这样的。

除了在PatchAsync中找到的带有Windows.Web.Http.HttpClient类的补丁异步请求方法之外,下面的代码也适用于我:

代码语言:javascript
复制
    public static async Task UpdateSubmoduleInBranch(string repo, string branchName, string submodulePath, string sha, string commitComment)
    {
        using (var client = new HttpClient())
        {
            try
            {
                //these headers authenticate with github, useragent is required.
                client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/vnd.github.v3+json"));
                client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", Settings.GitHub.AuthToken);
                client.DefaultRequestHeaders.UserAgent.Add(new ProductInfoHeaderValue("mathspathway-environment-manager", "v1.0"));

                var committer = Settings.GitHub.Committer;

                //get the branch, and collect the sha of the current commit
                var branchResponse = await client.GetAsync($"{Settings.GitHub.ApiUrl}/repos/{Settings.GitHub.OrgName}/{repo}/branches/{branchName}");
                JToken branchResult = JToken.Parse(await branchResponse.Content.ReadAsStringAsync());
                var currentCommitSha = branchResult["commit"].Value<string>("sha");

                //create the new tree, with the mode of 160000 (submodule mode) and type of commit, and the sha of the other 
                //repository's commit that you want to update the submodule to, and the base tree of the current commit on this repo
                var newTreeObj = new
                {
                    base_tree = currentCommitSha,
                    tree = new List<Object> { new { path = submodulePath, mode= "160000", type = "commit", sha = sha}
            }
                };

                HttpContent treeHttpContent = new StringContent(JsonConvert.SerializeObject(newTreeObj));
                var treeResponse = await client.PostAsync($"{Settings.GitHub.ApiUrl}/repos/{Settings.GitHub.OrgName}/{repo}/git/trees", treeHttpContent);
                var treeResponseContent = JToken.Parse(await treeResponse.Content.ReadAsStringAsync());
                var treeSha = treeResponseContent.Value<string>("sha");


                //Create a new commit based on the tree we just created, with the parent of the current commit on the branch
                var newCommitObj = new
                {
                    message = commitComment,
                    author = new { name = committer.Name, email = committer.Email, date = committer.Date },
                    parents = new[] { currentCommitSha },
                    tree = treeSha
                };
                HttpContent newCommitContent = new StringContent(JsonConvert.SerializeObject(newCommitObj));
                var commitResponse = await client.PostAsync($"{Settings.GitHub.ApiUrl}/repos/{Settings.GitHub.OrgName}/{repo}/git/commits", newCommitContent);
                var commitResponseContent = JToken.Parse(await commitResponse.Content.ReadAsStringAsync());
                var commitSha = commitResponseContent.Value<string>("sha");



                //create an update reference object, and update the branch's head commit reference to the new commit
                var updateRefObject = new { sha = commitSha, force = false };
                HttpContent updateRefContent = new StringContent(JsonConvert.SerializeObject(updateRefObject));
                var updateRefResponse = await client.PatchAsync($"{Settings.GitHub.ApiUrl}/repos/{Settings.GitHub.OrgName}/{repo}/git/refs/heads/{branchName}", updateRefContent);

            } catch (Exception ex)
            {
                Debug.WriteLine($"Error occurred updating submodule: {ex.Message}{Environment.NewLine}{Environment.NewLine}{ex.StackTrace}");
            }
        }
    }
EN

回答 1

Stack Overflow用户

发布于 2017-08-05 22:02:13

虽然试图实现大致相同的目标,但通过一个单独的用户提交一个拉请求,我给您的原始代码尝试了一些小的改变。其结果是它与Octokit.net完美地工作在一起。

提取样本码

代码语言:javascript
复制
var submoduleRepoId = (await gitHubClient.Repository.Get(submoduleRepoOwnerName, submoduleRepoName)).Id;
var submoduleRepoBranchLatestSha = (await gitHubClient.Git.Tree.Get(submoduleRepoId, submoduleRepoBranchName)).Sha;
…
var updateParentTree = new NewTree { BaseTree = parentRepoBranchLatestSha };
updateParentTree.Tree.Add(new NewTreeItem
{
    Mode = FileMode.Submodule,
    Sha = submoduleRepoBranchLatestSha,
    Path = pathToSubmoduleInParentRepo,
    Type = TreeType.Commit,
});
var newParentTree = await gitHubClient.Git.Tree.Create(pullRequestOwnerForkRepoId, updateParentTree);
var commitMessage = $"Bump to {submoduleOwnerName}/{submoduleRepoName}@{submoduleCommitHash}";
var newCommit = new NewCommit(commitMessage, newParentTree.Sha, parentBranchLatestSha);
var pullRequestBranchRef = $"heads/{pullRequestBranchName}";
var commit = await gitHubClient.Git.Commit.Create(pullRequestOwnerName, parentRepoName, newCommit);
var await gitHubClient.Git.Reference.Update(pullRequestOwnerForkRepoId, pullRequestBranchRef, new ReferenceUpdate(commit.Sha));

全样本代码

在这一点上,我只能看到一些潜在的差异。

  • 我绝对不HttpUtility.UrlEncode我的分支名称(Octokit必须为我做任何必要的编码)
  • 我要在他们自己的分叉上建立一个独立的用户分支

这可能是因为这些差异已经足够了,或者是当你尝试同样的事情时,已经发现了一个bug。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/44753494

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档