github-backup 0.53.0__py3-none-any.whl → 0.55.0__py3-none-any.whl

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.
github_backup/__init__.py CHANGED
@@ -1 +1 @@
1
- __version__ = "0.53.0"
1
+ __version__ = "0.55.0"
@@ -561,7 +561,7 @@ def get_github_host(args):
561
561
 
562
562
 
563
563
  def read_file_contents(file_uri):
564
- return open(file_uri[len(FILE_URI_PREFIX) :], "rt").readline().strip()
564
+ return open(file_uri[len(FILE_URI_PREFIX):], "rt").readline().strip()
565
565
 
566
566
 
567
567
  def get_github_repo_url(args, repository):
@@ -1565,16 +1565,22 @@ def retrieve_repositories(args, authenticated_user):
1565
1565
  repos.extend(gists)
1566
1566
 
1567
1567
  if args.include_starred_gists:
1568
- starred_gists_template = "https://{0}/gists/starred".format(
1569
- get_github_api_host(args)
1570
- )
1571
- starred_gists = retrieve_data(
1572
- args, starred_gists_template, single_request=False
1573
- )
1574
- # flag each repo as a starred gist for downstream processing
1575
- for item in starred_gists:
1576
- item.update({"is_gist": True, "is_starred": True})
1577
- repos.extend(starred_gists)
1568
+ if not authenticated_user.get("login") or args.user.lower() != authenticated_user["login"].lower():
1569
+ logger.warning(
1570
+ "Cannot retrieve starred gists for '%s'. GitHub only allows access to the authenticated user's starred gists.",
1571
+ args.user,
1572
+ )
1573
+ else:
1574
+ starred_gists_template = "https://{0}/gists/starred".format(
1575
+ get_github_api_host(args)
1576
+ )
1577
+ starred_gists = retrieve_data(
1578
+ args, starred_gists_template, single_request=False
1579
+ )
1580
+ # flag each repo as a starred gist for downstream processing
1581
+ for item in starred_gists:
1582
+ item.update({"is_gist": True, "is_starred": True})
1583
+ repos.extend(starred_gists)
1578
1584
 
1579
1585
  return repos
1580
1586
 
@@ -1666,9 +1672,10 @@ def backup_repositories(args, output_directory, repositories):
1666
1672
  repo_url = get_github_repo_url(args, repository)
1667
1673
 
1668
1674
  include_gists = args.include_gists or args.include_starred_gists
