Githubのツリー作成APIを使用すると、 sha = null
を渡して、指定したblobを削除する必要があることを示すことができます。
ただし、この情報をInputGitTreeElement
に渡す方法がありません。 strまたはgithub.GithubObject.NotSet
いずれかを指定できます。 これは、PyGithubを使用してツリーからファイルを削除する方法がないことを意味します(1回のコミットで複数のファイルを削除したいので、ツリーの作成が私にとって理想的な選択です)。
現在の設計では、実際に設定されている場合にのみsha
渡します。
https://github.com/PyGithub/PyGithub/blob/540a085001/github/InputGitTreeElement.py#L81
None
を渡すことは設計に反することを理解できます。 github.GithubObject.Null
ようなものを導入して、このフィールドがnull
ことを明示的に示すことができると思います。 GHAPIがnull値を受け入れるすべての場所で使用できます。
例
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を渡すと、正常に機能するはずです。
ああ、待って、なるほど。 私たちはそれがstrだと断言します! そうですね、それで、Noneを許可するために緩めることは完全に問題ないと思います。
私はこの変更で多くの問題を抱えています。 必要な変更を加えましたが、create_git_tree()APIは422 GitRPC :: BadObjectStateまたは一般的な404NotFoundエラーを返します。 単体テストのリプレイデータを取得できるように、公開リポジトリに対する実用的な例を提供できますか?
私のコードはプライベートリポジトリ用なので、ここであなたのためにそれの簡略版を作成しました:
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
受け取った理由の1 paths
は、ベースツリーに存在しない
テストリポジトリを公開することはできませんが、構造は次のとおりです。独自のリポジトリにダミーファイルを設定するだけです。
pods/
raghav/
network/
resources.tf
本当にありがとう! 翌日かそこらで試してみます。 たぶんfストリングなし。 :-)
@stevenk wohoo! これを修正してくれてありがとう
cc @rohitpaulk
@stevenkこのようなコミットを作成していますが、ファイルの差分がゼロの場合でもコミットします。 多少の違いがある場合にのみコミットする方法についてのヘルプをお願いします。 ありがとう !
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をフェッチするために使用された正確な方法を思い出しませんが、あなたは考えを理解します)
最も参考になるコメント
本当にありがとう! 翌日かそこらで試してみます。 たぶんfストリングなし。 :-)