资讯专栏INFORMATION COLUMN

使用 Github API 更新仓库

Jason_Geng / 2133人阅读

摘要:原文链接总览本文为大家提供一种使用更新仓库的方法。通常我们会使用客户端然后到,但为我们提供了相关,在某些情况下可以直接通过更新仓库。使用更新仓库只需六步。获取用于获取当前的的。更新使的指针指到你最新提交的版本。

原文链接:https://ssshooter.com/2019-01...

0. 总览

本文为大家提供一种使用 GitHub API 更新 GitHub 仓库的方法。通常我们会使用 Git 客户端 Commit 然后 Push 到 GitHub,但 GitHub 为我们提供了相关 API,在某些情况下可以直接通过 API 更新仓库。

在此之前有一些前置知识点,你需要了解 git 的储存原理。碰巧最近掘金有一篇很火的文章有提到相关知识。

使用 GitHub API 更新仓库只需六步。虽然对于第一次接触的新手来说可能会有点复杂,但是理清关系之后思路便会很清晰了。

获取 Ref:Ref 指 Git 的引用。如果要发起 Commit,必须知道你的 Commit 要提交到什么地方去(Commit 是一个接一个的链状关系,所以需要知道上一个 Commit 的信息),这一步做的就是这件事。

获取 Commit:用于获取当前 Commit 的 tree 的 sha。

生成 Blob:相当于正常本地提交的 add 操作,可以参考这里的解释。

生成 Tree:构建一个新的 tree,把上一步生成的 Blob 放到合适的位置。这里需要用到的参数 base_tree 就是来自第二步的 Commit 信息。

生成 Commit:提交你的 tree,这步跟正常 commit 很接近,不过要你手动找到此次提交的上一次提交,借哈希值把新的 Commit 接起来。

更新 Ref:使 master 的指针指到你最新提交的版本。

注意:访问 POST 方法的接口必须带 token,虽然 GET 可以不带,但是会限制访问频率,所以建议都带上。相关文档:https://developer.github.com/v3/#authentication

1. 获取 Ref  1.1 文档地址

https://developer.github.com/v3/git/refs/#get-a-reference

1.2 请求地址

GET https://api.github.com/repos/ssshooter/test/git/refs/heads/master

1.3 返回数据
{
  "ref": "refs/heads/master",
  "node_id": "MDM6UmVmMTY0Nzk4NDczOm1hc3Rlcg==",
  "url": "https://api.github.com/repos/ssshooter/test/git/refs/heads/master",
  "object": {
    "sha": "cda66de943082033f4b761639df77728d7bca4f0",
    "type": "commit",
    "url": "https://api.github.com/repos/ssshooter/test/git/commits/cda66de943082033f4b761639df77728d7bca4f0"
  }
}
2. 获取 Commit 2.1 文档地址

https://developer.github.com/v3/git/commits/#get-a-commit

2.2 请求地址

GET https://api.github.com/repos/ssshooter/test/git/commits/cda66de943082033f4b761639df77728d7bca4f0

