Skip to content

Commit 7eaf39c

Browse files
committed
Skip fetching gists that have not been updated
1 parent eb33ca8 commit 7eaf39c

1 file changed

Lines changed: 47 additions & 12 deletions

File tree

‎github_backup/github_backup.py‎

Lines changed: 47 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2096,13 +2096,34 @@ def remove_legacy_last_update_if_migrated(
20962096
)
20972097

20982098

2099+
def gist_backup_is_current(repository, repo_cwd, repo_dir):
2100+
"""Whether fetching a gist can be skipped because a clone exists and the
2101+
stored gist.json matches the listing's updated_at. Any edit to a gist —
2102+
including a git push — bumps updated_at, so this can never miss a content
2103+
change; at worst a comment bumps it and causes a harmless refetch."""
2104+
if not os.path.exists(repo_dir):
2105+
return False
2106+
updated_at = repository.get("updated_at")
2107+
if not updated_at:
2108+
return False
2109+
try:
2110+
with codecs.open(
2111+
os.path.join(repo_cwd, "gist.json"), encoding="utf-8"
2112+
) as f:
2113+
stored = json.load(f)
2114+
except (OSError, ValueError):
2115+
return False
2116+
return stored.get("updated_at") == updated_at
2117+
2118+
20992119
def backup_repositories(args, output_directory, repositories):
21002120
logger.info("Backing up repositories")
21012121
repos_template = "https://{0}/repos".format(get_github_api_host(args))
21022122
legacy_last_update_path, legacy_last_update = read_legacy_last_update(
21032123
args, output_directory
21042124
)
21052125
incremental_resource_work_attempted = False
2126+
skipped_unchanged_gists = 0
21062127

21072128
for repository in repositories:
21082129
if repository.get("is_gist"):
@@ -2136,20 +2157,29 @@ def backup_repositories(args, output_directory, repositories):
21362157
if not repository.get("is_gist")
21372158
else repository.get("id")
21382159
)
2139-
fetch_repository(
2140-
repo_name,
2141-
repo_url,
2142-
repo_dir,
2143-
skip_existing=args.skip_existing,
2144-
bare_clone=args.bare_clone,
2145-
lfs_clone=args.lfs_clone,
2146-
no_prune=args.no_prune,
2147-
)
2160+
if repository.get("is_gist") and gist_backup_is_current(
2161+
repository, repo_cwd, repo_dir
2162+
):
2163+
logger.debug(
2164+
"Skipping gist {0} (unchanged since last backup)".format(repo_name)
2165+
)
2166+
skipped_unchanged_gists += 1
2167+
else:
2168+
fetch_repository(
2169+
repo_name,
2170+
repo_url,
2171+
repo_dir,
2172+
skip_existing=args.skip_existing,
2173+
bare_clone=args.bare_clone,
2174+
lfs_clone=args.lfs_clone,
2175+
no_prune=args.no_prune,
2176+
)
21482177

21492178
if repository.get("is_gist"):
2150-
# dump gist information to a file as well; the clone may have
2151-
# been skipped (e.g. DMCA-blocked or empty gist), so make sure
2152-
# the directory exists
2179+
# dump gist information to a file as well, even when the fetch
2180+
# was skipped, so listing metadata (fork counts etc.) stays
2181+
# fresh; the clone may also have been skipped entirely (e.g.
2182+
# DMCA-blocked or empty gist), so make sure the directory exists
21532183
mkdir_p(repo_cwd)
21542184
output_file = "{0}/gist.json".format(repo_cwd)
21552185
with codecs.open(output_file, "w", encoding="utf-8") as f:
@@ -2219,6 +2249,11 @@ def backup_repositories(args, output_directory, repositories):
22192249
logger.info(f"Skipping remaining resources for {repository['full_name']}")
22202250
continue
22212251

2252+
if skipped_unchanged_gists:
2253+
logger.info(
2254+
"Skipped {0} unchanged gists".format(skipped_unchanged_gists)
2255+
)
2256+
22222257
if incremental_resource_work_attempted:
22232258
remove_legacy_last_update_if_migrated(
22242259
args, output_directory, legacy_last_update_path

0 commit comments

Comments
 (0)