github-backup 0.55.0__tar.gz → 0.56.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (27) hide show
  1. {github_backup-0.55.0 → github_backup-0.56.0}/CHANGES.rst +95 -1
  2. {github_backup-0.55.0/github_backup.egg-info → github_backup-0.56.0}/PKG-INFO +22 -1
  3. {github_backup-0.55.0 → github_backup-0.56.0}/README +21 -0
  4. {github_backup-0.55.0 → github_backup-0.56.0}/README.rst +21 -0
  5. github_backup-0.56.0/github_backup/__init__.py +1 -0
  6. github_backup-0.56.0/github_backup/__main__.py +13 -0
  7. github_backup-0.55.0/bin/github-backup → github_backup-0.56.0/github_backup/cli.py +2 -0
  8. {github_backup-0.55.0 → github_backup-0.56.0}/github_backup/github_backup.py +12 -10
  9. {github_backup-0.55.0 → github_backup-0.56.0/github_backup.egg-info}/PKG-INFO +22 -1
  10. {github_backup-0.55.0 → github_backup-0.56.0}/github_backup.egg-info/SOURCES.txt +3 -1
  11. github_backup-0.56.0/github_backup.egg-info/entry_points.txt +2 -0
  12. {github_backup-0.55.0 → github_backup-0.56.0}/release-requirements.txt +4 -4
  13. {github_backup-0.55.0 → github_backup-0.56.0}/setup.py +5 -1
  14. github_backup-0.55.0/github_backup/__init__.py +0 -1
  15. {github_backup-0.55.0 → github_backup-0.56.0}/LICENSE.txt +0 -0
  16. {github_backup-0.55.0 → github_backup-0.56.0}/MANIFEST.in +0 -0
  17. {github_backup-0.55.0 → github_backup-0.56.0}/github_backup.egg-info/dependency_links.txt +0 -0
  18. {github_backup-0.55.0 → github_backup-0.56.0}/github_backup.egg-info/top_level.txt +0 -0
  19. {github_backup-0.55.0 → github_backup-0.56.0}/github_backup.egg-info/zip-safe +0 -0
  20. {github_backup-0.55.0 → github_backup-0.56.0}/requirements.txt +0 -0
  21. {github_backup-0.55.0 → github_backup-0.56.0}/setup.cfg +0 -0
  22. {github_backup-0.55.0 → github_backup-0.56.0}/tests/test_all_starred.py +0 -0
  23. {github_backup-0.55.0 → github_backup-0.56.0}/tests/test_attachments.py +0 -0
  24. {github_backup-0.55.0 → github_backup-0.56.0}/tests/test_case_sensitivity.py +0 -0
  25. {github_backup-0.55.0 → github_backup-0.56.0}/tests/test_http_451.py +0 -0
  26. {github_backup-0.55.0 → github_backup-0.56.0}/tests/test_json_dump_if_changed.py +0 -0
  27. {github_backup-0.55.0 → github_backup-0.56.0}/tests/test_pagination.py +0 -0
@@ -1,10 +1,104 @@
1
1
  Changelog
2
2
  =========
3
3
 
4
- 0.55.0 (2025-12-07)
4
+ 0.56.0 (2025-12-11)
5
5
  -------------------
6
6
  ------------------------
7
7
 