2.3 返回数据
{
  "sha": "cda66de943082033f4b761639df77728d7bca4f0",
  "node_id": "MDY6Q29tbWl0MTY0Nzk4NDczOmNkYTY2ZGU5NDMwODIwMzNmNGI3NjE2MzlkZjc3NzI4ZDdiY2E0ZjA=",
  "url": "https://api.github.com/repos/ssshooter/test/git/commits/cda66de943082033f4b761639df77728d7bca4f0",
  "html_url": "https://github.com/ssshooter/test/commit/cda66de943082033f4b761639df77728d7bca4f0",
  "author": {
    "name": "DeJavuJo",
    "email": "ssshooterx@gmail.com",
    "date": "2019-01-09T06:02:07Z"
  },
  "committer": {
    "name": "GitHub",
    "email": "noreply@github.com",
    "date": "2019-01-09T06:02:07Z"
  },
  "tree": {
    "sha": "d7a57d28ace0db12773c7d70675f94a48da6421f",
    "url": "https://api.github.com/repos/ssshooter/test/git/trees/d7a57d28ace0db12773c7d70675f94a48da6421f"
  },
  "message": "Create readme.md",
  "parents": [
  ],
  "verification": {
    "verified": true,
    "reason": "valid",
    "signature": "-----BEGIN PGP SIGNATURE-----

wsBcBAABCAAQBQJcNY5fCRBK7hj4Ov3rIwAAdHIIABh8I89hATqg1mSYtpx1aY
Jt/woDobMO7FGE5qXO0NNrCMqwF6mdPJOMMMZvVWF1ULTm8ZJ52GAh5xAnPMZEnQ
8tTjj/Qc0eZCm5B1xO66rgx+7eKkeGUPJj5bX7Lf0i9Se70Ff0jaCdH94RgiSL2d
clDLhNyM4u6AH//k7S3Ud1O6ezXd4+99381Xa331PDLhJttUAbRFRCThszbcxRUT
PvyhPNvXB5ug4J+tAMaZJvZEaED0c1k2Yx1+TYkLvPjOlqXvqaDVpMZieluD5l+f
u13NAoCnLfBe0Skak/8MxRDbMcJYNW78ll60HAa6jJtElD8Vkek8WoVAZ8p3iIE=
=xI87
-----END PGP SIGNATURE-----
",
    "payload": "tree d7a57d28ace0db12773c7d70675f94a48da6421f
author DeJavuJo  1547013727 +0800
committer GitHub  1547013727 +0800

Create readme.md"
  }
}
3. 生成 Blob 3.1 文档地址

https://developer.github.com/v3/git/blobs/#create-a-blob

3.2 请求地址

POST https://api.github.com/repos/ssshooter/test/git/blobs

3.3 请求参数
{
  "content": "Content of the blob",
  "encoding": "utf-8"
}
3.4 返回数据
{
    "sha": "929246f65aab4d636cb229c790f966afc332c124",
    "url": "https://api.github.com/repos/ssshooter/test/git/blobs/929246f65aab4d636cb229c790f966afc332c124"
}
4. 生成 tree 4.1 文档地址

https://developer.github.com/v3/git/trees/#create-a-tree

4.2 请求地址

POST https://api.github.com/repos/ssshooter/test/git/trees

4.3 请求参数

注意:tree.path 可以写深层目录,如 deep/deep/newFile.md(前面不用写斜杠)

{
  "base_tree": "d7a57d28ace0db12773c7d70675f94a48da6421f", // commit tree 的 sha
  "tree": [
    {
      "path": "apiCommitFile.md", // 文件路径
      "mode": "100644", // 类型,详情看文档
      "type": "blob",
      "sha": "929246f65aab4d636cb229c790f966afc332c124" // 刚才生成的 blob 的 sha
    }
  ]
}
4.4 返回数据
{
    "sha": "2b3a65095ceb7cf4425f52d59ca5974d826cff80",
    "url": "https://api.github.com/repos/ssshooter/test/git/trees/2b3a65095ceb7cf4425f52d59ca5974d826cff80",
    "tree": [
        {
            "path": "readme.md",
            "mode": "100644",
            "type": "blob",
            "sha": "b1b716105590454bfc4c0247f193a04088f39c7f",
            "size": 5,
            "url": "https://api.github.com/repos/ssshooter/test/git/blobs/b1b716105590454bfc4c0247f193a04088f39c7f"
        },
        {
            "path": "tree",
            "mode": "040000",
            "type": "tree",
            "sha": "91d8d59147e395effaeacd01c9d8553b37cf77c5",
            "url": "https://api.github.com/repos/ssshooter/test/git/trees/91d8d59147e395effaeacd01c9d8553b37cf77c5"
        }
    ],
    "truncated": false
}
5. 生成 Commit 5.1 文档地址

