| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 07e8055 commit b1b585c
4 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -130,6 +130,8 @@ class IndexFile(LazyMixin, git_diff.Diffable, Serializable): | |||
| 130 | 130 | index directly before operating on it using the git command. | |
| 131 | 131 | """ | |
| 132 | 132 | ||
| 133 | + unsafe_git_checkout_index_options = ["--prefix"] | ||
| 134 | + | ||
| 133 | 135 | __slots__ = ("repo", "version", "entries", "_extension_data", "_file_path") | |
| 134 | 136 | ||
| 135 | 137 | _VERSION = 2 | |
@@ -1212,6 +1214,7 @@ def checkout( | |||
| 1212 | 1214 | paths: Union[None, Iterable[PathLike]] = None, | |
| 1213 | 1215 | force: bool = False, | |
| 1214 | 1216 | fprogress: Callable = lambda *args: None, | |
| 1217 | + allow_unsafe_options: bool = False, | ||
| 1215 | 1218 | **kwargs: Any, | |
| 1216 | 1219 | ) -> Union[None, Iterator[PathLike], Sequence[PathLike]]: | |
| 1217 | 1220 | """Check out the given paths or all files from the version known to the index | |
@@ -1238,6 +1241,9 @@ def checkout( | |||
| 1238 | 1241 | no explicit paths are given. Otherwise progress information will be send | |
| 1239 | 1242 | prior and after a file has been checked out. | |
| 1240 | 1243 | ||
| 1244 | + :param allow_unsafe_options: | ||
| 1245 | + Allow unsafe options, such as ``--prefix``. | ||
| 1246 | + | ||
| 1241 | 1247 | :param kwargs: | |
| 1242 | 1248 | Additional arguments to be passed to :manpage:`git-checkout-index(1)`. | |
| 1243 | 1249 | ||
@@ -1261,6 +1267,12 @@ def checkout( | |||
| 1261 | 1267 | i.e. if you want :manpage:`git-checkout(1)`-like behaviour, use | |
| 1262 | 1268 | ``head.checkout`` instead of ``index.checkout``. | |
| 1263 | 1269 | """ | |
| 1270 | + if not allow_unsafe_options: | ||
| 1271 | + Git.check_unsafe_options( | ||
| 1272 | + options=Git._option_candidates([], kwargs), | ||
| 1273 | + unsafe_options=self.unsafe_git_checkout_index_options, | ||
| 1274 | + ) | ||
| 1275 | + | ||
| 1264 | 1276 | args = ["--index"] | |
| 1265 | 1277 | if force: | |
| 1266 | 1278 | args.append("--force") | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -16,6 +16,7 @@ | |||
| 16 | 16 | ||
| 17 | 17 | from typing import Any, TYPE_CHECKING, Type, Union | |
| 18 | 18 | ||
| 19 | + from git.cmd import Git | ||
| 19 | 20 | from git.types import AnyGitObject, PathLike | |
| 20 | 21 | ||
| 21 | 22 | if TYPE_CHECKING: | |
@@ -42,6 +43,8 @@ class TagReference(Reference): | |||
| 42 | 43 | ||
| 43 | 44 | __slots__ = () | |
| 44 | 45 | ||
| 46 | + unsafe_git_tag_options = ["--file", "-F"] | ||
| 47 | + | ||
| 45 | 48 | _common_default = "tags" | |
| 46 | 49 | _common_path_default = Reference._common_path_default + "/" + _common_default | |
| 47 | 50 | ||
@@ -92,6 +95,7 @@ def create( | |||
| 92 | 95 | reference: Union[str, "SymbolicReference"] = "HEAD", | |
| 93 | 96 | logmsg: Union[str, None] = None, | |
| 94 | 97 | force: bool = False, | |
| 98 | + allow_unsafe_options: bool = False, | ||
| 95 | 99 | **kwargs: Any, | |
| 96 | 100 | ) -> "TagReference": | |
| 97 | 101 | """Create a new tag reference. | |
@@ -121,12 +125,21 @@ def create( | |||
| 121 | 125 | :param force: | |
| 122 | 126 | If ``True``, force creation of a tag even though that tag already exists. | |
| 123 | 127 | ||
| 128 | + :param allow_unsafe_options: | ||
| 129 | + Allow unsafe options, such as ``--file``. | ||
| 130 | + | ||
| 124 | 131 | :param kwargs: | |
| 125 | 132 | Additional keyword arguments to be passed to :manpage:`git-tag(1)`. | |
| 126 | 133 | ||
| 127 | 134 | :return: | |
| 128 | 135 | A new :class:`TagReference`. | |
| 129 | 136 | """ | |
| 137 | + if not allow_unsafe_options: | ||
| 138 | + Git.check_unsafe_options( | ||
| 139 | + options=Git._option_candidates([], kwargs), | ||
| 140 | + unsafe_options=cls.unsafe_git_tag_options, | ||
| 141 | + ) | ||
| 142 | + | ||
| 130 | 143 | if "ref" in kwargs and kwargs["ref"]: | |
| 131 | 144 | reference = kwargs["ref"] | |
| 132 | 145 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -31,6 +31,7 @@ | |||
| 31 | 31 | HookExecutionError, | |
| 32 | 32 | InvalidGitRepositoryError, | |
| 33 | 33 | UnmergedEntriesError, | |
| 34 | + UnsafeOptionError, | ||
| 34 | 35 | ) | |
| 35 | 36 | from git.index.fun import hook_path, run_commit_hook | |
| 36 | 37 | from git.index.typ import BaseIndexEntry, IndexEntry | |
@@ -202,6 +203,15 @@ def _make_hook(git_dir, name, content, make_exec=True): | |||
| 202 | 203 | ||
| 203 | 204 | @ddt.ddt | |
| 204 | 205 | class TestIndex(TestBase): | |
| 206 | + @with_rw_repo("HEAD") | ||
| 207 | + def test_checkout_rejects_unsafe_prefix(self, rw_repo): | ||
| 208 | + with tempfile.TemporaryDirectory() as target: | ||
| 209 | + with self.assertRaises(UnsafeOptionError): | ||
| 210 | + rw_repo.index.checkout(prefix=f"{target}/") | ||
| 211 | + | ||
| 212 | + rw_repo.index.checkout(prefix=f"{target}/", allow_unsafe_options=True) | ||
| 213 | + self.assertTrue(osp.isfile(osp.join(target, "CHANGES"))) | ||
| 214 | + | ||
| 205 | 215 | def __init__(self, *args): | |
| 206 | 216 | super().__init__(*args) | |
| 207 | 217 | self._reset_progress() | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -23,6 +23,7 @@ | |||
| 23 | 23 | SymbolicReference, | |
| 24 | 24 | TagReference, | |
| 25 | 25 | ) | |
| 26 | + from git.exc import UnsafeOptionError | ||
| 26 | 27 | from git.objects.tag import TagObject | |
| 27 | 28 | import git.refs as refs | |
| 28 | 29 | from git.util import Actor | |
@@ -60,6 +61,18 @@ def test_from_path(self): | |||
| 60 | 61 | # Check remoteness | |
| 61 | 62 | assert Reference(self.rorepo, "refs/remotes/origin").is_remote() | |
| 62 | 63 | ||
| 64 | + @with_rw_repo("HEAD") | ||
| 65 | + def test_tag_create_rejects_unsafe_file_options(self, rw_repo): | ||
| 66 | + with tempfile.NamedTemporaryFile("w", encoding="utf-8") as message: | ||
| 67 | + message.write("private tag message") | ||
| 68 | + message.flush() | ||
| 69 | + for index, option in enumerate(({"F": message.name}, {"file": message.name})): | ||
| 70 | + with self.assertRaises(UnsafeOptionError): | ||
| 71 | + TagReference.create(rw_repo, f"unsafe-{index}", **option) | ||
| 72 | + | ||
| 73 | + tag = TagReference.create(rw_repo, "allowed-file", F=message.name, allow_unsafe_options=True) | ||
| 74 | + self.assertEqual(tag.tag.message, "private tag message") | ||
| 75 | + | ||
| 63 | 76 | def test_from_pathlike(self): | |
| 64 | 77 | # Should be able to create any reference directly. | |
| 65 | 78 | for ref_type in (Reference, Head, TagReference, RemoteReference): | |
| Back | FazBrowse Home | New Git URL |
0 commit comments