Pygithub: InputGitTreeElement devrait permettre de passer "null" pour sha

Créé le 14 déc. 2019  ·  8Commentaires  ·  Source: PyGithub/PyGithub

L' API de création d'arbre de Github nous permet de passer sha = null pour indiquer que le blob spécifié doit être supprimé.

Cependant, je n'ai aucun moyen de transmettre cette information à mon InputGitTreeElement . Je peux soit lui donner un str ou un github.GithubObject.NotSet . Cela signifie que je n'ai aucun moyen de supprimer des fichiers d'un arbre à l'aide de PyGithub (j'aimerais supprimer plusieurs fichiers en un seul commit, donc la création d'arbres est le choix idéal pour moi).

La conception actuelle consiste à ne transmettre le sha s'il est réellement défini :
https://github.com/PyGithub/PyGithub/blob/540a085001/github/InputGitTreeElement.py#L81

Je peux comprendre que passer un None va à l'encontre du design. Je pense que quelque chose comme github.GithubObject.Null pourrait être introduit pour dire explicitement que ce champ est null . Il peut être utilisé partout où l'API GH accepte une valeur nulle.

Exemple

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
)

Cela supprimera my/dir/my_file.txt


Ma solution de contournement actuelle consiste à appuyer directement sur l'API pour créer un arbre (en utilisant des requêtes, en définissant sha=None ), obtenir l'arbre sha et l'utiliser avec pygithub pour mon flux de travail restant (committing, etc.).

S'il vous plaît laissez-moi savoir au cas où j'ai mal compris un aspect ou si quelque chose doit être développé.

Commentaire le plus utile

Merci beaucoup! Je vais essayer ça dans les prochains jours. Peut-être sans les f-strings. :-)

Tous les 8 commentaires

En fait, NotSet est une classe à part entière qui n'a rien à voir avec None, donc si vous passez None, cela devrait fonctionner correctement.

Oh, attends, je vois. Nous affirmons que c'est un str! D'accord, d'accord, donc je pense que desserrer pour autoriser None est parfaitement bien alors, belle prise.

J'ai beaucoup de mal avec ce changement. J'ai apporté les modifications nécessaires, mais l'API create_git_tree() renvoie 422 GitRPC::BadObjectState ou une erreur générique 404 Not Found. Êtes-vous en mesure de fournir un exemple de travail par rapport à un dépôt public afin que je puisse récupérer les données de relecture pour le test unitaire ?

Mon code est pour un dépôt privé, je viens donc d'en créer une version allégée pour vous ici :

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)

L'une des raisons pour lesquelles j'ai également reçu 422 GitRPC::BadObjectState était que je fournissais des noms de fichiers dans paths qui n'existaient pas dans l'arborescence de base. Par exemple, essayez de corrompre 1 des noms de fichiers ci-dessus.

Je ne peux pas rendre mon référentiel de test public, mais voici la structure, configurez simplement les fichiers factices dans votre propre référentiel

pods/
  raghav/
    network/
      resources.tf

Merci beaucoup! Je vais essayer ça dans les prochains jours. Peut-être sans les f-strings. :-)

@stevenk wahou ! merci d'avoir corrigé ça
cc @rohitpaulk

@stevenk Je crée un commit comme celui-ci, mais cela se commit même si le fichier diff est nul. S'il vous plaît, toute aide sur la façon de s'engager uniquement s'il y a des diff . Merci !

   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 Les arbres SHA sont essentiellement des sommes de contrôle de tous les fichiers de votre référentiel, vous pouvez donc simplement vérifier s'ils correspondent.

Dans votre contexte, ce serait quelque chose comme :

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

(Je ne me souviens pas de la méthode exacte utilisée pour aller chercher un sha, mais vous voyez l'idée)

Cette page vous a été utile?
0 / 5 - 0 notes