8
+ Fix
9
+ ~~~
10
+ - Replace deprecated git lfs clone with git clone + git lfs fetch --all.
11
+ [Rodos]
12
+
13
+ git lfs clone is deprecated - modern git clone handles LFS automatically.
14
+ Using git lfs fetch --all ensures all LFS objects across all refs are
15
+ backed up, matching the existing bare clone behavior and providing
16
+ complete LFS backups.
17
+
18
+ Closes #379
19
+ - Add Windows support with entry_points and os.replace. [Rodos]
20
+
21
+ - Replace os.rename() with os.replace() for atomic file operations
22
+ on Windows (os.rename fails if destination exists on Windows)
23
+ - Add entry_points console_scripts for proper .exe generation on Windows
24
+ - Create github_backup/cli.py with main() entry point
25
+ - Add github_backup/__main__.py for python -m github_backup support
26
+ - Keep bin/github-backup as thin wrapper for backwards compatibility
27
+
28
+ Closes #112
29
+
30
+ Other
31
+ ~~~~~
32
+ - Docs: add "Restoring from Backup" section to README. [Rodos]
33
+
34
+ Clarifies that this tool is backup-only with no inbuilt restore.
35
+ Documents that git repos can be pushed back, but issues/PRs have
36
+ GitHub API limitations affecting all backup tools.
37
+
38
+ Closes #246
39
+ - Chore(deps): bump urllib3 in the python-packages group.
40
+ [dependabot[bot]]
41
+
42
+ Bumps the python-packages group with 1 update: [urllib3](https://github.com/urllib3/urllib3).
43
+
44
+
45
+ Updates `urllib3` from 2.6.0 to 2.6.1
46
+ - [Release notes](https://github.com/urllib3/urllib3/releases)
47
+ - [Changelog](https://github.com/urllib3/urllib3/blob/main/CHANGES.rst)
48
+ - [Commits](https://github.com/urllib3/urllib3/compare/2.6.0...2.6.1)
49
+
50
+ ---
51
+ updated-dependencies:
52
+ - dependency-name: urllib3
53
+ dependency-version: 2.6.1
54
+ dependency-type: direct:production
55
+ update-type: version-update:semver-patch
56
+ dependency-group: python-packages
57
+ ...
58
+ - Chore(deps): bump the python-packages group with 3 updates.
59
+ [dependabot[bot]]
60
+
61
+ Bumps the python-packages group with 3 updates: [black](https://github.com/psf/black), [pytest](https://github.com/pytest-dev/pytest) and [platformdirs](https://github.com/tox-dev/platformdirs).
62
+
63
+
64
+ Updates `black` from 25.11.0 to 25.12.0
65
+ - [Release notes](https://github.com/psf/black/releases)
66
+ - [Changelog](https://github.com/psf/black/blob/main/CHANGES.md)
67
+ - [Commits](https://github.com/psf/black/compare/25.11.0...25.12.0)
68
+
69
+ Updates `pytest` from 9.0.1 to 9.0.2
70
+ - [Release notes](https://github.com/pytest-dev/pytest/releases)
71
+ - [Changelog](https://github.com/pytest-dev/pytest/blob/main/CHANGELOG.rst)
72
+ - [Commits](https://github.com/pytest-dev/pytest/compare/9.0.1...9.0.2)
73
+
74
+ Updates `platformdirs` from 4.5.0 to 4.5.1
75
+ - [Release notes](https://github.com/tox-dev/platformdirs/releases)
76
+ - [Changelog](https://github.com/tox-dev/platformdirs/blob/main/CHANGES.rst)
77
+ - [Commits](https://github.com/tox-dev/platformdirs/compare/4.5.0...4.5.1)
78
+
79
+ ---
80
+ updated-dependencies:
81
+ - dependency-name: black
82
+ dependency-version: 25.12.0
83
+ dependency-type: direct:production
84
+ update-type: version-update:semver-minor
85
+ dependency-group: python-packages
86
+ - dependency-name: pytest
87
+ dependency-version: 9.0.2
88
+ dependency-type: direct:production
89
+ update-type: version-update:semver-patch
90
+ dependency-group: python-packages
91
+ - dependency-name: platformdirs
92
+ dependency-version: 4.5.1
93
+ dependency-type: direct:production
94
+ update-type: version-update:semver-patch
95
+ dependency-group: python-packages
96
+ ...
97
+
98
+
99
+ 0.55.0 (2025-12-07)
100
+ -------------------
101
+
8
102
  Fix
9
103
  ~~~
10
104
  - Improve error messages for inaccessible repos and empty wikis. [Rodos]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: github-backup
3
- Version: 0.55.0
3
+ Version: 0.56.0
4
4
  Summary: backup a github user or organization
5
5
  Home-page: http://github.com/josegonzalez/python-github-backup
6
6
  Author: Jose Diaz-Gonzalez
@@ -245,6 +245,8 @@ When you use the ``--lfs`` option, you will need to make sure you have Git LFS i
245
245
 
246
246
  Instructions on how to do this can be found on https://git-lfs.github.com.
247
247
 
248
+ LFS objects are fetched for all refs, not just the current checkout, ensuring a complete backup of all LFS content across all branches and history.
249
+
248
250
 
249
251
  About Attachments
250
252
  -----------------
@@ -390,6 +392,25 @@ Debug an error/block or incomplete backup into a temporary directory. Omit "incr
390
392
  github-backup -f $FINE_ACCESS_TOKEN -o /tmp/github-backup/ -l debug -P --all-starred --starred --watched --followers --following --issues --issue-comments --issue-events --pulls --pull-comments --pull-commits --labels --milestones --repositories --wikis --releases --assets --pull-details --gists --starred-gists $GH_USER
391
393
 
392
394
 
395
+ Restoring from Backup
396
+ =====================
397
+
398
+ This tool creates backups only, there is no inbuilt restore command.
399
+
400
+ **Git repositories, wikis, and gists** can be restored by pushing them back to GitHub as you would any git repository. For example, to restore a bare repository backup::
401
+
402
+ cd /tmp/white-house/repositories/petitions/repository
403
+ git push --mirror git@github.com:WhiteHouse/petitions.git
404
+
405
+ **Issues, pull requests, comments, and other metadata** are saved as JSON files for archival purposes. The GitHub API does not support recreating this data faithfully, creating issues via the API has limitations:
406
+
407
+ - New issue/PR numbers are assigned (original numbers cannot be set)
408
+ - Timestamps reflect creation time (original dates cannot be set)
409
+ - The API caller becomes the author (original authors cannot be set)
410
+ - Cross-references between issues and PRs will break
411
+
412
+ These are GitHub API limitations that affect all backup and migration tools, not just this one. Recreating issues with these limitations via the GitHub API is an exercise for the reader. The JSON backups remain useful for searching, auditing, or manual reference.
413
+
393
414
 
394
415
  Development
395
416
  ===========
@@ -215,6 +215,8 @@ When you use the ``--lfs`` option, you will need to make sure you have Git LFS i
215
215
 
216
216
  Instructions on how to do this can be found on https://git-lfs.github.com.
217
217
 
218
+ LFS objects are fetched for all refs, not just the current checkout, ensuring a complete backup of all LFS content across all branches and history.
219
+
218
220
 
219
221
  About Attachments
220
222
  -----------------
@@ -360,6 +362,25 @@ Debug an error/block or incomplete backup into a temporary directory. Omit "incr
360
362
  github-backup -f $FINE_ACCESS_TOKEN -o /tmp/github-backup/ -l debug -P --all-starred --starred --watched --followers --following --issues --issue-comments --issue-events --pulls --pull-comments --pull-commits --labels --milestones --repositories --wikis --releases --assets --pull-details --gists --starred-gists $GH_USER
361
363
 
362
364
 
365
+ Restoring from Backup
366
+ =====================
367
+
368
+ This tool creates backups only, there is no inbuilt restore command.
369
+
370
+ **Git repositories, wikis, and gists** can be restored by pushing them back to GitHub as you would any git repository. For example, to restore a bare repository backup::
371
+
372
+ cd /tmp/white-house/repositories/petitions/repository
373
+ git push --mirror git@github.com:WhiteHouse/petitions.git
374
+
375
+ **Issues, pull requests, comments, and other metadata** are saved as JSON files for archival purposes. The GitHub API does not support recreating this data faithfully, creating issues via the API has limitations:
376
+
377
+ - New issue/PR numbers are assigned (original numbers cannot be set)
378
+ - Timestamps reflect creation time (original dates cannot be set)
379
+ - The API caller becomes the author (original authors cannot be set)
380
+ - Cross-references between issues and PRs will break
381
+
382
+ These are GitHub API limitations that affect all backup and migration tools, not just this one. Recreating issues with these limitations via the GitHub API is an exercise for the reader. The JSON backups remain useful for searching, auditing, or manual reference.
383
+
363
384
 
364
385
  Development
365
386
  ===========
@@ -215,6 +215,8 @@ When you use the ``--lfs`` option, you will need to make sure you have Git LFS i
215
215
 
216
216
  Instructions on how to do this can be found on https://git-lfs.github.com.
217
217
 
218
+ LFS objects are fetched for all refs, not just the current checkout, ensuring a complete backup of all LFS content across all branches and history.
219
+
218
220
 
219
221
  About Attachments
220
222
  -----------------
@@ -360,6 +362,25 @@ Debug an error/block or incomplete backup into a temporary directory. Omit "incr
360
362
  github-backup -f $FINE_ACCESS_TOKEN -o /tmp/github-backup/ -l debug -P --all-starred --starred --watched --followers --following --issues --issue-comments --issue-events --pulls --pull-comments --pull-commits --labels --milestones --repositories --wikis --releases --assets --pull-details --gists --starred-gists $GH_USER
361
363
 
362
364
 
365
+ Restoring from Backup
366
+ =====================
367
+
368
+ This tool creates backups only, there is no inbuilt restore command.
369
+
370
+ **Git repositories, wikis, and gists** can be restored by pushing them back to GitHub as you would any git repository. For example, to restore a bare repository backup::
371
+
372
+ cd /tmp/white-house/repositories/petitions/repository
373
+ git push --mirror git@github.com:WhiteHouse/petitions.git
374
+
375
+ **Issues, pull requests, comments, and other metadata** are saved as JSON files for archival purposes. The GitHub API does not support recreating this data faithfully, creating issues via the API has limitations:
376
+
377
+ - New issue/PR numbers are assigned (original numbers cannot be set)
378
+ - Timestamps reflect creation time (original dates cannot be set)
379
+ - The API caller becomes the author (original authors cannot be set)
380
+ - Cross-references between issues and PRs will break
381
+
382
+ These are GitHub API limitations that affect all backup and migration tools, not just this one. Recreating issues with these limitations via the GitHub API is an exercise for the reader. The JSON backups remain useful for searching, auditing, or manual reference.
383
+
363
384
 
364
385
  Development
365
386
  ===========
@@ -0,0 +1 @@
1
+ __version__ = "0.56.0"
@@ -0,0 +1,13 @@
1
+ """Allow running as: python -m github_backup"""
2
+
3
+ import sys
4
+
5
+ from github_backup.cli import main
6
+ from github_backup.github_backup import logger
7
+
8
+ if __name__ == "__main__":
9
+ try:
10
+ main()
11
+ except Exception as e:
12
+ logger.error(str(e))
13
+ sys.exit(1)
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env python
2
+ """Command-line interface for github-backup."""
2
3
 
3
4
  import logging
4
5
  import os
@@ -36,6 +37,7 @@ logging.basicConfig(level=logging.INFO, handlers=[stdout_handler, stderr_handler
36
37
 
37
38
 
38
39
  def main():
40
+ """Main entry point for github-backup CLI."""
39
41
  args = parse_args()
40
42
 
41
43
  if args.private and not get_auth(args):
@@ -1038,7 +1038,7 @@ def download_attachment_file(url, path, auth, as_app=False, fine=False):
1038
1038
  bytes_downloaded += len(chunk)
1039
1039
 
1040
1040
  # Atomic rename to final location
1041
- os.rename(temp_path, path)
1041
+ os.replace(temp_path, path)
1042
1042
 
1043
1043
  metadata["size_bytes"] = bytes_downloaded
1044
1044
  metadata["success"] = True
@@ -1459,7 +1459,7 @@ def download_attachments(
1459
1459
 
1460
1460
  # Rename to add extension (already atomic from download)
1461
1461
  try:
1462
- os.rename(filepath, final_filepath)
1462
+ os.replace(filepath, final_filepath)
1463
1463
  metadata["saved_as"] = os.path.basename(final_filepath)
1464
1464
  except Exception as e:
1465
1465
  logger.warning(
@@ -1490,7 +1490,7 @@ def download_attachments(
1490
1490
  manifest_path = os.path.join(attachments_dir, "manifest.json")
1491
1491
  with open(manifest_path + ".temp", "w") as f:
1492
1492
  json.dump(manifest, f, indent=2)
1493
- os.rename(manifest_path + ".temp", manifest_path) # Atomic write
1493
+ os.replace(manifest_path + ".temp", manifest_path) # Atomic write
1494
1494
  logger.debug(
1495
1495
  "Wrote manifest for {0} #{1}: {2} attachments".format(
1496
1496
  item_type_display, number, len(attachment_metadata_list)
@@ -1811,7 +1811,7 @@ def backup_issues(args, repo_cwd, repository, repos_template):
1811
1811
 
1812
1812
  with codecs.open(issue_file + ".temp", "w", encoding="utf-8") as f:
1813
1813
  json_dump(issue, f)
1814
- os.rename(issue_file + ".temp", issue_file) # Unlike json_dump, this is atomic
1814
+ os.replace(issue_file + ".temp", issue_file) # Atomic write
1815
1815
 
1816
1816
 
1817
1817
  def backup_pulls(args, repo_cwd, repository, repos_template):
@@ -1886,7 +1886,7 @@ def backup_pulls(args, repo_cwd, repository, repos_template):
1886
1886
 
1887
1887
  with codecs.open(pull_file + ".temp", "w", encoding="utf-8") as f:
1888
1888
  json_dump(pull, f)
1889
- os.rename(pull_file + ".temp", pull_file) # Unlike json_dump, this is atomic
1889
+ os.replace(pull_file + ".temp", pull_file) # Atomic write
1890
1890
 
1891
1891
 
1892
1892
  def backup_milestones(args, repo_cwd, repository, repos_template):
@@ -2090,11 +2090,13 @@ def fetch_repository(
2090
2090
  git_command.pop()
2091
2091
  logging_subprocess(git_command, cwd=local_dir)
2092
2092
  else:
2093
- if lfs_clone:
2094
- git_command = ["git", "lfs", "clone", remote_url, local_dir]
2095
- else:
2096
- git_command = ["git", "clone", remote_url, local_dir]
2093
+ git_command = ["git", "clone", remote_url, local_dir]
2097
2094
  logging_subprocess(git_command)
2095
+ if lfs_clone:
2096
+ git_command = ["git", "lfs", "fetch", "--all", "--prune"]
2097
+ if no_prune:
2098
+ git_command.pop()
2099
+ logging_subprocess(git_command, cwd=local_dir)
2098
2100
 
2099
2101
 
2100
2102
  def backup_account(args, output_directory):
@@ -2203,5 +2205,5 @@ def json_dump_if_changed(data, output_file_path):
2203
2205
  temp_file = output_file_path + ".temp"
2204
2206
  with codecs.open(temp_file, "w", encoding="utf-8") as f:
2205
2207
  f.write(new_content)
2206
- os.rename(temp_file, output_file_path) # Atomic on POSIX systems
2208
+ os.replace(temp_file, output_file_path) # Atomic write
2207
2209
  return True
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: github-backup
3
- Version: 0.55.0
3
+ Version: 0.56.0
4
4
  Summary: backup a github user or organization
5
5
  Home-page: http://github.com/josegonzalez/python-github-backup
6
6
  Author: Jose Diaz-Gonzalez
@@ -245,6 +245,8 @@ When you use the ``--lfs`` option, you will need to make sure you have Git LFS i
245
245
 
246
246
  Instructions on how to do this can be found on https://git-lfs.github.com.
247
247
 
248
+ LFS objects are fetched for all refs, not just the current checkout, ensuring a complete backup of all LFS content across all branches and history.
249
+
248
250
 
249
251
  About Attachments
250
252
  -----------------
@@ -390,6 +392,25 @@ Debug an error/block or incomplete backup into a temporary directory. Omit "incr
390
392
  github-backup -f $FINE_ACCESS_TOKEN -o /tmp/github-backup/ -l debug -P --all-starred --starred --watched --followers --following --issues --issue-comments --issue-events --pulls --pull-comments --pull-commits --labels --milestones --repositories --wikis --releases --assets --pull-details --gists --starred-gists $GH_USER
391
393
 
392
394
 
395
+ Restoring from Backup
396
+ =====================
397
+
398
+ This tool creates backups only, there is no inbuilt restore command.
399
+
400
+ **Git repositories, wikis, and gists** can be restored by pushing them back to GitHub as you would any git repository. For example, to restore a bare repository backup::
401
+
402
+ cd /tmp/white-house/repositories/petitions/repository
403
+ git push --mirror git@github.com:WhiteHouse/petitions.git
404
+
405
+ **Issues, pull requests, comments, and other metadata** are saved as JSON files for archival purposes. The GitHub API does not support recreating this data faithfully, creating issues via the API has limitations:
406
+
407
+ - New issue/PR numbers are assigned (original numbers cannot be set)
408
+ - Timestamps reflect creation time (original dates cannot be set)
409
+ - The API caller becomes the author (original authors cannot be set)
410
+ - Cross-references between issues and PRs will break
411
+
412
+ These are GitHub API limitations that affect all backup and migration tools, not just this one. Recreating issues with these limitations via the GitHub API is an exercise for the reader. The JSON backups remain useful for searching, auditing, or manual reference.
413
+
393
414
 
394
415
  Development
395
416
  ===========
@@ -6,12 +6,14 @@ README.rst
6
6
  release-requirements.txt
7
7
  requirements.txt
8
8
  setup.py
9
- bin/github-backup
10
9
  github_backup/__init__.py
10
+ github_backup/__main__.py
11
+ github_backup/cli.py
11
12
  github_backup/github_backup.py
12
13
  github_backup.egg-info/PKG-INFO
13
14
  github_backup.egg-info/SOURCES.txt
14
15
  github_backup.egg-info/dependency_links.txt
16
+ github_backup.egg-info/entry_points.txt
15
17
  github_backup.egg-info/top_level.txt
16
18
  github_backup.egg-info/zip-safe
17
19
  tests/test_all_starred.py
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ github-backup = github_backup.cli:main
@@ -1,5 +1,5 @@
1
1
  autopep8==2.3.2
2
- black==25.11.0
2
+ black==25.12.0
3
3
  bleach==6.3.0
4
4
  certifi==2025.11.12
5
5
  charset-normalizer==3.4.4
@@ -8,7 +8,7 @@ colorama==0.4.6
8
8
  docutils==0.22.3
9
9
  flake8==7.3.0
10
10
  gitchangelog==3.0.4
11
- pytest==9.0.1
11
+ pytest==9.0.2
12
12
  idna==3.11
13
13
  importlib-metadata==8.7.0
14
14
  jaraco.classes==3.4.0
@@ -21,7 +21,7 @@ mypy-extensions==1.1.0
21
21
  packaging==25.0
22
22
  pathspec==0.12.1
23
23
  pkginfo==1.12.1.2
24
- platformdirs==4.5.0
24
+ platformdirs==4.5.1
25
25
  pycodestyle==2.14.0
26
26
  pyflakes==3.4.0
27
27
  Pygments==2.19.2
@@ -35,6 +35,6 @@ setuptools==80.9.0
35
35
  six==1.17.0
36
36
  tqdm==4.67.1
37
37
  twine==6.2.0
38
- urllib3==2.6.0
38
+ urllib3==2.6.1
39
39
  webencodings==0.5.1
40
40
  zipp==3.23.0
@@ -33,7 +33,11 @@ setup(
33
33
  author="Jose Diaz-Gonzalez",
34
34
  author_email="github-backup@josediazgonzalez.com",
35
35
  packages=["github_backup"],
36
- scripts=["bin/github-backup"],
36
+ entry_points={
37
+ "console_scripts": [
38
+ "github-backup=github_backup.cli:main",
39
+ ],
40
+ },
37
41
  url="http://github.com/josegonzalez/python-github-backup",
38
42
  license="MIT",
39
43
  classifiers=[
@@ -1 +0,0 @@
1
- __version__ = "0.55.0"
File without changes