git-private2public 0.2.1__tar.gz → 0.2.2__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.
@@ -1,5 +1,10 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.2.2
4
+
5
+ - Fail closed with a concise redacted error when target-ref preflight times out.
6
+ - Prevent Git remote errors from echoing credential-bearing target URLs.
7
+
3
8
  ## 0.2.1
4
9
 
5
10
  - Add `.gitpublic/public/` overlays for public-only files after sanitization.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: git-private2public
3
- Version: 0.2.1
3
+ Version: 0.2.2
4
4
  Summary: Like .gitignore, but for what goes public. Keep a sanitized public mirror of your private repo.
5
5
  Project-URL: Homepage, https://github.com/megamen32/git-private2public
6
6
  Project-URL: Repository, https://github.com/megamen32/git-private2public
@@ -35,7 +35,7 @@ from pathlib import Path
35
35
  import time
36
36
  from typing import Iterable
37
37
 
38
- __version__ = "0.2.1"
38
+ __version__ = "0.2.2"
39
39
 
40
40
  try:
41
41
  import yaml
@@ -739,12 +739,14 @@ def create_snapshot_root(
739
739
 
740
740
 
741
741
  def _remote_ref_sha(url: str, ref: str) -> str:
742
- res = subprocess.run(
743
- ["git", "ls-remote", url, ref], capture_output=True, text=True, timeout=30
744
- )
742
+ try:
743
+ res = subprocess.run(
744
+ ["git", "ls-remote", url, ref], capture_output=True, text=True, timeout=30
745
+ )
746
+ except subprocess.TimeoutExpired:
747
+ raise SystemExit("cannot read target ref: operation timed out") from None
745
748
  if res.returncode != 0:
746
- err = (res.stderr or res.stdout).strip()
747
- raise SystemExit(f"cannot read target ref {ref}: {err}")
749
+ raise SystemExit("cannot read target ref")
748
750
  line = res.stdout.strip().splitlines()
749
751
  return line[0].split()[0] if line else ""
750
752
 
@@ -758,8 +760,8 @@ def _remote_refs(url: str) -> dict[str, str]:
758
760
  text=True,
759
761
  timeout=30,
760
762
  )
761
- except subprocess.TimeoutExpired as exc:
762
- raise SystemExit("cannot enumerate target refs: operation timed out") from exc
763
+ except subprocess.TimeoutExpired:
764
+ raise SystemExit("cannot enumerate target refs: operation timed out") from None
763
765
  if result.returncode != 0:
764
766
  raise SystemExit("cannot enumerate target refs")
765
767
  refs: dict[str, str] = {}
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "git-private2public"
3
- version = "0.2.1"
3
+ version = "0.2.2"
4
4
  description = "Like .gitignore, but for what goes public. Keep a sanitized public mirror of your private repo."
5
5
  readme = "README.md"
6
6
  license = {text = "MIT"}
@@ -115,8 +115,8 @@ def test_replace_rule_strips_separator_whitespace():
115
115
 
116
116
 
117
117
  def test_version_constant_matches_package_version():
118
- assert g.__version__ == "0.2.1"
119
- assert 'version = "0.2.1"' in (Path(__file__).parent.parent / "pyproject.toml").read_text()
118
+ assert g.__version__ == "0.2.2"
119
+ assert 'version = "0.2.2"' in (Path(__file__).parent.parent / "pyproject.toml").read_text()
120
120
 
121
121
 
122
122
  def test_gitpublic_secret_check_finds_only_replace_and_scan(tmp_path: Path):
@@ -462,6 +462,22 @@ def test_remote_ref_sha_reads_exact_sha(monkeypatch):
462
462
  assert g._remote_ref_sha("example", "refs/heads/main") == sha
463
463
 
464
464
 
465
+ def test_remote_ref_sha_timeout_fails_closed_without_url_leak(monkeypatch):
466
+ secret_url = "https://x-access-token:super-secret-token@example.test/private.git"
467
+
468
+ def timeout(*args, **kwargs):
469
+ raise subprocess.TimeoutExpired(args[0], timeout=30)
470
+
471
+ monkeypatch.setattr(g.subprocess, "run", timeout)
472
+ with pytest.raises(SystemExit) as error:
473
+ g._remote_ref_sha(secret_url, "refs/heads/main")
474
+
475
+ message = str(error.value)
476
+ assert message == "cannot read target ref: operation timed out"
477
+ assert secret_url not in message
478
+ assert "super-secret-token" not in message
479
+
480
+
465
481
  @pytest.mark.parametrize(
466
482
  "unexpected_ref",
467
483
  ["refs/heads/stale", "refs/tags/stale", "refs/notes/private"],