Pygithub: InputGitTreeElement 应该允许为 sha 传递“null”

创建于 2019-12-14  ·  8评论  ·  资料来源: PyGithub/PyGithub

Github的Tree创建api允许我们通过sha = null来表示需要删除指定的blob。

但是,我无法将此信息传递给我的InputGitTreeElement 。 我可以给它一个 str 或一个github.GithubObject.NotSet 。 这意味着我无法使用 PyGithub 从树中删除文件(我想在一次提交中删除多个文件,因此创建树是我的理想选择)。

当前的设计是只有在实际设置时才传递sha
https://github.com/PyGithub/PyGithub/blob/540a085001/github/InputGitTreeElement.py#L81

我可以理解传递None与设计背道而驰。 我认为可以引入类似github.GithubObject.Null来明确表示该字段是null 。 它可以在 GH API 接受空值的任何地方使用。

例子

new_tree = repo.create_git_tree(
    [
        InputGitTreeElement(
            path="my/dir/my_file.txt", mode="100644", type="blob", sha=github.GithubObject.Null
        ),
   ],
    base_tree=head_commit.tree
)

这将删除my/dir/my_file.txt


我目前的解决方法是直接点击 api 来创建树(使用请求,设置sha=None ),获取树 sha 并将它与 pygithub 一起用于我剩余的工作流程(提交等)。

如果我误解了某些方面或需要详细说明,请告诉我。

最有用的评论

非常感谢! 我会在第二天左右尝试一下。 也许没有 f 弦。 :-)

所有8条评论

实际上 NotSet 本身就是一个与 None 无关的类,所以如果你传入 None,它应该可以正常工作。

哦,等等,我明白了。 我们断言它是一个 str! 是的,好的,所以我认为放松以允许 None 是完全没问题的,很好的捕获。

我对这个变化有很多麻烦。 我已经进行了必要的更改,但是 create_git_tree() API 要么返回 422 GitRPC::BadObjectState 要么返回通用的 404 Not Found 错误。 您能否针对公共存储库提供一个工作示例,以便我可以获取单元测试的重放数据?

我的代码是用于私人仓库的,所以我在这里为您创建了一个精简版本:

import json
import requests
from http import HTTPStatus
from github import Github

TOKEN = "<GITHUB TOKEN>"
gh_client = Github(TOKEN)

repo = gh_client.get_repo("duaraghav8/test")
my_branch = "tree-test"

# paths is list of files to delete
paths = ["pods/raghav/network/resources.tf", "abc"]

sha = repo.get_branch(my_branch).commit.sha
head_commit = repo.get_git_commit(sha)

tree_objects = [
    {"path": path, "mode": "100644", "type": "blob", "sha": None}
    for path in paths
]
payload = {
    "base_tree": head_commit.tree.sha,
    "tree": tree_objects,
}
headers = {"Authorization": f"token {TOKEN}"}
url = f"{repo.url}/git/trees"

response = requests.post(url, headers=headers, data=json.dumps(payload))
if response.status_code != HTTPStatus.CREATED:
    raise RuntimeError("Failed")

new_tree_sha = response.json()["sha"]
tree = repo.get_git_tree(new_tree_sha)

我也收到422 GitRPC::BadObjectState原因是因为我在paths中提供了基本树中不存在的文件名。 例如,尝试破坏上述文件名中的 1 个。

我无法公开我的测试存储库,但这是结构,只需在您自己的存储库中设置虚拟文件

pods/
  raghav/
    network/
      resources.tf

非常感谢! 我会在第二天左右尝试一下。 也许没有 f 弦。 :-)

@stevenk 哇哦! 感谢您解决这个问题
抄送@rohitpaulk

@stevenk 我正在创建这样的提交,但即使文件差异为零,也会提交。 请提供有关如何提交的任何帮助,仅当有一些 diff 时。 谢谢 !

   file_list = [a.txt]
   file_names =[a.txt] 
    for i, entry in enumerate(file_list):
      with open(entry) as input_file:
        data = input_file.read()
      element = InputGitTreeElement(file_names[i], '100644', 'blob', data)
      element_list.append(element)
    tree = repo.create_git_tree(element_list, base_tree)
    parent = repo.get_git_commit(master_sha)
    commit = repo.create_git_commit(commit_message, tree, [parent])

@Abhishek627树 SHA 本质上是存储库中所有文件的校验和,因此您可以检查它们是否匹配。

在您的上下文中,这将类似于:

if tree.sha != base_tree.sha:
   # then commit

(我不记得用于获取 sha 的确切方法,但您明白了)

此页面是否有帮助?
0 / 5 - 0 等级

相关问题

PeterJCLaw picture PeterJCLaw  ·  6评论

grayaii picture grayaii  ·  4评论

BBI-YggyKing picture BBI-YggyKing  ·  5评论

nchammas picture nchammas  ·  3评论

jacquev6 picture jacquev6  ·  3评论