GeezerVison is showing github.com — Support index diffs against empty tree · gitpython-developers/GitPython@3895682
File treeExpand file treeCollapse file tree Open diff view settings Expand file treeCollapse file tree Open diff view settings Collapse file Copy file name to clipboardExpand all lines: git/index/base.py +40-3Lines changed: 40 additions & 3 deletions | 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 is git_diff.NULL_TREE: | | 1515 | + args: List[Union[PathLike, str]] = [ | | 1516 | + "--cached", | | 1517 | + "4b825dc642cb6eb9a060e54bf8d69288fbee4904", | | 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. | |
Collapse file Copy file name to clipboardExpand all lines: test/test_index.py +29-1Lines changed: 29 additions & 1 deletion | Original file line number | Diff line number | Diff line change |
|---|
| 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 | 27 | from git.exc import ( | 28 | 28 | CheckoutError, | 29 | 29 | GitCommandError, | @@ -555,6 +555,34 @@ def test_index_file_diffing(self, rw_repo): | 555 | 555 | rval = index.checkout("lib") | 556 | 556 | assert len(list(rval)) > 1 | 557 | 557 |
| | 558 | + @with_rw_directory | | 559 | + def test_index_file_diff_null_tree_with_initial_index(self, rw_dir): | | 560 | + repo = Repo.init(rw_dir) | | 561 | + filename = ".gitkeep" | | 562 | + file_path = osp.join(repo.working_tree_dir, filename) | | 563 | + with open(file_path, "w") as fp: | | 564 | + fp.write("# Initial file\n") | | 565 | + | | 566 | + index = repo.index | | 567 | + index.add([filename]) | | 568 | + index.write() | | 569 | + | | 570 | + index = IndexFile(repo) | | 571 | + assert not index.diff(None) | | 572 | + | | 573 | + diff = index.diff(NULL_TREE) | | 574 | + self.assertEqual(len(diff), 1) | | 575 | + self.assertEqual(diff[0].change_type, "A") | | 576 | + assert diff[0].new_file | | 577 | + self.assertEqual(diff[0].b_path, filename) | | 578 | + | | 579 | + self.assertEqual(len(index.diff(NULL_TREE, paths=filename)), 1) | | 580 | + self.assertEqual(len(index.diff(NULL_TREE, paths="missing")), 0) | | 581 | + | | 582 | + patch = index.diff(NULL_TREE, create_patch=True) | | 583 | + self.assertEqual(len(patch), 1) | | 584 | + self.assertIn(b"+# Initial file", patch[0].diff) | | 585 | + | 558 | 586 | def _count_existing(self, repo, files): | 559 | 587 | """Return count of files that actually exist in the repository directory.""" | 560 | 588 | existing = 0 | |
|