From 3d84a47a88f6757514cb3ee91b829f53ba09e7e0 Mon Sep 17 00:00:00 2001 From: Enrico Minack Date: Wed, 18 Dec 2024 11:40:19 +0100 Subject: [PATCH] Get branches where commit is head (#3083) Implements `GET /repos/{owner}/{repo}/commits/{commit_sha}/branches-where-head` https://docs.github.com/rest/commits/commits#list-branches-for-head-commit --- github/Commit.py | 9 ++++++ tests/Commit.py | 9 ++++++ .../Commit.testGetBranchesWhereHead.txt | 32 +++++++++++++++++++ 3 files changed, 50 insertions(+) create mode 100644 tests/ReplayData/Commit.testGetBranchesWhereHead.txt diff --git a/github/Commit.py b/github/Commit.py index 229dba39f..02dd3d4de 100644 --- a/github/Commit.py +++ b/github/Commit.py @@ -47,6 +47,7 @@ from typing import TYPE_CHECKING, Any +import github.Branch import github.CheckRun import github.CheckSuite import github.CommitCombinedStatus @@ -61,6 +62,7 @@ from github.PaginatedList import PaginatedList if TYPE_CHECKING: + from github.Branch import Branch from github.CheckRun import CheckRun from github.CheckSuite import CheckSuite from github.CommitCombinedStatus import CommitCombinedStatus @@ -206,6 +208,13 @@ def create_status( ) return github.CommitStatus.CommitStatus(self._requester, headers, data) + def get_branches_where_head(self) -> list[Branch]: + """ + :calls: `GET /repos/{owner}/{repo}/commits/{commit_sha}/branches-where-head `_ + """ + headers, data = self._requester.requestJsonAndCheck("GET", f"{self.url}/branches-where-head") + return [github.Branch.Branch(self._requester, headers, item) for item in data] + def get_comments(self) -> PaginatedList[CommitComment]: """ :calls: `GET /repos/{owner}/{repo}/commits/{sha}/comments `_ diff --git a/tests/Commit.py b/tests/Commit.py index 2c93c08c1..ebe691d3b 100644 --- a/tests/Commit.py +++ b/tests/Commit.py @@ -85,6 +85,15 @@ def testAttributes(self): 'Commit(sha="1292bf0e22c796e91cc3d6e24b544aece8c21f2a")', ) + def testGetBranchesWhereHead(self): + repo = self.g.get_repo("PyGithub/PyGithub") + commit = repo.get_commit("0791cc7b1a706ab5d7c607ddff35de4d486ba3e9") + self.assertListKeyEqual( + commit.get_branches_where_head(), + lambda b: b.name, + ["release-v2-0"], + ) + def testGetComments(self): self.assertListKeyEqual( self.commit.get_comments(), diff --git a/tests/ReplayData/Commit.testGetBranchesWhereHead.txt b/tests/ReplayData/Commit.testGetBranchesWhereHead.txt new file mode 100644 index 000000000..7fdd74cb9 --- /dev/null +++ b/tests/ReplayData/Commit.testGetBranchesWhereHead.txt @@ -0,0 +1,32 @@ +https +GET +api.github.com +None +/repos/PyGithub/PyGithub +{'Authorization': 'Basic login_and_password_removed', 'User-Agent': 'PyGithub/Python'} +None +200 +[('Date', 'Fri, 22 Nov 2024 17:49:09 GMT'), ('Content-Type', 'application/json; charset=utf-8'), ('Cache-Control', 'public, max-age=60, s-maxage=60'), ('Vary', 'Accept,Accept-Encoding, Accept, X-Requested-With'), ('ETag', 'W/"3b6c36f50d6e093db7fb1c9b925c4e9f4fc0995880d09205fd79b58e2f0f70d0"'), ('Last-Modified', 'Fri, 22 Nov 2024 11:14:22 GMT'), ('X-GitHub-Media-Type', 'github.v3; format=json'), ('x-github-api-version-selected', '2022-11-28'), ('Access-Control-Expose-Headers', 'ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset'), ('Access-Control-Allow-Origin', '*'), ('Strict-Transport-Security', 'max-age=31536000; includeSubdomains; preload'), ('X-Frame-Options', 'deny'), ('X-Content-Type-Options', 'nosniff'), ('X-XSS-Protection', '0'), ('Referrer-Policy', 'origin-when-cross-origin, strict-origin-when-cross-origin'), ('Content-Security-Policy', "default-src 'none'"), ('Content-Encoding', 'gzip'), ('Server', 'github.com'), ('X-RateLimit-Limit', '60'), ('X-RateLimit-Remaining', '48'), ('X-RateLimit-Reset', '1732300847'), ('X-RateLimit-Resource', 'core'), ('X-RateLimit-Used', '12'), ('Accept-Ranges', 'bytes'), ('Content-Length', '1461'), ('X-GitHub-Request-Id', 'D400:184C4C:27A457A:2818963:6740C416')] +{"id":3544490,"node_id":"MDEwOlJlcG9zaXRvcnkzNTQ0NDkw","name":"PyGithub","full_name":"PyGithub/PyGithub","private":false,"owner":{"login":"PyGithub","id":11288996,"node_id":"MDEyOk9yZ2FuaXphdGlvbjExMjg4OTk2","avatar_url":"https://avatars.githubusercontent.com/u/11288996?v=4","gravatar_id":"","url":"https://api.github.com/users/PyGithub","html_url":"https://github.com/PyGithub","followers_url":"https://api.github.com/users/PyGithub/followers","following_url":"https://api.github.com/users/PyGithub/following{/other_user}","gists_url":"https://api.github.com/users/PyGithub/gists{/gist_id}","starred_url":"https://api.github.com/users/PyGithub/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/PyGithub/subscriptions","organizations_url":"https://api.github.com/users/PyGithub/orgs","repos_url":"https://api.github.com/users/PyGithub/repos","events_url":"https://api.github.com/users/PyGithub/events{/privacy}","received_events_url":"https://api.github.com/users/PyGithub/received_events","type":"Organization","user_view_type":"public","site_admin":false},"html_url":"https://github.com/PyGithub/PyGithub","description":"Typed interactions with the GitHub API v3","fork":false,"url":"https://api.github.com/repos/PyGithub/PyGithub","forks_url":"https://api.github.com/repos/PyGithub/PyGithub/forks","keys_url":"https://api.github.com/repos/PyGithub/PyGithub/keys{/key_id}","collaborators_url":"https://api.github.com/repos/PyGithub/PyGithub/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/PyGithub/PyGithub/teams","hooks_url":"https://api.github.com/repos/PyGithub/PyGithub/hooks","issue_events_url":"https://api.github.com/repos/PyGithub/PyGithub/issues/events{/number}","events_url":"https://api.github.com/repos/PyGithub/PyGithub/events","assignees_url":"https://api.github.com/repos/PyGithub/PyGithub/assignees{/user}","branches_url":"https://api.github.com/repos/PyGithub/PyGithub/branches{/branch}","tags_url":"https://api.github.com/repos/PyGithub/PyGithub/tags","blobs_url":"https://api.github.com/repos/PyGithub/PyGithub/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/PyGithub/PyGithub/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/PyGithub/PyGithub/git/refs{/sha}","trees_url":"https://api.github.com/repos/PyGithub/PyGithub/git/trees{/sha}","statuses_url":"https://api.github.com/repos/PyGithub/PyGithub/statuses/{sha}","languages_url":"https://api.github.com/repos/PyGithub/PyGithub/languages","stargazers_url":"https://api.github.com/repos/PyGithub/PyGithub/stargazers","contributors_url":"https://api.github.com/repos/PyGithub/PyGithub/contributors","subscribers_url":"https://api.github.com/repos/PyGithub/PyGithub/subscribers","subscription_url":"https://api.github.com/repos/PyGithub/PyGithub/subscription","commits_url":"https://api.github.com/repos/PyGithub/PyGithub/commits{/sha}","git_commits_url":"https://api.github.com/repos/PyGithub/PyGithub/git/commits{/sha}","comments_url":"https://api.github.com/repos/PyGithub/PyGithub/comments{/number}","issue_comment_url":"https://api.github.com/repos/PyGithub/PyGithub/issues/comments{/number}","contents_url":"https://api.github.com/repos/PyGithub/PyGithub/contents/{+path}","compare_url":"https://api.github.com/repos/PyGithub/PyGithub/compare/{base}...{head}","merges_url":"https://api.github.com/repos/PyGithub/PyGithub/merges","archive_url":"https://api.github.com/repos/PyGithub/PyGithub/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/PyGithub/PyGithub/downloads","issues_url":"https://api.github.com/repos/PyGithub/PyGithub/issues{/number}","pulls_url":"https://api.github.com/repos/PyGithub/PyGithub/pulls{/number}","milestones_url":"https://api.github.com/repos/PyGithub/PyGithub/milestones{/number}","notifications_url":"https://api.github.com/repos/PyGithub/PyGithub/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/PyGithub/PyGithub/labels{/name}","releases_url":"https://api.github.com/repos/PyGithub/PyGithub/releases{/id}","deployments_url":"https://api.github.com/repos/PyGithub/PyGithub/deployments","created_at":"2012-02-25T12:53:47Z","updated_at":"2024-11-22T11:14:22Z","pushed_at":"2024-11-06T20:49:20Z","git_url":"git://github.com/PyGithub/PyGithub.git","ssh_url":"git@github.com:PyGithub/PyGithub.git","clone_url":"https://github.com/PyGithub/PyGithub.git","svn_url":"https://github.com/PyGithub/PyGithub","homepage":"https://pygithub.readthedocs.io/","size":16447,"stargazers_count":7048,"watchers_count":7048,"language":"Python","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"has_discussions":true,"forks_count":1786,"mirror_url":null,"archived":false,"disabled":false,"open_issues_count":351,"license":{"key":"lgpl-3.0","name":"GNU Lesser General Public License v3.0","spdx_id":"LGPL-3.0","url":"https://api.github.com/licenses/lgpl-3.0","node_id":"MDc6TGljZW5zZTEy"},"allow_forking":true,"is_template":false,"web_commit_signoff_required":false,"topics":["github","github-api","pygithub","python"],"visibility":"public","forks":1786,"open_issues":351,"watchers":7048,"default_branch":"main","temp_clone_token":null,"custom_properties":{},"organization":{"login":"PyGithub","id":11288996,"node_id":"MDEyOk9yZ2FuaXphdGlvbjExMjg4OTk2","avatar_url":"https://avatars.githubusercontent.com/u/11288996?v=4","gravatar_id":"","url":"https://api.github.com/users/PyGithub","html_url":"https://github.com/PyGithub","followers_url":"https://api.github.com/users/PyGithub/followers","following_url":"https://api.github.com/users/PyGithub/following{/other_user}","gists_url":"https://api.github.com/users/PyGithub/gists{/gist_id}","starred_url":"https://api.github.com/users/PyGithub/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/PyGithub/subscriptions","organizations_url":"https://api.github.com/users/PyGithub/orgs","repos_url":"https://api.github.com/users/PyGithub/repos","events_url":"https://api.github.com/users/PyGithub/events{/privacy}","received_events_url":"https://api.github.com/users/PyGithub/received_events","type":"Organization","user_view_type":"public","site_admin":false},"network_count":1786,"subscribers_count":111} + +https +GET +api.github.com +None +/repos/PyGithub/PyGithub/commits/0791cc7b1a706ab5d7c607ddff35de4d486ba3e9 +{'Authorization': 'Basic login_and_password_removed', 'User-Agent': 'PyGithub/Python'} +None +200 +[('Date', 'Fri, 22 Nov 2024 17:49:10 GMT'), ('Content-Type', 'application/json; charset=utf-8'), ('Cache-Control', 'public, max-age=60, s-maxage=60'), ('Vary', 'Accept,Accept-Encoding, Accept, X-Requested-With'), ('ETag', 'W/"d881425df5536b0fb95213928ad35316ca7f4bc4bc8759bbca66d904a071e73b"'), ('Last-Modified', 'Mon, 28 Aug 2023 18:27:45 GMT'), ('X-GitHub-Media-Type', 'github.v3; format=json'), ('x-github-api-version-selected', '2022-11-28'), ('Access-Control-Expose-Headers', 'ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset'), ('Access-Control-Allow-Origin', '*'), ('Strict-Transport-Security', 'max-age=31536000; includeSubdomains; preload'), ('X-Frame-Options', 'deny'), ('X-Content-Type-Options', 'nosniff'), ('X-XSS-Protection', '0'), ('Referrer-Policy', 'origin-when-cross-origin, strict-origin-when-cross-origin'), ('Content-Security-Policy', "default-src 'none'"), ('Content-Encoding', 'gzip'), ('Server', 'github.com'), ('X-RateLimit-Limit', '60'), ('X-RateLimit-Remaining', '47'), ('X-RateLimit-Reset', '1732300847'), ('X-RateLimit-Resource', 'core'), ('X-RateLimit-Used', '13'), ('Accept-Ranges', 'bytes'), ('Content-Length', '1923'), ('X-GitHub-Request-Id', 'D406:D7387:27C39FB:28367CF:6740C416')] +{"sha":"0791cc7b1a706ab5d7c607ddff35de4d486ba3e9","node_id":"C_kwDOADYVqtoAKDA3OTFjYzdiMWE3MDZhYjVkN2M2MDdkZGZmMzVkZTRkNDg2YmEzZTk","commit":{"author":{"name":"Enrico Minack","email":"github@enrico.minack.dev","date":"2023-08-28T18:27:45Z"},"committer":{"name":"Enrico Minack","email":"github@enrico.minack.dev","date":"2023-08-28T18:27:45Z"},"message":"Fixing lint errors in release branch","tree":{"sha":"29bb34c69f42d69d0e13d5951a47b32ac4bea130","url":"https://api.github.com/repos/PyGithub/PyGithub/git/trees/29bb34c69f42d69d0e13d5951a47b32ac4bea130"},"url":"https://api.github.com/repos/PyGithub/PyGithub/git/commits/0791cc7b1a706ab5d7c607ddff35de4d486ba3e9","comment_count":0,"verification":{"verified":false,"reason":"unsigned","signature":null,"payload":null,"verified_at":null}},"url":"https://api.github.com/repos/PyGithub/PyGithub/commits/0791cc7b1a706ab5d7c607ddff35de4d486ba3e9","html_url":"https://github.com/PyGithub/PyGithub/commit/0791cc7b1a706ab5d7c607ddff35de4d486ba3e9","comments_url":"https://api.github.com/repos/PyGithub/PyGithub/commits/0791cc7b1a706ab5d7c607ddff35de4d486ba3e9/comments","author":{"login":"EnricoMi","id":44700269,"node_id":"MDQ6VXNlcjQ0NzAwMjY5","avatar_url":"https://avatars.githubusercontent.com/u/44700269?v=4","gravatar_id":"","url":"https://api.github.com/users/EnricoMi","html_url":"https://github.com/EnricoMi","followers_url":"https://api.github.com/users/EnricoMi/followers","following_url":"https://api.github.com/users/EnricoMi/following{/other_user}","gists_url":"https://api.github.com/users/EnricoMi/gists{/gist_id}","starred_url":"https://api.github.com/users/EnricoMi/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/EnricoMi/subscriptions","organizations_url":"https://api.github.com/users/EnricoMi/orgs","repos_url":"https://api.github.com/users/EnricoMi/repos","events_url":"https://api.github.com/users/EnricoMi/events{/privacy}","received_events_url":"https://api.github.com/users/EnricoMi/received_events","type":"User","user_view_type":"public","site_admin":false},"committer":{"login":"EnricoMi","id":44700269,"node_id":"MDQ6VXNlcjQ0NzAwMjY5","avatar_url":"https://avatars.githubusercontent.com/u/44700269?v=4","gravatar_id":"","url":"https://api.github.com/users/EnricoMi","html_url":"https://github.com/EnricoMi","followers_url":"https://api.github.com/users/EnricoMi/followers","following_url":"https://api.github.com/users/EnricoMi/following{/other_user}","gists_url":"https://api.github.com/users/EnricoMi/gists{/gist_id}","starred_url":"https://api.github.com/users/EnricoMi/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/EnricoMi/subscriptions","organizations_url":"https://api.github.com/users/EnricoMi/orgs","repos_url":"https://api.github.com/users/EnricoMi/repos","events_url":"https://api.github.com/users/EnricoMi/events{/privacy}","received_events_url":"https://api.github.com/users/EnricoMi/received_events","type":"User","user_view_type":"public","site_admin":false},"parents":[{"sha":"9f7850bf6572ea8572b8b136b8b3d3e09cb38403","url":"https://api.github.com/repos/PyGithub/PyGithub/commits/9f7850bf6572ea8572b8b136b8b3d3e09cb38403","html_url":"https://github.com/PyGithub/PyGithub/commit/9f7850bf6572ea8572b8b136b8b3d3e09cb38403"}],"stats":{"total":23,"additions":17,"deletions":6},"files":[{"sha":"85536829e55af14399a2341f3dc4dc23b44ea5cf","filename":"github/Auth.py","status":"modified","additions":10,"deletions":4,"changes":14,"blob_url":"https://github.com/PyGithub/PyGithub/blob/0791cc7b1a706ab5d7c607ddff35de4d486ba3e9/github%2FAuth.py","raw_url":"https://github.com/PyGithub/PyGithub/raw/0791cc7b1a706ab5d7c607ddff35de4d486ba3e9/github%2FAuth.py","contents_url":"https://api.github.com/repos/PyGithub/PyGithub/contents/github%2FAuth.py?ref=0791cc7b1a706ab5d7c607ddff35de4d486ba3e9","patch":"@@ -83,7 +83,7 @@ def token_type(self) -> str:\n @property\n def token(self) -> str:\n return (\n- base64.b64encode(f\"{self.login}:{self.password}\".encode())\n+ base64.b64encode(f\"{self.username}:{self.password}\".encode())\n .decode(\"utf-8\")\n .replace(\"\\n\", \"\")\n )\n@@ -491,20 +491,26 @@ def username(self) -> str:\n \n @property\n def login(self) -> str:\n- assert self._login is not None, \"Method withRequester(Requester) must be called first\"\n+ assert (\n+ self._login is not None\n+ ), \"Method withRequester(Requester) must be called first\"\n return self._login\n \n @property\n def password(self) -> str:\n- assert self._password is not None, \"Method withRequester(Requester) must be called first\"\n+ assert (\n+ self._password is not None\n+ ), \"Method withRequester(Requester) must be called first\"\n return self._password\n \n def withRequester(self, requester: Requester) -> \"NetrcAuth\":\n super().withRequester(requester)\n \n auth = utils.get_netrc_auth(requester.base_url, raise_errors=True)\n if auth is None:\n- raise RuntimeError(f\"Could not get credentials from netrc for host {requester.hostname}\")\n+ raise RuntimeError(\n+ f\"Could not get credentials from netrc for host {requester.hostname}\"\n+ )\n \n self._login, self._password = auth\n "},{"sha":"37f76d9e16a3cf9556b5995aff1ff0a73f79696d","filename":"github/Requester.py","status":"modified","additions":3,"deletions":1,"changes":4,"blob_url":"https://github.com/PyGithub/PyGithub/blob/0791cc7b1a706ab5d7c607ddff35de4d486ba3e9/github%2FRequester.py","raw_url":"https://github.com/PyGithub/PyGithub/raw/0791cc7b1a706ab5d7c607ddff35de4d486ba3e9/github%2FRequester.py","contents_url":"https://api.github.com/repos/PyGithub/PyGithub/contents/github%2FRequester.py?ref=0791cc7b1a706ab5d7c607ddff35de4d486ba3e9","patch":"@@ -258,7 +258,9 @@ class Requester:\n _frameBuffer: List[Any]\n \n @staticmethod\n- def noopAuth(request: requests.models.PreparedRequest) -> requests.models.PreparedRequest:\n+ def noopAuth(\n+ request: requests.models.PreparedRequest,\n+ ) -> requests.models.PreparedRequest:\n return request\n \n @classmethod"},{"sha":"d895066ee05a1f1fdddf20960d41af82b5807497","filename":"tests/Authentication.py","status":"modified","additions":4,"deletions":1,"changes":5,"blob_url":"https://github.com/PyGithub/PyGithub/blob/0791cc7b1a706ab5d7c607ddff35de4d486ba3e9/tests%2FAuthentication.py","raw_url":"https://github.com/PyGithub/PyGithub/raw/0791cc7b1a706ab5d7c607ddff35de4d486ba3e9/tests%2FAuthentication.py","contents_url":"https://api.github.com/repos/PyGithub/PyGithub/contents/tests%2FAuthentication.py?ref=0791cc7b1a706ab5d7c607ddff35de4d486ba3e9","patch":"@@ -220,7 +220,10 @@ def testNetrcAuthFails(self):\n with mock.patch.dict(os.environ, {\"NETRC\": tmp.name}):\n with self.assertRaises(RuntimeError) as exc:\n github.Github(auth=auth)\n- self.assertEqual(exc.exception.args, (\"Could not get credentials from netrc for host api.github.com\",))\n+ self.assertEqual(\n+ exc.exception.args,\n+ (\"Could not get credentials from netrc for host api.github.com\",),\n+ )\n \n def testCreateJWT(self):\n auth = github.Auth.AppAuth(APP_ID, PRIVATE_KEY)"}]} + +https +GET +api.github.com +None +/repos/PyGithub/PyGithub/commits/0791cc7b1a706ab5d7c607ddff35de4d486ba3e9/branches-where-head +{'Authorization': 'Basic login_and_password_removed', 'User-Agent': 'PyGithub/Python'} +None +200 +[('Date', 'Fri, 22 Nov 2024 17:49:10 GMT'), ('Content-Type', 'application/json; charset=utf-8'), ('Cache-Control', 'public, max-age=60, s-maxage=60'), ('Vary', 'Accept,Accept-Encoding, Accept, X-Requested-With'), ('ETag', 'W/"717c5c48f3e422fc79179d2410bef733347be76673684d8432ed5721f118ca40"'), ('X-GitHub-Media-Type', 'github.v3; format=json'), ('x-github-api-version-selected', '2022-11-28'), ('Access-Control-Expose-Headers', 'ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset'), ('Access-Control-Allow-Origin', '*'), ('Strict-Transport-Security', 'max-age=31536000; includeSubdomains; preload'), ('X-Frame-Options', 'deny'), ('X-Content-Type-Options', 'nosniff'), ('X-XSS-Protection', '0'), ('Referrer-Policy', 'origin-when-cross-origin, strict-origin-when-cross-origin'), ('Content-Security-Policy', "default-src 'none'"), ('Content-Encoding', 'gzip'), ('Server', 'github.com'), ('X-RateLimit-Limit', '60'), ('X-RateLimit-Remaining', '46'), ('X-RateLimit-Reset', '1732300847'), ('X-RateLimit-Resource', 'core'), ('X-RateLimit-Used', '14'), ('Accept-Ranges', 'bytes'), ('Content-Length', '160'), ('X-GitHub-Request-Id', 'D414:C227F:25E58EB:2658690:6740C416')] +[{"name":"release-v2-0","commit":{"sha":"0791cc7b1a706ab5d7c607ddff35de4d486ba3e9","url":"https://api.github.com/repos/PyGithub/PyGithub/commits/0791cc7b1a706ab5d7c607ddff35de4d486ba3e9"},"protected":false}]