From 1bad563e3f23d3d8b9f98721d857a660692f4847 Mon Sep 17 00:00:00 2001 From: Eric Wheeler Date: Sat, 19 Jul 2025 17:17:58 -0700 Subject: [PATCH 1/3] Add conditional check for git checkout in development path Only insert development path into sys.path when running from a git checkout (when ../.git exists). This makes the script more robust by only using the development tree when available and falling back to installed package otherwise. --- bin/github-backup | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/bin/github-backup b/bin/github-backup index b33d19f..c6116a1 100755 --- a/bin/github-backup +++ b/bin/github-backup @@ -4,6 +4,15 @@ import logging import os import sys + +# If we are running from a git-checkout, we can run against the development +# tree without installing. +if os.path.exists(os.path.join(os.path.dirname(__file__), "..", ".git")): + sys.path.insert( + 0, os.path.abspath(os.path.join(os.path.dirname(__file__), "..")) + ) + + from github_backup.github_backup import ( backup_account, backup_repositories, From d820dd994d931f8dbead5e63dceef5c5b49bafa3 Mon Sep 17 00:00:00 2001 From: Eric Wheeler Date: Sat, 19 Jul 2025 17:28:52 -0700 Subject: [PATCH 2/3] Fix -R flag to allow backups of repositories not owned by user Previously, using -R flag would show zero issues/PRs for repositories not owned by the primary user due to incorrect pagination parameters being added to single repository API calls. - Remove pagination parameters for single repository requests - Support owner/repo format in -R flag (e.g., -R owner/repo-name) - Skip filtering when specific repository is requested - Fix URL construction for requests without query parameters This enables backing up any repository, not just those owned by the primary user specified in -u flag. --- github_backup/github_backup.py | 49 +++++++++++++++++++++++++--------- 1 file changed, 36 insertions(+), 13 deletions(-) diff --git a/github_backup/github_backup.py b/github_backup/github_backup.py index 29c9e58..4b2d790 100644 --- a/github_backup/github_backup.py +++ b/github_backup/github_backup.py @@ -578,10 +578,15 @@ def retrieve_data_gen(args, template, query_args=None, single_request=False): page = 0 while True: - page = page + 1 + if single_request: + request_page, request_per_page = None, None + else: + page = page + 1 + request_page, request_per_page = page, per_page + request = _construct_request( - per_page, - page, + request_per_page, + request_page, query_args, template, auth, @@ -715,14 +720,22 @@ def _get_response(request, auth, template): def _construct_request( per_page, page, query_args, template, auth, as_app=None, fine=False ): - querystring = urlencode( - dict( - list({"per_page": per_page, "page": page}.items()) - + list(query_args.items()) - ) - ) + all_query_args = {} + if per_page: + all_query_args["per_page"] = per_page + if page: + all_query_args["page"] = page + if query_args: + all_query_args.update(query_args) - request = Request(template + "?" + querystring) + request_url = template + if all_query_args: + querystring = urlencode(all_query_args) + request_url = template + "?" + querystring + else: + querystring = "" + + request = Request(request_url) if auth is not None: if not as_app: if fine: @@ -735,7 +748,11 @@ def _construct_request( request.add_header( "Accept", "application/vnd.github.machine-man-preview+json" ) - logger.info("Requesting {}?{}".format(template, querystring)) + + log_url = template + if querystring: + log_url += "?" + querystring + logger.info("Requesting {}".format(log_url)) return request @@ -885,9 +902,13 @@ def retrieve_repositories(args, authenticated_user): ) if args.repository: + if "/" in args.repository: + repo_path = args.repository + else: + repo_path = "{0}/{1}".format(args.user, args.repository) single_request = True - template = "https://{0}/repos/{1}/{2}".format( - get_github_api_host(args), args.user, args.repository + template = "https://{0}/repos/{1}".format( + get_github_api_host(args), repo_path ) repos = retrieve_data(args, template, single_request=single_request) @@ -928,6 +949,8 @@ def retrieve_repositories(args, authenticated_user): def filter_repositories(args, unfiltered_repositories): + if args.repository: + return unfiltered_repositories logger.info("Filtering repositories") repositories = [] From a4f15b06d94c0481861a3cd149f3ac5b10fbefa7 Mon Sep 17 00:00:00 2001 From: Eric Wheeler Date: Fri, 25 Jul 2025 11:47:08 -0700 Subject: [PATCH 3/3] Revert "Add conditional check for git checkout in development path" This reverts commit 1bad563e3f23d3d8b9f98721d857a660692f4847. --- bin/github-backup | 9 --------- 1 file changed, 9 deletions(-) diff --git a/bin/github-backup b/bin/github-backup index c6116a1..b33d19f 100755 --- a/bin/github-backup +++ b/bin/github-backup @@ -4,15 +4,6 @@ import logging import os import sys - -# If we are running from a git-checkout, we can run against the development -# tree without installing. -if os.path.exists(os.path.join(os.path.dirname(__file__), "..", ".git")): - sys.path.insert( - 0, os.path.abspath(os.path.join(os.path.dirname(__file__), "..")) - ) - - from github_backup.github_backup import ( backup_account, backup_repositories,