From: Brian Warner Date: Wed, 29 Jul 2015 00:19:42 +0000 (-0700) Subject: cp: error on target-filename collisions, rather than overwrite X-Git-Tag: allmydata-tahoe-1.10.2b1~2^2~1 X-Git-Url: https://git.rkrishnan.org/specifications/%5B/%5D%20/flags/install.html?a=commitdiff_plain;h=98ab848cdae2743753d48dda2c34f081496f7e80;p=tahoe-lafs%2Ftahoe-lafs.git cp: error on target-filename collisions, rather than overwrite Closes ticket:2447 --- diff --git a/src/allmydata/scripts/tahoe_cp.py b/src/allmydata/scripts/tahoe_cp.py index b603d6ba..351b6a33 100644 --- a/src/allmydata/scripts/tahoe_cp.py +++ b/src/allmydata/scripts/tahoe_cp.py @@ -496,8 +496,9 @@ class Copier: def try_copy(self): """ - All usage errors are caught here, not in a subroutine. This bottoms - out in copy_file_to_file() or copy_things_to_directory(). + All usage errors (except for target filename collisions) are caught + here, not in a subroutine. This bottoms out in copy_file_to_file() or + copy_things_to_directory(). """ source_specs = self.options.sources destination_spec = self.options.destination @@ -735,6 +736,23 @@ class Copier: # sourceobject) dicts for all the files that need to wind up there. targetmap = self.build_targetmap(sources, target) + # target name collisions are an error + collisions = [] + for target, sources in targetmap.items(): + target_names = {} + for source in sources: + name = source.basename() + if name in target_names: + collisions.append((target, source, target_names[name])) + else: + target_names[name] = source + if collisions: + self.to_stderr("cannot copy multiple files with the same name into the same target directory") + # I'm not sure how to show where the collisions are coming from + #for (target, source1, source2) in collisions: + # self.to_stderr(source1.basename()) + return 1 + # step four: walk through the list of targets. For each one, copy all # the files. If the target is a TahoeDirectory, upload and create # read-caps, then do a set_children to the target directory. diff --git a/src/allmydata/test/test_cli_cp.py b/src/allmydata/test/test_cli_cp.py index 82648307..3c8bc80a 100644 --- a/src/allmydata/test/test_cli_cp.py +++ b/src/allmydata/test/test_cli_cp.py @@ -787,7 +787,7 @@ cp -r $PARENTCAP/dir3/file3 $DIRCAP $PARENTCAP/dir2 $FILECAP to/missing/ : E2-DE cp -r $PARENTCAP/dir4 to : to/dir4/emptydir/ cp -r $PARENTCAP/dir4 to/ : to/dir4/emptydir/ -# name collisions: ensure files are copied in order +# name collisions should cause errors, not overwrites cp -r $PARENTCAP/dir6/dir $PARENTCAP/dir5/dir to : E9-COLLIDING-TARGETS cp -r $PARENTCAP/dir5/dir $PARENTCAP/dir6/dir to : E9-COLLIDING-TARGETS cp -r $DIRCAP6 $DIRCAP5 to : E9-COLLIDING-TARGETS @@ -949,7 +949,7 @@ class CopyOut(GridTestMixin, CLITestMixin, unittest.TestCase): return set(["E6-MANYONE"]) if err == "target is not a directory, but ends with a slash": return set(["E7-BADSLASH"]) - if err == "cannot copy multiple files with the same name from different source directories into the same target directory": + if err == "cannot copy multiple files with the same name into the same target directory": return set(["E9-COLLIDING-TARGETS"]) if (err.startswith("source ") and "is not a directory, but ends with a slash" in err):