1675
+ include_starred = args.all_starred and repository.get("is_starred")
1669
1676
  if (args.include_repository or args.include_everything) or (
1670
1677
  include_gists and repository.get("is_gist")
1671
- ):
1678
+ ) or include_starred:
1672
1679
  repo_name = (
1673
1680
  repository.get("name")
1674
1681
  if not repository.get("is_gist")
@@ -2017,12 +2024,9 @@ def fetch_repository(
2017
2024
  ):
2018
2025
  if bare_clone:
2019
2026
  if os.path.exists(local_dir):
2020
- clone_exists = (
2021
- subprocess.check_output(
2022
- ["git", "rev-parse", "--is-bare-repository"], cwd=local_dir
2023
- )
2024
- == b"true\n"
2025
- )
2027
+ clone_exists = subprocess.check_output(
2028
+ ["git", "rev-parse", "--is-bare-repository"], cwd=local_dir
2029
+ ) == b"true\n"
2026
2030
  else:
2027
2031
  clone_exists = False
2028
2032
  else:
@@ -2037,11 +2041,14 @@ def fetch_repository(
2037
2041
  "git ls-remote " + remote_url, stdout=FNULL, stderr=FNULL, shell=True
2038
2042
  )
2039
2043
  if initialized == 128:
2040
- logger.info(
2041
- "Skipping {0} ({1}) since it's not initialized".format(
2042
- name, masked_remote_url
2044
+ if ".wiki.git" in remote_url:
2045
+ logger.info(
2046
+ "Skipping {0} wiki (wiki is enabled but has no content)".format(name)
2047
+ )
2048
+ else:
2049
+ logger.info(
2050
+ "Skipping {0} (repository not accessible - may be empty, private, or credentials invalid)".format(name)
2043
2051
  )
2044
- )
2045
2052
  return
2046
2053
 
2047
2054
  if clone_exists:
@@ -9,6 +9,7 @@ from github_backup.github_backup import (
9
9
  backup_repositories,
10
10
  check_git_lfs_install,
11
11
  filter_repositories,
12
+ get_auth,
12
13
  get_authenticated_user,
13
14
  logger,
14
15
  mkdir_p,
@@ -16,16 +17,33 @@ from github_backup.github_backup import (
16
17
  retrieve_repositories,
17
18
  )
18
19
 
19
- logging.basicConfig(
20
- format="%(asctime)s.%(msecs)03d: %(message)s",
20
+ # INFO and DEBUG go to stdout, WARNING and above go to stderr
21
+ log_format = logging.Formatter(
22
+ fmt="%(asctime)s.%(msecs)03d: %(message)s",
21
23
  datefmt="%Y-%m-%dT%H:%M:%S",
22
- level=logging.INFO,
23
24
  )
24
25
 
26
+ stdout_handler = logging.StreamHandler(sys.stdout)
27
+ stdout_handler.setLevel(logging.DEBUG)
28
+ stdout_handler.addFilter(lambda r: r.levelno < logging.WARNING)
29
+ stdout_handler.setFormatter(log_format)
30
+
31
+ stderr_handler = logging.StreamHandler(sys.stderr)
32
+ stderr_handler.setLevel(logging.WARNING)
33
+ stderr_handler.setFormatter(log_format)
34
+
35
+ logging.basicConfig(level=logging.INFO, handlers=[stdout_handler, stderr_handler])
36
+
25
37
 
26
38
  def main():
27
39
  args = parse_args()
28
40
 
41
+ if args.private and not get_auth(args):
42
+ logger.warning(
43
+ "The --private flag has no effect without authentication. "
44
+ "Use -t/--token, -f/--token-fine, or -u/--username to authenticate."
45
+ )
46
+
29
47
  if args.quiet:
30
48
  logger.setLevel(logging.WARNING)
31
49
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: github-backup
3
- Version: 0.53.0
3
+ Version: 0.55.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
@@ -311,11 +311,11 @@ If the incremental argument is used, this will result in the next backup only re
311
311
 
312
312
  It's therefore recommended to only use the incremental argument if the output/result is being actively monitored, or complimented with periodic full non-incremental runs, to avoid unexpected missing data in a regular backup runs.
313
313
 
314
- 1. **Starred public repo hooks blocking**
314
+ **Starred public repo hooks blocking**
315
315
 
316
- Since the ``--all`` argument includes ``--hooks``, if you use ``--all`` and ``--all-starred`` together to clone a users starred public repositories, the backup will likely error and block the backup continuing.
316
+ Since the ``--all`` argument includes ``--hooks``, if you use ``--all`` and ``--all-starred`` together to clone a users starred public repositories, the backup will likely error and block the backup continuing.
317
317
 
318
- This is due to needing the correct permission for ``--hooks`` on public repos.
318
+ This is due to needing the correct permission for ``--hooks`` on public repos.
319
319
 
320
320
 
321
321
  "bare" is actually "mirror"
@@ -331,6 +331,8 @@ Starred gists vs starred repo behaviour
331
331
 
332
332
  The starred normal repo cloning (``--all-starred``) argument stores starred repos separately to the users own repositories. However, using ``--starred-gists`` will store starred gists within the same directory as the users own gists ``--gists``. Also, all gist repo directory names are IDs not the gist's name.
333
333
 
334
+ Note: ``--starred-gists`` only retrieves starred gists for the authenticated user, not the target user, due to a GitHub API limitation.
335
+
334
336
 
335
337
  Skip existing on incomplete backups
336
338
  -----------------------------------
@@ -338,6 +340,25 @@ Skip existing on incomplete backups
338
340
  The ``--skip-existing`` argument will skip a backup if the directory already exists, even if the backup in that directory failed (perhaps due to a blocking error). This may result in unexpected missing data in a regular backup.
339
341
 
340
342
 
343
+ Updates use fetch, not pull
344
+ ---------------------------
345
+
346
+ When updating an existing repository backup, ``github-backup`` uses ``git fetch`` rather than ``git pull``. This is intentional - a backup tool should reliably download data without risk of failure. Using ``git pull`` would require handling merge conflicts, which adds complexity and could cause backups to fail unexpectedly.
347
+
348
+ With fetch, **all branches and commits are downloaded** safely into remote-tracking branches. The working directory files won't change, but your backup is complete.
349
+
350
+ If you look at files directly (e.g., ``cat README.md``), you'll see the old content. The new data is in the remote-tracking branches (confusingly named "remote" but stored locally). To view or use the latest files::
351
+
352
+ git show origin/main:README.md # view a file
353
+ git merge origin/main # update working directory
354
+
355
+ All branches are backed up as remote refs (``origin/main``, ``origin/feature-branch``, etc.).
356
+
357
+ If you want to browse files directly without merging, consider using ``--bare`` which skips the working directory entirely - the backup is just the git data.
358
+
359
+ See `#269 <https://github.com/josegonzalez/python-github-backup/issues/269>`_ for more discussion.
360
+
361
+
341
362
  Github Backup Examples
342
363
  ======================
343
364
 
@@ -387,7 +408,12 @@ A huge thanks to all the contibuters!
387
408
  Testing
388
409
  -------
389
410
 
390
- This project currently contains no unit tests. To run linting::
411
+ To run the test suite::
412
+
413
+ pip install pytest
414
+ pytest
415
+
416
+ To run linting::
391
417
 
392
418
  pip install flake8
393
419
  flake8 --ignore=E501
@@ -0,0 +1,9 @@
1
+ github_backup/__init__.py,sha256=UQLHFqXC6UhDcoKB4MFAazCsPAeQEfBN68BEvb4D2Tk,23
2
+ github_backup/github_backup.py,sha256=UMxNz_SWr7FGLYybd0RLtZu17vOwmUvZTMOlM3Uj6lk,80729
3
+ github_backup-0.55.0.data/scripts/github-backup,sha256=E-kXsqfjwG3h6z9wRgWOdmrCwdUBMNhJwH63sCiAPQw,2250
4
+ github_backup-0.55.0.dist-info/licenses/LICENSE.txt,sha256=ML-pLyn1qtAKo_DHMcQ8-p7k3f8cp-IR-mf5B49R2rk,1085
5
+ github_backup-0.55.0.dist-info/METADATA,sha256=xJ5GAGwpxzZhi7hBnMm4jRNtZLRKvU0lj4ClDZrd6RA,22937
6
+ github_backup-0.55.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
7
+ github_backup-0.55.0.dist-info/top_level.txt,sha256=Za6fKRAlxZ0b3ZBH_osPqklLe14LetdNAkvAQANT2AA,14
8
+ github_backup-0.55.0.dist-info/zip-safe,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
9
+ github_backup-0.55.0.dist-info/RECORD,,
@@ -1,9 +0,0 @@
1
- github_backup/__init__.py,sha256=btg9YcqDqo4fSYBUGAuFCISDFG2ovLMzO6BXZ916pVY,23
2
- github_backup/github_backup.py,sha256=-7oiAGDfavMxSiqWgaiyS5vYq31kFxOXgEH0Vw5MTIo,80149
3
- github_backup-0.53.0.data/scripts/github-backup,sha256=I79TNA67phytRmI9nm_LlD9h2zauXFOsOn9tYyAy9pU,1546
4
- github_backup-0.53.0.dist-info/licenses/LICENSE.txt,sha256=ML-pLyn1qtAKo_DHMcQ8-p7k3f8cp-IR-mf5B49R2rk,1085
5
- github_backup-0.53.0.dist-info/METADATA,sha256=fcDh7eOlfqyPFWkjuULwk8XzFoAQAa5Ld_gK_6CEc3g,21544
6
- github_backup-0.53.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
7
- github_backup-0.53.0.dist-info/top_level.txt,sha256=Za6fKRAlxZ0b3ZBH_osPqklLe14LetdNAkvAQANT2AA,14
8
- github_backup-0.53.0.dist-info/zip-safe,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
9
- github_backup-0.53.0.dist-info/RECORD,,