| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 19799d0 commit 040de4b
3 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -9,7 +9,7 @@ | |||
| 9 | 9 | import re | |
| 10 | 10 | import warnings | |
| 11 | 11 | ||
| 12 | - from git.cmd import handle_process_output | ||
| 12 | + from git.cmd import Git, handle_process_output | ||
| 13 | 13 | from git.compat import defenc | |
| 14 | 14 | from git.objects.blob import Blob | |
| 15 | 15 | from git.objects.util import mode_str_to_int | |
@@ -35,7 +35,6 @@ | |||
| 35 | 35 | if TYPE_CHECKING: | |
| 36 | 36 | from subprocess import Popen | |
| 37 | 37 | ||
| 38 | - from git.cmd import Git | ||
| 39 | 38 | from git.objects.base import IndexObject | |
| 40 | 39 | from git.objects.commit import Commit | |
| 41 | 40 | from git.objects.tree import Tree | |
@@ -190,6 +189,7 @@ def diff( | |||
| 190 | 189 | other: Union[DiffConstants, "Tree", "Commit", str, None] = INDEX, | |
| 191 | 190 | paths: Union[PathLike, List[PathLike], Tuple[PathLike, ...], None] = None, | |
| 192 | 191 | create_patch: bool = False, | |
| 192 | + allow_unsafe_options: bool = False, | ||
| 193 | 193 | **kwargs: Any, | |
| 194 | 194 | ) -> "DiffIndex[Diff]": | |
| 195 | 195 | """Create diffs between two items being trees, trees and index or an index and | |
@@ -219,6 +219,10 @@ def diff( | |||
| 219 | 219 | applied makes the self to other. Patches are somewhat costly as blobs have | |
| 220 | 220 | to be read and diffed. | |
| 221 | 221 | ||
| 222 | + :param allow_unsafe_options: | ||
| 223 | + If ``True``, allow options such as ``--output`` that can write to arbitrary | ||
| 224 | + filesystem paths. | ||
| 225 | + | ||
| 222 | 226 | :param kwargs: | |
| 223 | 227 | Additional arguments passed to :manpage:`git-diff(1)`, such as ``R=True`` to | |
| 224 | 228 | swap both sides of the diff. | |
@@ -231,6 +235,12 @@ def diff( | |||
| 231 | 235 | an instance of :class:`~git.objects.tree.Tree` or | |
| 232 | 236 | :class:`~git.objects.commit.Commit`, or a git command error will occur. | |
| 233 | 237 | """ | |
| 238 | + if not allow_unsafe_options: | ||
| 239 | + Git.check_unsafe_options( | ||
| 240 | + options=Git._option_candidates([other], kwargs), | ||
| 241 | + unsafe_options=self.repo.unsafe_git_revision_options, | ||
| 242 | + ) | ||
| 243 | + | ||
| 234 | 244 | args: List[Union[PathLike, Diffable]] = [] | |
| 235 | 245 | args.append("--abbrev=40") # We need full shas. | |
| 236 | 246 | args.append("--full-index") # Get full index paths, not only filenames. | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -23,6 +23,7 @@ | |||
| 23 | 23 | from gitdb.db import MemoryDB | |
| 24 | 24 | ||
| 25 | 25 | from git.compat import defenc, force_bytes | |
| 26 | + from git.cmd import Git | ||
| 26 | 27 | import git.diff as git_diff | |
| 27 | 28 | from git.exc import CheckoutError, GitCommandError, GitError, InvalidGitRepositoryError | |
| 28 | 29 | from git.objects import Blob, Commit, Object, Submodule, Tree | |
@@ -1492,6 +1493,7 @@ def diff( | |||
| 1492 | 1493 | ] = git_diff.INDEX, | |
| 1493 | 1494 | paths: Union[PathLike, List[PathLike], Tuple[PathLike, ...], None] = None, | |
| 1494 | 1495 | create_patch: bool = False, | |
| 1496 | + allow_unsafe_options: bool = False, | ||
| 1495 | 1497 | **kwargs: Any, | |
| 1496 | 1498 | ) -> git_diff.DiffIndex[git_diff.Diff]: | |
| 1497 | 1499 | """Diff this index against the working copy or a :class:`~git.objects.tree.Tree` | |
@@ -1504,6 +1506,12 @@ def diff( | |||
| 1504 | 1506 | Will only work with indices that represent the default git index as they | |
| 1505 | 1507 | have not been initialized with a stream. | |
| 1506 | 1508 | """ | |
| 1509 | + if not allow_unsafe_options: | ||
| 1510 | + Git.check_unsafe_options( | ||
| 1511 | + options=Git._option_candidates([other], kwargs), | ||
| 1512 | + unsafe_options=self.repo.unsafe_git_revision_options, | ||
| 1513 | + ) | ||
| 1514 | + | ||
| 1507 | 1515 | # Only run if we are the default repository index. | |
| 1508 | 1516 | if self._file_path != self._index_path(): | |
| 1509 | 1517 | raise AssertionError("Cannot call %r on indices that do not represent the default git index" % self.diff()) | |
@@ -1560,12 +1568,18 @@ def diff( | |||
| 1560 | 1568 | # Invert the existing R flag. | |
| 1561 | 1569 | cur_val = kwargs.get("R", False) | |
| 1562 | 1570 | kwargs["R"] = not cur_val | |
| 1563 | - return other.diff(self.INDEX, paths, create_patch, **kwargs) | ||
| 1571 | + return other.diff( | ||
| 1572 | + self.INDEX, | ||
| 1573 | + paths, | ||
| 1574 | + create_patch, | ||
| 1575 | + allow_unsafe_options=allow_unsafe_options, | ||
| 1576 | + **kwargs, | ||
| 1577 | + ) | ||
| 1564 | 1578 | # END diff against other item handling | |
| 1565 | 1579 | ||
| 1566 | 1580 | # If other is not None here, something is wrong. | |
| 1567 | 1581 | if other is not None: | |
| 1568 | 1582 | raise ValueError("other must be None, Diffable.INDEX, a Tree or Commit, was %r" % other) | |
| 1569 | 1583 | ||
| 1570 | 1584 | # Diff against working copy - can be handled by superclass natively. | |
| 1571 | - return super().diff(other, paths, create_patch, **kwargs) | ||
| 1585 | + return super().diff(other, paths, create_patch, allow_unsafe_options=allow_unsafe_options, **kwargs) | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -14,6 +14,7 @@ | |||
| 14 | 14 | ||
| 15 | 15 | from git import NULL_TREE, Diff, DiffIndex, Diffable, GitCommandError, Repo, Submodule | |
| 16 | 16 | from git.cmd import Git | |
| 17 | + from git.exc import UnsafeOptionError | ||
| 17 | 18 | ||
| 18 | 19 | from test.lib import StringProcessAdapter, TestBase, fixture, with_rw_directory | |
| 19 | 20 | ||
@@ -352,6 +353,25 @@ def test_diff_submodule(self): | |||
| 352 | 353 | self.assertIsInstance(diff.a_blob.size, int) | |
| 353 | 354 | self.assertIsInstance(diff.b_blob.size, int) | |
| 354 | 355 | ||
| 356 | + def test_diff_rejects_unsafe_output_options(self): | ||
| 357 | + commit = self.rorepo.head.commit | ||
| 358 | + | ||
| 359 | + calls = ( | ||
| 360 | + lambda target: commit.diff(output=target), | ||
| 361 | + lambda target: commit.diff(other=f"--output={target}"), | ||
| 362 | + lambda target: self.rorepo.index.diff(NULL_TREE, output=target), | ||
| 363 | + lambda target: self.rorepo.index.diff(f"--output={target}"), | ||
| 364 | + ) | ||
| 365 | + for index, call in enumerate(calls): | ||
| 366 | + target = osp.join(self.repo_dir, f"diff-output-{index}") | ||
| 367 | + with self.assertRaises(UnsafeOptionError): | ||
| 368 | + call(target) | ||
| 369 | + self.assertFalse(osp.exists(target)) | ||
| 370 | + | ||
| 371 | + allowed_target = osp.join(self.repo_dir, "allowed-diff-output") | ||
| 372 | + commit.diff(output=allowed_target, allow_unsafe_options=True) | ||
| 373 | + self.assertTrue(osp.isfile(allowed_target)) | ||
| 374 | + | ||
| 355 | 375 | def test_diff_interface(self): | |
| 356 | 376 | """Test a few variations of the main diff routine.""" | |
| 357 | 377 | assertion_map = {} | |
| Back | FazBrowse Home | New Git URL |
0 commit comments