【问题标题】:Get all file names from a Github repo through the Github API通过 Github API 从 Github 存储库中获取所有文件名
【发布时间】:2014-09-21 05:18:09
【问题描述】:

是否可以使用 GitHub API 从存储库中获取所有文件名?

我目前正在尝试使用 PyGithub 进行修改,但只要它有效,我完全可以手动执行请求。

到目前为止我的算法是:

  1. 获取用户存储库名称
  2. 获取与某个描述匹配的用户仓库
  3. ???获取 repo 文件名?

【问题讨论】:

    标签: github github-api


    【解决方案1】:

    这必须与特定的提交相关,因为某些文件可能存在于某些提交中而在其他提交中不存在,因此在查看文件之前,您需要使用 List commits on a repository 之类的东西:

    GET /repos/:owner/:repo/commits
    

    如果您只对分支上的最新提交感兴趣,可以将sha 参数设置为分支名称:

    shastring SHA 或分支开始列出提交。

    一旦你有一个提交哈希,你可以inspect that commit

    GET /repos/:owner/:repo/git/commits/:sha
    

    应该返回类似这样的内容(从 GitHub 的文档中截断):

    {
      "sha": "...",
      "...",
      "tree": {
        "url": "https://api.github.com/repos/octocat/Hello-World/git/trees/691272480426f78a0138979dd3ce63b77f706feb",
        "sha": "691272480426f78a0138979dd3ce63b77f706feb"
      },
      "...": "..."
    }
    

    查看其的哈希值,本质上就是它的目录内容。在这种情况下,691272480426f78a0138979dd3ce63b77f706feb。现在终于可以request the contents of that tree

    GET /repos/:owner/:repo/git/trees/:sha
    

    GitHub 示例的输出是

    {
      "sha": "9fb037999f264ba9a7fc6274d15fa3ae2ab98312",
      "url": "https://api.github.com/repos/octocat/Hello-World/trees/9fb037999f264ba9a7fc6274d15fa3ae2ab98312",
      "tree": [
        {
          "path": "file.rb",
          "mode": "100644",
          "type": "blob",
          "size": 30,
          "sha": "44b4fc6d56897b048c772eb4087f854f46256132",
          "url": "https://api.github.com/repos/octocat/Hello-World/git/blobs/44b4fc6d56897b048c772eb4087f854f46256132"
        },
        {
          "path": "subdir",
          "mode": "040000",
          "type": "tree",
          "sha": "f484d249c660418515fb01c2b9662073663c242e",
          "url": "https://api.github.com/repos/octocat/Hello-World/git/blobs/f484d249c660418515fb01c2b9662073663c242e"
        },
        {
          "path": "exec_file",
          "mode": "100755",
          "type": "blob",
          "size": 75,
          "sha": "45b983be36b73c0788dc9cbcb76cbb80fc7bb057",
          "url": "https://api.github.com/repos/octocat/Hello-World/git/blobs/45b983be36b73c0788dc9cbcb76cbb80fc7bb057"
        }
      ]
    }
    

    如您所见,我们有一些对应于文件的blob,还有一些对应于子目录的附加树。你可能想do this recursively

    【讨论】:

    • Repository Contents API 也值得一看。它提供了熟悉的目录式导航结构,展示了目录和文件树。
    • :sha可以是标签,如master
    【解决方案2】:

    您可以使用Github git trees

    https://api.github.com/repos/[USER]/[REPO]/git/trees/[BRANCH]?recursive=1

    回购

    https://github.com/deeja/bing-maps-loader

    API 调用

    https://api.github.com/repos/deeja/bing-maps-loader/git/trees/master?recursive=1

    返回

    {
    sha: "55382e87889ccb4c173bc99a42cc738358fc253a",
    url: "https://api.github.com/repos/deeja/bing-maps-loader/git/trees/55382e87889ccb4c173bc99a42cc738358fc253a",
    tree: [
    {
    path: "README.md",
    mode: "100644",
    type: "blob",
    sha: "41ceefc1262bb80a25529342ee3ec2ec7add7063",
    size: 3196,
    url: "https://api.github.com/repos/deeja/bing-maps-loader/git/blobs/41ceefc1262bb80a25529342ee3ec2ec7add7063"
    },
    {
    path: "index.js",
    mode: "100644",
    type: "blob",
    sha: "a81c94f70d1ca2a0df02bae36eb2aa920c7fb20e",
    size: 1581,
    url: "https://api.github.com/repos/deeja/bing-maps-loader/git/blobs/a81c94f70d1ca2a0df02bae36eb2aa920c7fb20e"
    },
    {
    path: "package.json",
    mode: "100644",
    type: "blob",
    sha: "45f24dcb7a457b14fede4cb907e957600882b340",
    size: 595,
    url: "https://api.github.com/repos/deeja/bing-maps-loader/git/blobs/45f24dcb7a457b14fede4cb907e957600882b340"
    }
    ],
    truncated: false
    }
    

    【讨论】:

      【解决方案3】:

      现在使用 graphql api 变得更加容易,您可以在一个查询中获取所有内容

      首先你得到你的回购:

      query {
        repository(name: "MyRepo" owner: "mylogin"){
      
        }
      }
      

      然后你得到它的 defaultBranchRef 来让生活更轻松

          defaultBranchRef{
      
          }
      

      现在所有的分支 ref 真的只是一个提交的指针,而且由于 graphql 是强类型的(并且 refs 可以是不同的东西)我们需要让它知道它是一个提交,

         target{
            ...on Commit {
      
            }
         }
      

      所以 target 是我们的 ref 所指向的,我们说“如果它是一个提交,就这样做”

      它应该怎么做? 它应该获得最新的提交(因为它将在 repo 中包含最新的文件)

      为此我们查​​询历史记录

              history(first: 1 until: "2019-10-08T00:00:00"){
                  nodes{
      
                  }
              }
      

      现在在nodes 内部,我们在提交内部,现在我们可以看到文件, 提交指针中的文件实际上只是一个指向树的指针,而树只有条目,可以是 Tree 类型的对象,也可以是 blob 类型的对象

      代表文件的条目被称为 blob,但由于我们不会对它们做任何事情,只是列出它们的名称,因此您甚至不需要知道这一点

      但重要的是要知道树也是条目,所以如果你找到一棵树,你需要深入挖掘,但你只能深入到预先定义的级别。

             tree{
                 entries {
                   name
                   object {
                     ...on Tree{
                       entries{
                         name
                         object {
                            ...on Tree{
                              entries{
                                name
                              }
                            }
                         }
                       }
                     }
                   }
                 } 
             }
      

      现在把它们放在一起:

      query{
        repository(owner: "MyLogin", name: "MyRepo") {
          defaultBranchRef {
            target {
              ... on Commit {
                history(first: 1 until: "2019-10-08T00:00:00") {
                  nodes {
                    tree {
                      entries {
                        name
                        object {
                          ... on Tree {
                            entries {
                              name
                              object{
                                ...on Tree{
                                  entries{
                                    name
                                    object{
                                      ...on Tree{
                                        entries{
                                          name
                                        }                                  
                                      }
                                    }
                                  }   
                                }
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
      

      【讨论】:

        【解决方案4】:

        正如丹所说:github trees

        请参阅下面的工作示例

        import requests
        
        user = "grumbach"
        repo = "ft_ping"
        
        url = "https://api.github.com/repos/{}/{}/git/trees/master?recursive=1".format(user, repo)
        r = requests.get(url)
        res = r.json()
        
        for file in res["tree"]:
            print(file["path"])
        

        为了简单起见,我省略了错误管理,反正迅猛龙已经灭绝了……

        【讨论】:

        • 感谢您的示例!
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-02-28
        • 2021-08-29
        • 1970-01-01
        • 2017-09-01
        • 2020-12-05
        相关资源
        最近更新 更多