https://developer.github.com/v3/git/commits/#create-a-commit

5.2 请求地址

POST https://api.github.com/repos/ssshooter/test/git/commits

5.3 请求参数
{
  "message": "a Commit with GitHub api",
  "parents": [
    "cda66de943082033f4b761639df77728d7bca4f0" // 上次 commit 的sha
  ],
  "tree": "2b3a65095ceb7cf4425f52d59ca5974d826cff80"
}
5.4 返回数据
{
    "sha": "45c58a9358b67fc81e4034cb36c5196d791686ef",
    "node_id": "MDY6Q29tbWl0MTY0Nzk4NDczOjQ1YzU4YTkzNThiNjdmYzgxZTQwMzRjYjM2YzUxOTZkNzkxNjg2ZWY=",
    "url": "https://api.github.com/repos/ssshooter/test/git/commits/45c58a9358b67fc81e4034cb36c5196d791686ef",
    "html_url": "https://github.com/ssshooter/test/commit/45c58a9358b67fc81e4034cb36c5196d791686ef",
    "author": {
        "name": "ssshooter",
        "email": "ssshooterx@gmail.com",
        "date": "2019-01-09T10:24:10Z"
    },
    "committer": {
        "name": "ssshooter",
        "email": "ssshooterx@gmail.com",
        "date": "2019-01-09T10:24:10Z"
    },
    "tree": {
        "sha": "2b3a65095ceb7cf4425f52d59ca5974d826cff80",
        "url": "https://api.github.com/repos/ssshooter/test/git/trees/2b3a65095ceb7cf4425f52d59ca5974d826cff80"
    },
    "message": "a Commit with GitHub api",
    "parents": [
        {
            "sha": "cda66de943082033f4b761639df77728d7bca4f0",
            "url": "https://api.github.com/repos/ssshooter/test/git/commits/cda66de943082033f4b761639df77728d7bca4f0",
            "html_url": "https://github.com/ssshooter/test/commit/cda66de943082033f4b761639df77728d7bca4f0"
        }
    ],
    "verification": {
        "verified": false,
        "reason": "unsigned",
        "signature": null,
        "payload": null
    }
}
6. 更新 Ref 6.1 文档地址

https://developer.github.com/v3/git/refs/#update-a-reference

6.2 请求地址

https://api.github.com/repos/ssshooter/test/git/refs/heads/master

6.3 请求参数
{
    "sha":"45c58a9358b67fc81e4034cb36c5196d791686ef",
    "force":true
}
6.4 返回数据
{
    "ref": "refs/heads/master",
    "node_id": "MDM6UmVmMTY0Nzk4NDczOm1hc3Rlcg==",
    "url": "https://api.github.com/repos/ssshooter/test/git/refs/heads/master",
    "object": {
        "sha": "45c58a9358b67fc81e4034cb36c5196d791686ef",
        "type": "commit",
        "url": "https://api.github.com/repos/ssshooter/test/git/commits/45c58a9358b67fc81e4034cb36c5196d791686ef"
    }
}
7. node.js 实践代码
var updateGitHubRes = function(blob, path) {
  var commitSha
  var commitTreeSha
  return getRef()
    .then(({ data }) => {
      commitSha = data.object.sha
      return getCommit(commitSha)
    })
    .then(({ data }) => {
      commitTreeSha = data.tree.sha
      return createBlob(blob)
    })
    .then(({ data }) => {
      var blobSha = data.sha
      return createTree(commitTreeSha, path, blobSha)
    })
    .then(({ data }) => {
      var treeSha = data.sha
      return createCommit(commitSha, treeSha)
    })
    .then(({ data }) => {
      var newCommitSha = data.sha
      return updataRef(newCommitSha)
    })
    .catch(err => {
      console.log(err)
    })
}

var getRef = function() {
  return axios.get(`/${owner}/${repo}/git/refs/heads/master`)
}

var getCommit = function(commitSha) {
  return axios.get(`/${owner}/${repo}/git/commits/${commitSha}`)
}

