API создания дерева Github позволяет нам передать sha = null
чтобы указать, что указанный большой двоичный объект необходимо удалить.
Однако у меня нет возможности передать эту информацию моему InputGitTreeElement
. Я могу дать ему строчку или 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 для моего оставшегося рабочего процесса (фиксация и т. Д.).
Пожалуйста, дайте мне знать, если я неправильно понял какой-то аспект или если что-то нужно уточнить.
На самом деле NotSet - это отдельный класс, который не имеет ничего общего с None, поэтому, если вы передадите None, он должен работать нормально.
Ой, подожди, понятно. Мы утверждаем, что это ул. Хорошо, хорошо, поэтому я думаю, что ослабление, чтобы разрешить None, в таком случае совершенно нормально, хороший улов.
У меня много проблем с этим изменением. Я внес необходимые изменения, но API create_git_tree () либо возвращает 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
, которых не было в базовом дереве. Например, попробуйте испортить одно из указанных выше имен файлов.
Я не могу сделать свое тестовое репо общедоступным, но вот структура, просто установите фиктивные файлы в собственное репо.
pods/
raghav/
network/
resources.tf
Огромное спасибо! Я попробую это сделать на следующий день или около того. Может быть, без фа-струн. :-)
@stevenk wohoo! спасибо за исправление
cc @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 Tree SHA - это, по сути, контрольные суммы всех файлов в вашем репозитории, поэтому вы можете просто проверить, совпадают ли они.
В вашем контексте это будет примерно так:
if tree.sha != base_tree.sha:
# then commit
(Я не помню точный метод, используемый для получения ша, но вы поняли идею)
Самый полезный комментарий
Огромное спасибо! Я попробую это сделать на следующий день или около того. Может быть, без фа-струн. :-)