如何通过 GitHub 的 API 进行挑选
How to cherry-pick through GitHub's API
我在通过 GitHub API 执行 简单 cherry-pick 时遇到问题。这一定是可能的,但我不清楚如何...
我正在使用 C# 为 Slack 开发一个聊天机器人,以帮助管理 Kubernetes 环境和 GitHub 版本,并希望使用 修补程序功能 对其进行扩展。给定一个环境,它应该创建一个与当前版本匹配的分支,并在其中挑选一个或多个提交 SHA,由请求的作者通过 Slack 提供。
所有管道都已就位。使用 POST /repos/:owner/:repo/git/refs
我能够创建与特定版本匹配的分支。这意味着我已经为下一步准备好了 branch name
、commit SHA
和 tree SHA
;挑选一个或多个提交 SHA 到这个分支。使用 POST /repos/:owner/:repo/git/commits
我可以创建一个提交,但我不确定要使用哪个树 and/or 父级 - 这可能会导致我在调用 POST /repos/:owner/:repo/merges
时遇到问题,因为它 returns me status 409 (merge conflict) where locally, 当然没有.
我能找到的唯一真实例子是 https://github.com/tibdex/github-cherry-pick。然而,它并不真正符合我的场景,我很难理解 Git 内部工作原理。
我的场景(从最新到最旧);
* commit E (current state of `master`)
* commit D
* commit C (deployed to environment)
* commit B
* commit A
在这种情况下,我想将提交 E 挑选到提交 C 的新分支中,创建一个我可以发布的集合(A、B、C、E)。
* commit E (current state of `master`)
* commit D
|
| * commit E (new branch, to be deployed)
|/
* commit C (deployed to environment)
* commit B
* commit A
基本上我需要的是这个 bash;
的 GitHub API 版本
git checkout -b {new-branch-name} {sha}
git cherry-pick {sha}
git push main {new-branch-name}
感谢任何帮助!
以下是我如何在 Git 集线器 API 上用伪代码实现 cherry-pick:
// here is a commit, for example, from a pull request:
listOfCommits = GET /repos/$owner/$repo/pulls/$number/commits
commit = listOfCommits.head // the first one in the list
// Here is the branch we want to cherry-pick to:
branch = GET /repos/$owner/$repo/branches/$branchName
branchSha = branch.commit.sha
branchTree = branch.commit.commit.tree.sha
// Create a temporary commit on the branch, which extends as a sibling of
// the commit we want but contains the current tree of the target branch:
parentSha = commit.parents.head // first parent -- there should only be one
tempCommit = POST /repos/$owner/$repo/git/commits { "message": "temp",
"tree": branchTree,
"parents": [parentSha] }
// Now temporarily force the branch over to that commit
PATCH /repos/$owner/$repo/git/refs/heads/$refName { sha = tempCommit.sha,
force = true }
// Merge the commit we want into this mess:
merge = POST /repos/$owner/$repo/merges { "base": branchName
"head": commit.sha }
// and get that tree!
mergeTree = merge.commit.tree.sha
// Now that we know what the tree should be, create the cherry-pick commit.
// Note that branchSha is the original from up at the top.
cherry = POST /repos/$owner/$repo/git/commits { "message": "looks good!",
"tree": mergeTree,
"parents": [branchSha] }
// Replace the temp commit with the real commit:
PATCH /repos/$owner/$repo/git/refs/heads/$refName { sha = cherry.sha,
force = true }
// Done!
Git高手请指教,我相信这样就可以了:
git checkout -b {new-branch-name} {sha}
git cherry-pick {sha}
git push main {new-branch-name}
已接受的答案有效,但不清楚原因。
以下内容摘自我对这个脚本的要点(在 golang 中)的评论:https://gist.github.com/sashamor/7918b3be758759440feb7825547370f9
GitHub 不支持直接使用 API 创建 cherry-pick 提交。
但是,它确实支持在 git 树中创建提交对象。所以,我们将
从第一原则创建一个新的 cherry-pick 提交。
要创建提交,我们需要三样东西:
- 提交信息。
- 父提交。
- 树(也就是这次提交时 repo 中所有对象的状态)。
对于 cherry-pick 提交,这很简单:
- 消息很简单 - 我们使用来自原始提交的消息,加上一个
“从...中精心挑选”页脚。
- 父 SHA 也很简单 - 我们使用我们想要的提交的 SHA
樱桃采摘,延伸树。
- 树是棘手的部分 - 我们需要创建一个新的 git 对象
包含我们希望它们处于的状态的文件,然后使用它。
以下步骤用于创建树 SHA。一旦我们有了它,我们就可以
创建提交。
为了得到树,我们可以使用合并API。目前,GitHub 合并 API
需要两件事:
- 要合并到的分支。
- 我们要合并的提交的 SHA。
乍一看,一个解决方案似乎是使用 merge with:
- 要选择的分支。
- 对 cherry-pick 的承诺。
然而,这有一个警告,所有提交 before cherry-pick
提交,不在要挑选的分支中,包含在
合并。我们不想要这个。为了解决这个问题,我们可以“欺骗”git
包括 cherry-pick 提交,通过(临时)设置
分支到我们想要挑选的提交的父级。这样,当
git 执行合并,它检测到我们正在提交的分支的父级
merging to 匹配我们正在合并的提交的父级,并合并
一棵大小为 1 的树,仅包含 cherry-pick 提交。
要创建这个新的“树尖”提交:
- 消息无关紧要 - 它丢失了。
- 父级是我们要挑选的提交的父级 - 这个
这样,cherry-pick 提交和分支都有相同的父级。
- 这棵树是我们要挑选的树枝。
然后我们创建一个指向这个提交的临时分支,这样我们就可以合并
到它上面。然后我们可以调用 merge with:
- 一个树枝与我们正在挑选的树枝相匹配的树枝,以及一个
父级匹配我们正在挑选的提交的父级。
- 对 cherry-pick 的承诺。
此合并操作的结果提交具有我们需要的树 SHA。
最后,我们可以使用它来创建 cherry-pick 提交。这可以是
根据需要重复多次,新的 cherry-pick 提交是
每次基本分支。
我在通过 GitHub API 执行 简单 cherry-pick 时遇到问题。这一定是可能的,但我不清楚如何...
我正在使用 C# 为 Slack 开发一个聊天机器人,以帮助管理 Kubernetes 环境和 GitHub 版本,并希望使用 修补程序功能 对其进行扩展。给定一个环境,它应该创建一个与当前版本匹配的分支,并在其中挑选一个或多个提交 SHA,由请求的作者通过 Slack 提供。
所有管道都已就位。使用 POST /repos/:owner/:repo/git/refs
我能够创建与特定版本匹配的分支。这意味着我已经为下一步准备好了 branch name
、commit SHA
和 tree SHA
;挑选一个或多个提交 SHA 到这个分支。使用 POST /repos/:owner/:repo/git/commits
我可以创建一个提交,但我不确定要使用哪个树 and/or 父级 - 这可能会导致我在调用 POST /repos/:owner/:repo/merges
时遇到问题,因为它 returns me status 409 (merge conflict) where locally, 当然没有.
我能找到的唯一真实例子是 https://github.com/tibdex/github-cherry-pick。然而,它并不真正符合我的场景,我很难理解 Git 内部工作原理。
我的场景(从最新到最旧);
* commit E (current state of `master`)
* commit D
* commit C (deployed to environment)
* commit B
* commit A
在这种情况下,我想将提交 E 挑选到提交 C 的新分支中,创建一个我可以发布的集合(A、B、C、E)。
* commit E (current state of `master`)
* commit D
|
| * commit E (new branch, to be deployed)
|/
* commit C (deployed to environment)
* commit B
* commit A
基本上我需要的是这个 bash;
的 GitHub API 版本git checkout -b {new-branch-name} {sha}
git cherry-pick {sha}
git push main {new-branch-name}
感谢任何帮助!
以下是我如何在 Git 集线器 API 上用伪代码实现 cherry-pick:
// here is a commit, for example, from a pull request:
listOfCommits = GET /repos/$owner/$repo/pulls/$number/commits
commit = listOfCommits.head // the first one in the list
// Here is the branch we want to cherry-pick to:
branch = GET /repos/$owner/$repo/branches/$branchName
branchSha = branch.commit.sha
branchTree = branch.commit.commit.tree.sha
// Create a temporary commit on the branch, which extends as a sibling of
// the commit we want but contains the current tree of the target branch:
parentSha = commit.parents.head // first parent -- there should only be one
tempCommit = POST /repos/$owner/$repo/git/commits { "message": "temp",
"tree": branchTree,
"parents": [parentSha] }
// Now temporarily force the branch over to that commit
PATCH /repos/$owner/$repo/git/refs/heads/$refName { sha = tempCommit.sha,
force = true }
// Merge the commit we want into this mess:
merge = POST /repos/$owner/$repo/merges { "base": branchName
"head": commit.sha }
// and get that tree!
mergeTree = merge.commit.tree.sha
// Now that we know what the tree should be, create the cherry-pick commit.
// Note that branchSha is the original from up at the top.
cherry = POST /repos/$owner/$repo/git/commits { "message": "looks good!",
"tree": mergeTree,
"parents": [branchSha] }
// Replace the temp commit with the real commit:
PATCH /repos/$owner/$repo/git/refs/heads/$refName { sha = cherry.sha,
force = true }
// Done!
Git高手请指教,我相信这样就可以了:
git checkout -b {new-branch-name} {sha}
git cherry-pick {sha}
git push main {new-branch-name}
已接受的答案有效,但不清楚原因。
以下内容摘自我对这个脚本的要点(在 golang 中)的评论:https://gist.github.com/sashamor/7918b3be758759440feb7825547370f9
GitHub 不支持直接使用 API 创建 cherry-pick 提交。 但是,它确实支持在 git 树中创建提交对象。所以,我们将 从第一原则创建一个新的 cherry-pick 提交。
要创建提交,我们需要三样东西:
- 提交信息。
- 父提交。
- 树(也就是这次提交时 repo 中所有对象的状态)。
对于 cherry-pick 提交,这很简单:
- 消息很简单 - 我们使用来自原始提交的消息,加上一个 “从...中精心挑选”页脚。
- 父 SHA 也很简单 - 我们使用我们想要的提交的 SHA 樱桃采摘,延伸树。
- 树是棘手的部分 - 我们需要创建一个新的 git 对象 包含我们希望它们处于的状态的文件,然后使用它。
以下步骤用于创建树 SHA。一旦我们有了它,我们就可以 创建提交。
为了得到树,我们可以使用合并API。目前,GitHub 合并 API 需要两件事:
- 要合并到的分支。
- 我们要合并的提交的 SHA。
乍一看,一个解决方案似乎是使用 merge with:
- 要选择的分支。
- 对 cherry-pick 的承诺。
然而,这有一个警告,所有提交 before cherry-pick 提交,不在要挑选的分支中,包含在 合并。我们不想要这个。为了解决这个问题,我们可以“欺骗”git 包括 cherry-pick 提交,通过(临时)设置 分支到我们想要挑选的提交的父级。这样,当 git 执行合并,它检测到我们正在提交的分支的父级 merging to 匹配我们正在合并的提交的父级,并合并 一棵大小为 1 的树,仅包含 cherry-pick 提交。
要创建这个新的“树尖”提交:
- 消息无关紧要 - 它丢失了。
- 父级是我们要挑选的提交的父级 - 这个 这样,cherry-pick 提交和分支都有相同的父级。
- 这棵树是我们要挑选的树枝。
然后我们创建一个指向这个提交的临时分支,这样我们就可以合并 到它上面。然后我们可以调用 merge with:
- 一个树枝与我们正在挑选的树枝相匹配的树枝,以及一个 父级匹配我们正在挑选的提交的父级。
- 对 cherry-pick 的承诺。 此合并操作的结果提交具有我们需要的树 SHA。
最后,我们可以使用它来创建 cherry-pick 提交。这可以是 根据需要重复多次,新的 cherry-pick 提交是 每次基本分支。