var createBlob = function(content) {
  return axios.post(`/${owner}/${repo}/git/blobs`, {
    content,
    encoding: "utf-8"
  })
}

var createTree = function(base_tree, path, sha) {
  return axios.post(`/${owner}/${repo}/git/trees`, {
    base_tree, // commit tree 的 sha
    tree: [
      {
        path, // 文件路径
        mode: "100644", // 类型,详情看文档
        type: "blob",
        sha // 刚才生成的 blob 的 sha
      }
    ]
  })
}

var createCommit = function(parentCommitSha, tree, message = "update post") {
  return axios.post(`/${owner}/${repo}/git/commits`, {
    message,
    parents: [parentCommitSha],// 上次 commit 的sha
    tree
  })
}

var updataRef = function(newCommitSha) {
  return axios.post(`/${owner}/${repo}/git/refs/heads/master`, {
    sha: newCommitSha,
    force: true
  })
}
参考文献

https://int128.hatenablog.com/entry/2017/09/05/161641
https://juejin.im/post/5c33f49de51d45523070f7bb
https://git-scm.com/book/zh/v2/Git-内部原理-Git-引用

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/101029.html

相关文章

  • 使用 Gatsby.js 搭建静态博客 EX 使用语雀发布到博客

    摘要:原文链接偶然看到通过语雀发布文章到静态博客,很方便,实现过程也很有意思。我的配置接收推送此时在语雀发布文章,接口就会收到推送的文章信息。 原文链接:https://ssshooter.com/2019-01... 偶然看到通过语雀 webhook 发布文章到 Hexo 静态博客,很方便,实现过程也很有意思。同样的原理可以运用到 Gatsby.js 博客上。 因为使用了 netlify,...

    DoINsiSt 评论0 收藏0
  • 使用 Gatsby.js 搭建静态博客 6 评论系统

    摘要:原文链接方案选择大家都知道等第三方评论系统的存在。部署自己的的原理就是使用接口把评论更新到你静态博客的仓库,触发博客重新部署,在页面生成评论。这样得到的博客页面包括评论部分都是完全静态的。配置完毕推送到或本地运行。 原文链接:https://ssshooter.com/2019-01... 方案选择 大家都知道 disqus 等第三方评论系统的存在。disqus 几年前还是挺好使的,但...

    venmos 评论0 收藏0
  • Hexo 博客终极玩法:云端写作,自动部署

    摘要:配置触发方式一般会得到这么个语雀配置配置一个仓库的可以选择所有更新触发或者主动触发,主动触发的意思即发布需要勾选一个选项才会触发。 Hexo + Github + 语雀 + yuque-hexo +travis-ci+severless 打造全自动持续集成个人博客,云端写作,自动部署,完美体验~ 一、Hexo+Github 的痛点 1.为啥要用hexo+github? 作为一个程序猿,...

    AlphaWallet 评论0 收藏0
  • Hexo 博客终极玩法:云端写作,自动部署

    摘要:配置触发方式一般会得到这么个语雀配置配置一个仓库的可以选择所有更新触发或者主动触发,主动触发的意思即发布需要勾选一个选项才会触发。 Hexo + Github + 语雀 + yuque-hexo +travis-ci+severless 打造全自动持续集成个人博客,云端写作,自动部署,完美体验~ 一、Hexo+Github 的痛点 1.为啥要用hexo+github? 作为一个程序猿,...

    EsgynChina 评论0 收藏0
  • 使用 satis 搭建 composer 本地仓库

    摘要:如果需要定时更新,则需要配置定时任务去定时更新设置本地仓库设置虚拟主机使用本地仓库中的包文件中添加以下拉取,即可获取本地库了如果本地仓库不存在且有网络会去网络中获取。 环境 windows nginx php composer 安装 拉取 satis 项目包,并拉取项目依赖 composer create-project composer/satis --stability=de...

    张率功 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<