Pygithub: InputGitTreeElement debería permitir pasar "nulo" para sha

Creado en 14 dic. 2019  ·  8Comentarios  ·  Fuente: PyGithub/PyGithub

La api de creación de árboles de Github nos permite pasar sha = null para indicar que el blob especificado debe eliminarse.

Sin embargo, no tengo forma de pasar esta información a mi InputGitTreeElement . Puedo darle una str o github.GithubObject.NotSet . Esto significa que no tengo forma de eliminar archivos de un árbol usando PyGithub (me gustaría eliminar varios archivos en una sola confirmación, por lo que la creación de árboles es la opción ideal para mí).

El diseño actual es solo pasar sha si realmente está configurado:
https://github.com/PyGithub/PyGithub/blob/540a085001/github/InputGitTreeElement.py#L81

Puedo entender que pasar un None va en contra del diseño. Creo que se podría introducir algo como github.GithubObject.Null para decir explícitamente que este campo es null . Se puede usar en cualquier lugar donde la API de GH acepte un valor nulo.

Ejemplo

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
)

Esto eliminará my/dir/my_file.txt


Mi solución actual es presionar directamente la API para crear un árbol (usando solicitudes, configurando sha=None ), obtener el árbol sha y usarlo con pygithub para mi flujo de trabajo restante (compromiso, etc.).

Por favor, avíseme en caso de que haya entendido mal algún aspecto o si algo necesita ser elaborado.

Comentario más útil

¡Muchas gracias! Lo intentaré en los próximos días. Quizás sin las cuerdas f. :-)

Todos 8 comentarios

En realidad, NotSet es una clase por derecho propio que no tiene nada que ver con None, por lo que si pasa None, debería funcionar bien.

Oh, espera, ya veo. Afirmamos que es un str! Bien, de acuerdo, entonces creo que aflojar para permitir a None está perfectamente bien, entonces, buena captura.

Estoy teniendo muchos problemas con este cambio. Hice los cambios necesarios, pero la API create_git_tree () devuelve 422 GitRPC :: BadObjectState o un error genérico 404 No encontrado. ¿Puede proporcionar un ejemplo de trabajo contra un repositorio público para que pueda obtener los datos de reproducción para la prueba unitaria?

Mi código es para un repositorio privado, así que acabo de crear una versión simplificada para ti aquí:

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)

Una de las razones por las que yo también recibí 422 GitRPC::BadObjectState fue porque estaba proporcionando nombres de archivo en paths que no existían en el árbol base. Por ejemplo, intente corromper 1 de los nombres de archivo anteriores.

No puedo hacer público mi repositorio de prueba, pero aquí está la estructura, solo configure los archivos ficticios en su propio repositorio

pods/
  raghav/
    network/
      resources.tf

¡Muchas gracias! Lo intentaré en los próximos días. Quizás sin las cuerdas f. :-)

@stevenk wohoo! gracias por arreglar esto
cc @rohitpaulk

@stevenk Estoy creando una confirmación como esta, pero esta se confirma incluso si el archivo diff es cero. Por favor, cualquier ayuda sobre cómo comprometerse solo si hay alguna diferencia. Gracias !

   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 son esencialmente sumas de comprobación de todos los archivos en su repositorio, por lo que puede verificar si coinciden.

En su contexto, sería algo como:

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

(No recuerdo el método exacto usado para buscar un sha, pero entiendes la idea)

¿Fue útil esta página
0 / 5 - 0 calificaciones