首先,要在github上创建一个access token,用来做调API请求时的登录核身。
登录github.com,进入settings页面
选择developer settings
点击personal access tokens
选择需要的权限和有效期,点击生成。需要注意的是,access token只会展示这一次,要记得及时保存,否则以后不会再出现(忘了只能重新申请)。
想要验证申请的access token能否用于登录,可以在ssh上尝试访问一下github(这一步非常重要,因为我申请的第一个acess token直接去调API,却一直提示"bad credential",而我一直以为是调API的姿势不对,没想到是access token复制出错了,绕了很多弯路)。
也可以用登录API去访问一下,只要返回200就表示登录成功。从代码里可以看到,只要把正确的access token放入请求头的Authorization中,即可实现登录。
headers = {"Authorization": "token %s" % token, 'Accept': 'application/vnd.github.v3+json',
'Content-Type': 'application/json'}
login = requests.get("https://api.github.com/user", headers=headers)
获取登录方式以后,就可以根据api文档进行各种操作了。这里主要记录创建仓库和分支的能力。
gihub的所有API都可以在GitHub REST API中查询,比如创建一个个人仓库Repositories - GitHub Docs
其实构造参数的方式很简单,请求头是固定的,除了Authorization用于登录之外,官方文档还需要一个Accept参数。作为一个POST接口,body parameters里要提供一些必要或可选的参数,这里我就提供了一个必要的name参数作为仓库名,就顺利地创建了一个个人仓库。
url = 'https://api.github.com/user/repos'
headers = {"Authorization": "token %s" % token, 'Accept': 'application/vnd.github.v3+json',
'Content-Type': 'application/json'}
data = json.dumps({"name": "%s" % repo_name})
r = requests.post(url, data=data, headers=headers)
正当我以为创建分支和创建仓库一样容易的时候,现实就给了我当头一棒。github官方文档branches下并没有create a branch的api。于是在网上进行了一通搜索,发知道原来可以通过创建引用块reference来间接创建出一个分支,Git references - GitHub Docs
body parameters主要提供2个内容:
-ref:要创建的引用块的名字,必须是以refs打头且至少有2个斜杠的字符串,第二个斜杠之后就是要创建的分支名。
-sha:引用块的SHA1 value。SHA1 value就是仓库里某个commit的commit id。sha的值可以通过List commits接口来获取。
但是在调用List commits接口后,发现新创建的仓库下并没有任何commits,而且和没有create a branch一样,官方文档也没有提供create a commit的接口,并且在我对能查询到的api进行一系列操作后发现,对仓库做的任何操作都会提示"the repository is empty"。甚至让我在SSH里直接对git进行操作,如git init,git branch -m main等,也是同样的报错,同时在github网站也没有任何分支和提交的记录(github应该会默认创建一个main分支)。
经过一系列努力,感觉自己创建的仓库不太对劲,只能回到"create a repository for the authenticated user" API下去查看有没有什么线索,于是发现了这个可选参数:
由于文档里并没有提示这个参数的默认值是什么,我只能尝试强制把它设置成true,看效果如何。非常幸运,加上这参数创建的仓库,默认有一个提交(就是生成readme的那个提交),且存在默认分支main。于是接下来的操作就十分顺理成章了,整体代码如下:
# Create a repository for the authenticated user
url = host + '/user/repos'
data = json.dumps({"name": "%s" % repo_name, "auto_init": True})
r = requests.post(url, data=data, headers=headers)
# List commits
url = host + "/repos/%s/%s/commits" % (username, repo_name)
r = requests.get(url, headers=headers)
text = json.loads(r.text)
sha1 = text[0]['sha']
# create branch by creating refs
url = host + "/repos/%s/%s/git/refs" % (username, repo_name)
data = json.dumps({"ref": "refs/heads/%s" % branch_name, "sha": "%s" % sha1})
r = requests.post(url, data=data, headers=headers)
这样既能创建仓库,也能通过仓库的引用创建分支。
完结,撒花~



