Pygithub: InputGitTreeElement должен разрешать передачу "null" для sha

Созданный на 14 дек. 2019  ·  8Комментарии  ·  Источник: PyGithub/PyGithub

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 для моего оставшегося рабочего процесса (фиксация и т. Д.).

Пожалуйста, дайте мне знать, если я неправильно понял какой-то аспект или если что-то нужно уточнить.

Самый полезный комментарий

Огромное спасибо! Я попробую это сделать на следующий день или около того. Может быть, без фа-струн. :-)

Все 8 Комментарий

На самом деле 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

(Я не помню точный метод, используемый для получения ша, но вы поняли идею)

Была ли эта страница полезной?
0 / 5 - 0 рейтинги