| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -3,7 +3,7 @@ | |||
| 3 | 3 | # This module is part of GitPython and is released under the | |
| 4 | 4 | # 3-Clause BSD License: https://opensource.org/license/bsd-3-clause/ | |
| 5 | 5 | ||
| 6 | - __all__ = ["DiffConstants", "NULL_TREE", "INDEX", "Diffable", "DiffIndex", "Diff"] | ||
| 6 | + __all__ = ["DiffConstants", "NULL_TREE", "NULL_TREE_SHA", "INDEX", "Diffable", "DiffIndex", "Diff"] | ||
| 7 | 7 | ||
| 8 | 8 | import enum | |
| 9 | 9 | import re | |
@@ -84,6 +84,9 @@ class DiffConstants(enum.Enum): | |||
| 84 | 84 | :const:`git.NULL_TREE` and :const:`Diffable.NULL_TREE`. | |
| 85 | 85 | """ | |
| 86 | 86 | ||
| 87 | + NULL_TREE_SHA = "4b825dc642cb6eb9a060e54bf8d69288fbee4904" | ||
| 88 | + """SHA of Git's canonical empty tree object.""" | ||
| 89 | + | ||
| 87 | 90 | INDEX: Literal[DiffConstants.INDEX] = DiffConstants.INDEX | |
| 88 | 91 | """Stand-in indicating you want to diff against the index. | |
| 89 | 92 | ||
@@ -599,7 +602,14 @@ def _index_from_patch_format(cls, repo: "Repo", proc: Union["Popen", "Git.AutoIn | |||
| 599 | 602 | ||
| 600 | 603 | # FIXME: Here SLURPING raw, need to re-phrase header-regexes linewise. | |
| 601 | 604 | text_list: List[bytes] = [] | |
| 602 | - handle_process_output(proc, text_list.append, None, finalize_process, decode_streams=False) | ||
| 605 | + stderr_list: List[bytes] = [] | ||
| 606 | + | ||
| 607 | + def finalize_process_with_stderr(proc: Union["Popen", "Git.AutoInterrupt"]) -> None: | ||
| 608 | + finalize_process(proc, stderr=b"".join(stderr_list)) | ||
| 609 | + | ||
| 610 | + handle_process_output( | ||
| 611 | + proc, text_list.append, stderr_list.append, finalize_process_with_stderr, decode_streams=False | ||
| 612 | + ) | ||
| 603 | 613 | ||
| 604 | 614 | # For now, we have to bake the stream. | |
| 605 | 615 | text = b"".join(text_list) | |
@@ -765,11 +775,16 @@ def _index_from_raw_format(cls, repo: "Repo", proc: "Popen") -> "DiffIndex[Diff] | |||
| 765 | 775 | # :100644 100644 687099101... 37c5e30c8... M .gitignore | |
| 766 | 776 | ||
| 767 | 777 | index: "DiffIndex" = DiffIndex() | |
| 778 | + stderr_list: List[bytes] = [] | ||
| 779 | + | ||
| 780 | + def finalize_process_with_stderr(proc: Union["Popen", "Git.AutoInterrupt"]) -> None: | ||
| 781 | + finalize_process(proc, stderr=b"".join(stderr_list)) | ||
| 782 | + | ||
| 768 | 783 | handle_process_output( | |
| 769 | 784 | proc, | |
| 770 | 785 | lambda byt: cls._handle_diff_line(byt, repo, index), | |
| 771 | - None, | ||
| 772 | - finalize_process, | ||
| 786 | + stderr_list.append, | ||
| 787 | + finalize_process_with_stderr, | ||
| 773 | 788 | decode_streams=False, | |
| 774 | 789 | ) | |
| 775 | 790 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1480,12 +1480,11 @@ def reset( | |||
| 1480 | 1480 | ||
| 1481 | 1481 | return self | |
| 1482 | 1482 | ||
| 1483 | - # FIXME: This is documented to accept the same parameters as Diffable.diff, but this | ||
| 1484 | - # does not handle NULL_TREE for `other`. (The suppressed mypy error is about this.) | ||
| 1485 | 1483 | def diff( | |
| 1486 | 1484 | self, | |
| 1487 | - other: Union[ # type: ignore[override] | ||
| 1485 | + other: Union[ | ||
| 1488 | 1486 | Literal[git_diff.DiffConstants.INDEX], | |
| 1487 | + Literal[git_diff.DiffConstants.NULL_TREE], | ||
| 1489 | 1488 | "Tree", | |
| 1490 | 1489 | "Commit", | |
| 1491 | 1490 | str, | |
@@ -1512,6 +1511,44 @@ def diff( | |||
| 1512 | 1511 | if other is self.INDEX: | |
| 1513 | 1512 | return git_diff.DiffIndex() | |
| 1514 | 1513 | ||
| 1514 | + if other == git_diff.NULL_TREE or other == git_diff.NULL_TREE_SHA: | ||
| 1515 | + args: List[Union[PathLike, str]] = [ | ||
| 1516 | + "--cached", | ||
| 1517 | + git_diff.NULL_TREE_SHA, | ||
| 1518 | + "--abbrev=40", | ||
| 1519 | + "--full-index", | ||
| 1520 | + ] | ||
| 1521 | + | ||
| 1522 | + if not any(x in kwargs for x in ("find_renames", "no_renames", "M")): | ||
| 1523 | + args.append("-M") | ||
| 1524 | + | ||
| 1525 | + if create_patch: | ||
| 1526 | + args.append("-p") | ||
| 1527 | + args.append("--no-ext-diff") | ||
| 1528 | + else: | ||
| 1529 | + args.append("--raw") | ||
| 1530 | + args.append("-z") | ||
| 1531 | + | ||
| 1532 | + args.append("--no-color") | ||
| 1533 | + | ||
| 1534 | + if paths is not None and not isinstance(paths, (tuple, list)): | ||
| 1535 | + paths = [paths] | ||
| 1536 | + | ||
| 1537 | + if paths: | ||
| 1538 | + args.append("--") | ||
| 1539 | + args.extend(paths) | ||
| 1540 | + | ||
| 1541 | + kwargs["as_process"] = True | ||
| 1542 | + proc = self.repo.git.diff(*args, **kwargs) | ||
| 1543 | + | ||
| 1544 | + diff_method = ( | ||
| 1545 | + git_diff.Diff._index_from_patch_format if create_patch else git_diff.Diff._index_from_raw_format | ||
| 1546 | + ) | ||
| 1547 | + index = diff_method(self.repo, proc) | ||
| 1548 | + | ||
| 1549 | + proc.wait() | ||
| 1550 | + return index | ||
| 1551 | + | ||
| 1515 | 1552 | # Index against anything but None is a reverse diff with the respective item. | |
| 1516 | 1553 | # Handle existing -R flags properly. | |
| 1517 | 1554 | # Transform strings to the object so that we can call diff on it. | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -90,7 +90,7 @@ def __init__(self, input_string): | |||
| 90 | 90 | self.stdout = io.BytesIO(input_string) | |
| 91 | 91 | self.stderr = io.BytesIO() | |
| 92 | 92 | ||
| 93 | - def wait(self): | ||
| 93 | + def wait(self, stderr=None): | ||
| 94 | 94 | return 0 | |
| 95 | 95 | ||
| 96 | 96 | poll = wait | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -23,7 +23,8 @@ | |||
| 23 | 23 | import ddt | |
| 24 | 24 | import pytest | |
| 25 | 25 | ||
| 26 | - from git import BlobFilter, Diff, Git, IndexFile, Object, Repo, Tree | ||
| 26 | + from git import BlobFilter, Diff, Git, IndexFile, NULL_TREE, Object, Repo, Tree | ||
| 27 | + from git.diff import NULL_TREE_SHA | ||
| 27 | 28 | from git.exc import ( | |
| 28 | 29 | CheckoutError, | |
| 29 | 30 | GitCommandError, | |
@@ -555,6 +556,39 @@ def test_index_file_diffing(self, rw_repo): | |||
| 555 | 556 | rval = index.checkout("lib") | |
| 556 | 557 | assert len(list(rval)) > 1 | |
| 557 | 558 | ||
| 559 | + @with_rw_directory | ||
| 560 | + def test_index_file_diff_null_tree_with_initial_index(self, rw_dir): | ||
| 561 | + repo = Repo.init(rw_dir) | ||
| 562 | + filename = ".gitkeep" | ||
| 563 | + file_path = osp.join(repo.working_tree_dir, filename) | ||
| 564 | + with open(file_path, "w") as fp: | ||
| 565 | + fp.write("# Initial file\n") | ||
| 566 | + | ||
| 567 | + index = repo.index | ||
| 568 | + index.add([filename]) | ||
| 569 | + index.write() | ||
| 570 | + | ||
| 571 | + index = IndexFile(repo) | ||
| 572 | + self.assertEqual(len(index.diff(None)), 0) | ||
| 573 | + | ||
| 574 | + diff = index.diff(NULL_TREE) | ||
| 575 | + self.assertEqual(len(diff), 1) | ||
| 576 | + self.assertEqual(diff[0].change_type, "A") | ||
| 577 | + assert diff[0].new_file | ||
| 578 | + self.assertEqual(diff[0].b_path, filename) | ||
| 579 | + | ||
| 580 | + self.assertEqual(len(index.diff(NULL_TREE, paths=filename)), 1) | ||
| 581 | + self.assertEqual(len(index.diff(NULL_TREE_SHA, paths=filename)), 1) | ||
| 582 | + self.assertEqual(len(index.diff(NULL_TREE, paths="missing")), 0) | ||
| 583 | + | ||
| 584 | + patch = index.diff(NULL_TREE, create_patch=True) | ||
| 585 | + self.assertEqual(len(patch), 1) | ||
| 586 | + self.assertIn(b"+# Initial file", patch[0].diff) | ||
| 587 | + | ||
| 588 | + with self.assertRaises(GitCommandError) as exc_info: | ||
| 589 | + index.diff(NULL_TREE, bogus_option=True) | ||
| 590 | + self.assertIn("usage: git diff", exc_info.exception.stderr) | ||
| 591 | + | ||
| 558 | 592 | def _count_existing(self, repo, files): | |
| 559 | 593 | """Return count of files that actually exist in the repository directory.""" | |
| 560 | 594 | existing = 0 | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -687,7 +687,12 @@ def test_multiple_urls(self, rw_repo): | |||
| 687 | 687 | ||
| 688 | 688 | def test_fetch_error(self): | |
| 689 | 689 | rem = self.rorepo.remote("origin") | |
| 690 | - with self.assertRaisesRegex(GitCommandError, "[Cc]ouldn't find remote ref __BAD_REF__"): | ||
| 690 | + msg = ( | ||
| 691 | + r"[Cc]ouldn't find remote ref __BAD_REF__|" | ||
| 692 | + r"could not read Username|" | ||
| 693 | + r"expected flush after ref listing" | ||
| 694 | + ) | ||
| 695 | + with self.assertRaisesRegex(GitCommandError, msg): | ||
| 691 | 696 | rem.fetch("__BAD_REF__") | |
| 692 | 697 | ||
| 693 | 698 | @with_rw_repo("0.1.6", bare=False) | |
| Back | FazBrowse Home | New Git URL |
0 commit comments