|
36 | 36 | Submodule, |
37 | 37 | Tree, |
38 | 38 | ) |
| 39 | +from git.compat import safe_decode |
39 | 40 | from git.exc import BadObject, UnsafeOptionError, UnsafeProtocolError |
40 | 41 | from git.repo.fun import find_worktree_git_dir |
41 | 42 | from git.util import bin_to_hex, cwd, rmfile, rmtree |
@@ -754,6 +755,35 @@ def test_blame_incremental(self, git): |
754 | 755 | ), |
755 | 756 | ) |
756 | 757 |
|
| 758 | + def test_blame_incremental_preserves_historical_paths(self): |
| 759 | + self.maxDiff = None |
| 760 | + paths = ( |
| 761 | + b"plain.txt", |
| 762 | + b" spaced name.txt ", |
| 763 | + "café.txt".encode(), |
| 764 | + b"byte-\xff.txt", |
| 765 | + b'"literal-\\303\\251.txt"', |
| 766 | + b'quote"name.txt', |
| 767 | + b"back\\slash.txt", |
| 768 | + b"control\a\b\t\n\v\f\r.txt", |
| 769 | + ) |
| 770 | + for quote_path in ("true", "false"): |
| 771 | + for i, path in enumerate(paths): |
| 772 | + with self.subTest(quote_path=quote_path, path=path), fixture_repo( |
| 773 | + "blame-paths.sh", quote_path, subdir=str(i) |
| 774 | + ) as repo: |
| 775 | + entries = list(repo.blame_incremental("HEAD", "current.txt")) |
| 776 | + original = repo.commit("HEAD~2") |
| 777 | + self.assertEqual( |
| 778 | + sorted(entries, key=lambda e: e.linenos.start), |
| 779 | + [ |
| 780 | + (original, range(1, 2), safe_decode(path), range(1, 2)), |
| 781 | + (repo.head.commit, range(2, 3), "current.txt", range(2, 3)), |
| 782 | + (original, range(3, 4), safe_decode(path), range(3, 4)), |
| 783 | + ], |
| 784 | + ) |
| 785 | + self.assertEqual(list(repo.blame("HEAD", "current.txt", incremental=True)), entries) |
| 786 | + |
757 | 787 | @mock.patch.object(Git, "_call_process") |
758 | 788 | def test_blame_complex_revision(self, git): |
759 | 789 | git.return_value = fixture("blame_complex_revision") |
|
0 commit comments