From f2254af5d3fd183ec150740d517bd0f8070fc67d Mon Sep 17 00:00:00 2001 From: Andrej730 Date: Sat, 14 Sep 2024 10:45:53 +0500 Subject: [PATCH 1/4] _to_relative_path to support mixing slashes and backslashes Working on Windows you sometime end up having some paths with backslashes (windows native) and some with slashes - this PR will resolve the issue using gitpython for those kind of cases (see example below). It will also fix the issues if paths contain redundant separators or "..". ``` import git repo = git.Repo(r"C:\gittest") repo.index.add(r"C:\gittest\1.txt") # Traceback (most recent call last): # File "c:\second_test.py", line 5, in # repo.index.add(r"C:/gittest/2.txt") # File "Python311\Lib\site-packages\git\index\base.py", line 879, in add # paths, entries = self._preprocess_add_items(items) # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ # File "Python311\Lib\site-packages\git\index\base.py", line 672, in _preprocess_add_items # paths.append(self._to_relative_path(item)) # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ # File "Python311\Lib\site-packages\git\index\base.py", line 657, in _to_relative_path # raise ValueError("Absolute path %r is not in git repository at %r" % (path, self.repo.working_tree_dir)) # ValueError: Absolute path 'C:/gittest/2.txt' is not in git repository at 'C:\\gittest' repo.index.add(r"C:/gittest/2.txt") repo.index.commit("test") ``` --- git/index/base.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/git/index/base.py b/git/index/base.py index 47925ad1c..7f53e614a 100644 --- a/git/index/base.py +++ b/git/index/base.py @@ -653,7 +653,7 @@ def _to_relative_path(self, path: PathLike) -> PathLike: return path if self.repo.bare: raise InvalidGitRepositoryError("require non-bare repository") - if not str(path).startswith(str(self.repo.working_tree_dir)): + if not osp.normpath(str(path)).startswith(osp.normpath(str(self.repo.working_tree_dir))): raise ValueError("Absolute path %r is not in git repository at %r" % (path, self.repo.working_tree_dir)) return os.path.relpath(path, self.repo.working_tree_dir) From ca06b11efde845080354dac71e9062ea6d63ab84 Mon Sep 17 00:00:00 2001 From: Andrej730 Date: Sat, 14 Sep 2024 16:51:41 +0500 Subject: [PATCH 2/4] test adding a file using non-normalized path --- test/test_index.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/test/test_index.py b/test/test_index.py index 2684cfd81..efd5b83a6 100644 --- a/test/test_index.py +++ b/test/test_index.py @@ -1181,6 +1181,18 @@ def test_index_add_pathlike(self, rw_repo): rw_repo.index.add(file) + @with_rw_repo("HEAD") + def test_index_add_non_normalized_path(self, rw_repo): + git_dir = Path(rw_repo.git_dir) + + file = git_dir / "file.txt" + file.touch() + non_normalized_path = file.as_posix() + if os.name != "nt": + non_normalized_path = non_normalized_path.replace("/", "\\") + + rw_repo.index.add(non_normalized_path) + class TestIndexUtils: @pytest.mark.parametrize("file_path_type", [str, Path]) From 46740590f7918fd5b789c95db7e41fbda06fb46f Mon Sep 17 00:00:00 2001 From: Andrej730 Date: Sat, 14 Sep 2024 16:52:56 +0500 Subject: [PATCH 3/4] Remove redundant path normalization for working_tree_dir --- git/index/base.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/git/index/base.py b/git/index/base.py index 7f53e614a..39cc9143c 100644 --- a/git/index/base.py +++ b/git/index/base.py @@ -653,7 +653,7 @@ def _to_relative_path(self, path: PathLike) -> PathLike: return path if self.repo.bare: raise InvalidGitRepositoryError("require non-bare repository") - if not osp.normpath(str(path)).startswith(osp.normpath(str(self.repo.working_tree_dir))): + if not osp.normpath(str(path)).startswith(str(self.repo.working_tree_dir)): raise ValueError("Absolute path %r is not in git repository at %r" % (path, self.repo.working_tree_dir)) return os.path.relpath(path, self.repo.working_tree_dir) From 8327b82a1079f667006f649cb3f1bbdcc8792955 Mon Sep 17 00:00:00 2001 From: Andrej730 Date: Sat, 14 Sep 2024 21:18:18 +0500 Subject: [PATCH 4/4] Fix test failing on unix --- test/test_index.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/test_index.py b/test/test_index.py index efd5b83a6..c586a0b5a 100644 --- a/test/test_index.py +++ b/test/test_index.py @@ -1189,7 +1189,7 @@ def test_index_add_non_normalized_path(self, rw_repo): file.touch() non_normalized_path = file.as_posix() if os.name != "nt": - non_normalized_path = non_normalized_path.replace("/", "\\") + non_normalized_path = "/" + non_normalized_path[1:].replace("/", "//") rw_repo.index.add(non_normalized_path)