From c5fd3e3cff79965ca07b6be9d883fe2a13163e2a Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Tue, 5 Jan 2021 11:04:41 +0200 Subject: [PATCH] add: handle long filenames (#5201) (#5206) (cherry picked from commit b779a117ab39f8622fcb1b1ab53ceec19e0b84cf) Co-authored-by: Ruslan Kuprieiev --- dvc/tree/local.py | 6 +++--- tests/func/test_add.py | 19 +++++++++++++++++++ 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/dvc/tree/local.py b/dvc/tree/local.py index 5eddad93e..0be9a1dbe 100644 --- a/dvc/tree/local.py +++ b/dvc/tree/local.py @@ -177,7 +177,7 @@ class LocalTree(BaseTree): move(from_info, to_info, mode=mode) def copy(self, from_info, to_info): - tmp_info = to_info.parent / tmp_fname(to_info.name) + tmp_info = to_info.parent / tmp_fname("") try: System.copy(from_info, tmp_info) os.chmod(tmp_info, self.file_mode) @@ -188,7 +188,7 @@ class LocalTree(BaseTree): def copy_fobj(self, fobj, to_info): self.makedirs(to_info.parent) - tmp_info = to_info.parent / tmp_fname(to_info.name) + tmp_info = to_info.parent / tmp_fname("") try: copy_fobj_to_file(fobj, tmp_info) os.chmod(tmp_info, self.file_mode) @@ -236,7 +236,7 @@ class LocalTree(BaseTree): return System.is_hardlink(path_info) def reflink(self, from_info, to_info): - tmp_info = to_info.parent / tmp_fname(to_info.name) + tmp_info = to_info.parent / tmp_fname("") System.reflink(from_info, tmp_info) # NOTE: reflink has its own separate inode, so you can set permissions # that are different from the source. diff --git a/tests/func/test_add.py b/tests/func/test_add.py index 216d742fc..0ea78066b 100644 --- a/tests/func/test_add.py +++ b/tests/func/test_add.py @@ -1,3 +1,4 @@ +import errno import filecmp import logging import os @@ -951,3 +952,21 @@ def test_add_preserve_meta(tmp_dir, dvc): meta: some metadata """ ) + + +# NOTE: unless long paths are enabled on Windows, PATH_MAX and NAME_MAX +# are the same 260 chars, which makes the test unnecessarily complex +@pytest.mark.skipif(os.name == "nt", reason="unsupported on Windows") +def test_add_long_fname(tmp_dir, dvc): + name_max = os.pathconf(tmp_dir, "PC_NAME_MAX") + name = "a" * name_max + tmp_dir.gen({"data": {name: "foo"}}) + + # nothing we can do in this case, as the resulting dvcfile + # will definitely exceed NAME_MAX + with pytest.raises(OSError) as info: + dvc.add(os.path.join("data", name)) + assert info.value.errno == errno.ENAMETOOLONG + + dvc.add("data") + assert (tmp_dir / "data").read_text() == {name: "foo"}