You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python上传GitHub文件函数首次成功后报422错误的问题

问题:上传GitHub文件首次成功,更新时报错"sha wasn't supplied"

我编写了如下Python函数,用于通过PyGithub库将文件上传至GitHub仓库:

def upload_to_github(github_token: str,
                     source_file: str, destination_folder: str,
                     github_repo: str, git_branch: str) -> None:
    """
    Uploads a file to a GitHub Pages repository using the PyGithub library.
    Parameters:
        github_token: Github token for authentication
        source_file: The path of the local file to be uploaded
        destination_folder: The path of the folder in the GitHub repository where the file will be uploaded
        github_repo: The name of the GitHub repository
        git_branch: The name of the branch in the GitHub repository
    """
    from github import Github

    # Create a Github instance using the username and password
    g = Github(github_token)
    # Get the repository object
    repo = g.get_user().get_repo(github_repo)
    # Get the branch object
    branch = repo.get_branch(git_branch)
    # Read the source file as binary data
    with open(source_file, "rb") as f:
        content = f.read()
    # Create the path of the file in the GitHub repository
    path = destination_folder + "/" + source_file.split("/")[-1]
    # Create or update the file in the GitHub repository
    repo.create_file(path, "Upload file", content, branch=branch.name)

该文件首次上传可成功,但再次上传同一文件时,会报错:

github.GithubException.GithubException: 422 {"message": "Invalid request.\n\n\"sha\" wasn't supplied.", "documentation_url": "https://docs.github.com/rest/repos/contents#create-or-update-file-contents"}

为何仅首次上传有效,无法更新已上传的文件?


原因分析

GitHub的REST API要求更新已存在的文件时必须提供该文件当前的SHA值,这个机制是为了防止并发修改冲突——确保你是基于文件的最新版本进行更新。首次创建文件时,因为文件不存在,所以不需要SHA参数;但当文件已经存在时,必须传入该文件当前的SHA才能完成更新操作。你的代码只调用了create_file方法,没有处理文件已存在的情况,自然缺少SHA参数,导致报错。

修复后的代码

修改函数,先检查目标路径下的文件是否存在:如果存在,获取其SHA值,再调用create_file时传入该参数;如果不存在,直接创建即可。

def upload_to_github(github_token: str,
                     source_file: str, destination_folder: str,
                     github_repo: str, git_branch: str) -> None:
    """
    Uploads or updates a file to a GitHub Pages repository using the PyGithub library.
    Parameters:
        github_token: Github token for authentication
        source_file: The path of the local file to be uploaded
        destination_folder: The path of the folder in the GitHub repository where the file will be uploaded
        github_repo: The name of the GitHub repository
        git_branch: The name of the branch in the GitHub repository
    """
    from github import Github
    from github.GithubException import UnknownObjectException

    # Initialize GitHub instance
    g = Github(github_token)
    repo = g.get_user().get_repo(github_repo)
    branch = repo.get_branch(git_branch)
    
    # Read local file content
    with open(source_file, "rb") as f:
        content = f.read()
    
    # Build target file path in repo
    file_name = source_file.split("/")[-1]
    path = f"{destination_folder}/{file_name}"
    
    # Check if file exists in repo to get SHA
    sha = None
    try:
        # Try to get the existing file
        existing_file = repo.get_contents(path, ref=branch.name)
        sha = existing_file.sha
    except UnknownObjectException:
        # File doesn't exist, no SHA needed
        pass
    
    # Create or update the file
    repo.create_file(
        path, 
        "Upload/Update file", 
        content, 
        branch=branch.name,
        sha=sha  # Pass SHA only if file exists
    )

说明

  • 新增了UnknownObjectException捕获:当文件不存在时,PyGithub会抛出这个异常,此时我们不需要设置SHA。
  • 获取到已存在文件的SHA后,将其传入create_file方法,GitHub会识别这是一个更新操作,而非创建操作。
  • 修改了提交信息,更准确地反映操作类型。

内容的提问来源于stack exchange,提问作者user3848207

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 14:45:26