| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 6492e1b commit cd22bfc
7 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1108,6 +1108,20 @@ compatibility bug or reduction in CLI calls. | |||
| 1108 | 1108 | | Config-backed remote/submodule maintenance | Missing config enumeration/multivar/removal operations (GIX-12), plus filesystem and worktree lifecycle requirements. | | |
| 1109 | 1109 | | Hook execution | Every explicit hook request, including an absent hook, retains Git-managed lookup, execution and diagnostics until GIX-23 is addressed. Native operations retain GitPython's default hook/fsmonitor/maintenance restrictions. | | |
| 1110 | 1110 | ||
| 1111 | + ### Submodule transport policy | ||
| 1112 | + | ||
| 1113 | + Submodule clone and fetch stay on the CLI and pass `GIT_PROTOCOL_FROM_USER=0` | ||
| 1114 | + for URLs from `.gitmodules`, matching `git submodule update --init` and | ||
| 1115 | + `git submodule update --remote`. A `protocol.file.allow=user` policy therefore | ||
| 1116 | + rejects the file transport, while `always` permits it. The existing explicit | ||
| 1117 | + `allow_unsafe_protocols=True` opt-in preserves the caller's environment policy; | ||
| 1118 | + `user` is accepted only when `GIT_PROTOCOL_FROM_USER` is unset or permits it. | ||
| 1119 | + The regression compares both backends with Git 2.54.0, including unchanged | ||
| 1120 | + checkouts after denied transfers. | ||
| 1121 | + GixPython 0.2.0 still needs the clone/environment and fetch-result contracts | ||
| 1122 | + listed above before these calls can move to Gix. This is a shared GitPython | ||
| 1123 | + policy bug, not a demonstrated Gix compatibility mismatch. | ||
| 1124 | + | ||
| 1111 | 1125 | ### Downstream mirror-fetch result gap | |
| 1112 | 1126 | ||
| 1113 | 1127 | Airflow Git provider 1.0.1's bare-cache refspecs | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -371,6 +371,11 @@ def _module_abspath(cls, parent_repo: "Repo", path: PathLike, name: str) -> Path | |||
| 371 | 371 | ) | |
| 372 | 372 | raise NotADirectoryError() | |
| 373 | 373 | ||
| 374 | + @classmethod | ||
| 375 | + def _transport_env(cls, allow_unsafe_protocols: bool = False) -> Dict[str, str]: | ||
| 376 | + """Apply Git's non-user transport policy to URLs read from ``.gitmodules``.""" | ||
| 377 | + return {} if allow_unsafe_protocols else {"GIT_PROTOCOL_FROM_USER": "0"} | ||
| 378 | + | ||
| 374 | 379 | @classmethod | |
| 375 | 380 | def _clone_repo( | |
| 376 | 381 | cls, | |
@@ -940,7 +945,10 @@ def update( | |||
| 940 | 945 | They only take effect with the `init` option. | |
| 941 | 946 | ||
| 942 | 947 | :param allow_unsafe_protocols: | |
| 943 | - Allow unsafe protocols to be used, like ``ext``. | ||
| 948 | + Allow unsafe protocols to be used, like ``ext``. Clone and fetch also | ||
| 949 | + preserve the caller's ``GIT_PROTOCOL_FROM_USER`` policy instead of | ||
| 950 | + forcing it to ``0``. A ``user`` transport such as ``file`` is then | ||
| 951 | + accepted only when that environment policy permits it. | ||
| 944 | 952 | ||
| 945 | 953 | :param allow_unsafe_options: | |
| 946 | 954 | Allow unsafe options to be used, like ``--upload-pack``. | |
@@ -992,7 +1000,8 @@ def fetch_remotes(module_repo: "Repo") -> None: | |||
| 992 | 1000 | ) | |
| 993 | 1001 | # =============================== | |
| 994 | 1002 | if not dry_run: | |
| 995 | - remote.fetch(progress=progress) | ||
| 1003 | + with module_repo.git.custom_environment(**self._transport_env(allow_unsafe_protocols)): | ||
| 1004 | + remote.fetch(progress=progress) | ||
| 996 | 1005 | # END handle dry-run | |
| 997 | 1006 | # =============================== | |
| 998 | 1007 | if i == len_rmts - 1: | |
@@ -1080,7 +1089,7 @@ def fetch_remotes(module_repo: "Repo") -> None: | |||
| 1080 | 1089 | self.path, | |
| 1081 | 1090 | self.name, | |
| 1082 | 1091 | n=True, | |
| 1083 | - env=env, | ||
| 1092 | + env={**self._transport_env(allow_unsafe_protocols), **(env or {})}, | ||
| 1084 | 1093 | multi_options=clone_multi_options, | |
| 1085 | 1094 | allow_unsafe_options=allow_unsafe_options, | |
| 1086 | 1095 | allow_unsafe_protocols=allow_unsafe_protocols, | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -10,6 +10,7 @@ | |||
| 10 | 10 | "with_rw_directory", | |
| 11 | 11 | "with_rw_repo", | |
| 12 | 12 | "with_rw_and_rw_remote_repo", | |
| 13 | + "patch_git_config", | ||
| 13 | 14 | "PathLikeMock", | |
| 14 | 15 | "TestBase", | |
| 15 | 16 | "TestCase", | |
@@ -36,6 +37,7 @@ | |||
| 36 | 37 | import textwrap | |
| 37 | 38 | import time | |
| 38 | 39 | import unittest | |
| 40 | + from unittest import mock | ||
| 39 | 41 | from typing import Union, Type, Tuple | |
| 40 | 42 | ||
| 41 | 43 | import pytest | |
@@ -82,6 +84,26 @@ def fixture(name): | |||
| 82 | 84 | # { Adapters | |
| 83 | 85 | ||
| 84 | 86 | ||
| 87 | + @contextlib.contextmanager | ||
| 88 | + def patch_git_config(name, value): | ||
| 89 | + """Temporarily add a git config name-value pair, using environment variables.""" | ||
| 90 | + pair_index = int(os.getenv("GIT_CONFIG_COUNT", "0")) | ||
| 91 | + | ||
| 92 | + # This is recomputed each time the context is entered, for compatibility with | ||
| 93 | + # existing GIT_CONFIG_* environment variables, even if changed in this process. | ||
| 94 | + patcher = mock.patch.dict( | ||
| 95 | + os.environ, | ||
| 96 | + { | ||
| 97 | + "GIT_CONFIG_COUNT": str(pair_index + 1), | ||
| 98 | + f"GIT_CONFIG_KEY_{pair_index}": name, | ||
| 99 | + f"GIT_CONFIG_VALUE_{pair_index}": value, | ||
| 100 | + }, | ||
| 101 | + ) | ||
| 102 | + | ||
| 103 | + with patcher: | ||
| 104 | + yield | ||
| 105 | + | ||
| 106 | + | ||
| 85 | 107 | class StringProcessAdapter: | |
| 86 | 108 | """Allows strings to be used as process objects returned by subprocess.Popen. | |
| 87 | 109 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -7,7 +7,7 @@ | |||
| 7 | 7 | import os | |
| 8 | 8 | import os.path | |
| 9 | 9 | ||
| 10 | - from test.lib import TestBase | ||
| 10 | + from test.lib import TestBase, patch_git_config | ||
| 11 | 11 | from test.lib.helper import with_rw_directory, with_rw_repo | |
| 12 | 12 | from test.lib.fixtures import writable_fixture | |
| 13 | 13 | ||
@@ -25,6 +25,7 @@ def tearDown(self): | |||
| 25 | 25 | # "'C:\\Users\\appveyor\\AppData\\Local\\Temp\\1\\test_work_tree_unsupportedryfa60di\\master_repo\\.git\\objects\\pack\\pack-bc9e0787aef9f69e1591ef38ea0a6f566ec66fe3.idx") # noqa: E501 | |
| 26 | 26 | @with_rw_repo("HEAD") | |
| 27 | 27 | @with_rw_directory | |
| 28 | + @patch_git_config("protocol.file.allow", "always") | ||
| 28 | 29 | def test_init_repo_object(self, rw_dir, rw_repo): | |
| 29 | 30 | # [1-test_init_repo_object] | |
| 30 | 31 | from git import Repo | |
@@ -484,6 +485,7 @@ def test_references_and_objects(self, rw_dir): | |||
| 484 | 485 | repo.git.clear_cache() | |
| 485 | 486 | ||
| 486 | 487 | @with_rw_repo("c15a6e1923a14bc760851913858a3942a4193cdb") | |
| 488 | + @patch_git_config("protocol.file.allow", "always") | ||
| 487 | 489 | def test_submodules(self, repo): | |
| 488 | 490 | # [1-test_submodules] | |
| 489 | 491 | sms = repo.submodules | |
| Back | FazBrowse Home | New Git URL |
0 commit comments