From 97fd19407d610de298c45500f7e1ad3e62b8a263 Mon Sep 17 00:00:00 2001 From: Brian Warner Date: Sun, 3 May 2015 21:49:34 -0700 Subject: [PATCH] Improve docs on 'cp -r', noting the recent 2329 changes refs ticket:2329 --- NEWS.rst | 56 +++++++++++++++++++++++++++++++++--- docs/frontends/CLI.rst | 15 ++++++++++ src/allmydata/scripts/cli.py | 11 +++++-- 3 files changed, 75 insertions(+), 7 deletions(-) diff --git a/NEWS.rst b/NEWS.rst index a96110e3..336ab874 100644 --- a/NEWS.rst +++ b/NEWS.rst @@ -7,9 +7,9 @@ User-Visible Changes in Tahoe-LAFS Release 1.10.1 (XXXX-XX-XX) ''''''''''''''''''''''''''' -Unedited list of all changes after 1.10 and before 0d935e8 06-Jan-2015. This -list is not yet limited to user-visible ones. It *should* include all tickets -closed during this time, even minor non-user-visible ones. +Unedited list of all changes after 1.10.0 and before 0d935e8 06-Jan-2015. +This list is not yet limited to user-visible ones. It *should* include all +tickets closed during this time, even minor non-user-visible ones. - show git branch in version output #1953 - packaging fixes #1969 #1960 @@ -59,7 +59,7 @@ closed during this time, even minor non-user-visible ones. - improve version-number reporting #2340 - add per-server "(space) Available" column to welcome page #648 - add public-key auth to SFTP server #1411 - +- `tahoe cp -r` changes w.r.t. unnamed directories #2329 all tickets noted as closed: 1953 1960 1974 1972 1717 1381 898 1707 1918 1807 740 1842 1992 2165 1847 2086 2208 2048 2128 2245 1336 2248 2067 712 1800 1966 @@ -72,6 +72,54 @@ all tickets referenced (fixed? not fixed?): 1834 1969 1742 1988 982 1064 1536 PRs noted as closed: 62 48 57 61 62 63 64 69 73 81 82 84 85 87 91 94 95 96 103 56 32 50 107 109 114 112 120 122 125 126 133 +- "tahoe cp" changes: + +There are many "cp"-like tools in the unix world (POSIX /bin/cp, the "scp" +provided by SSH, rsync). They each behave slightly differently in unusual +circumstances, generally dealing with copying whole directories at a time, +into a target which may or may not exist already. The usual question is +whether the user is referring to the source directory as a whole, or to its +contents. For example, should "cp -r foodir bardir" create a new directory +named "bardir/foodir"? Or should it behave more like "cp -r foodir/* bardir"? +Some tools use the presence of a trailing slash to indicate which behavior +you want. Others ignore trailing slashes. + +"tahoe cp" is no exception to having exceptional cases. This release fixes +some bad behavior and attempts to establish a consistent rationale for its +behavior. + +The new rule is: + +- If the thing being copied is a directory, and it has a name (e.g. it's not + a raw tahoe directorycap), then you are referring to the directory itself. +- If the thing being copied is an unnamed directory (e.g. raw dircap or + alias), then you are referring to the contents. +- Trailing slashes do not affect the behavior of the copy (although putting a + trailing slash on a file-like target is an error). +- The "-r" (--recursive) flag does not affect the behavior of the copy + (although omitting -r when the source is a directory is an error). +- If the target refers to something that does not yet exist: + - and if the source is a single file, then create a new file; + - otherwise, create a directory. + +There are two main cases where the behavior of tahoe-1.10.1 differs from that +of the 1.10.0 release: + +- "cp DIRCAP/file.txt ./local/missing" , where "./local" is a directory but + "./local/missing" does not exist. The implication is that you want tahoe to + create a new file named "./local/missing" and fill it with the contents of + the tahoe-side DIRCAP/file.txt. In 1.10.0, a plain "cp" would do just this, + but "cp -r" would do "mkdir ./local/missing" and then create a file named + "./local/missing/file.txt". In 1.10.1, both "cp" and "cp -r" create a file + named "./local/missing". +- "cp -r PARENTCAP/dir ./local/missing", where PARENTCAP/dir/ contains + "file.txt", and again "./local" is a directory but "./local/missing" does + not exist. In both 1.10.0 and 1.10.1, this first does "mkdir + ./local/missing". In 1.10.0, it would then copy the contents of the source + directory into the new directory, resulting in "./local/missing/file.txt". + In 1.10.1, following the new rule of "a named directory source refers to + the directory itself", the tool creates "./local/missing/dir/file.txt". + Release 1.10.0 (2013-05-01) diff --git a/docs/frontends/CLI.rst b/docs/frontends/CLI.rst index e91632f5..3effb456 100644 --- a/docs/frontends/CLI.rst +++ b/docs/frontends/CLI.rst @@ -455,6 +455,21 @@ Command Examples all source arguments which are directories will be copied into new subdirectories of the target. + The behavior of ``tahoe cp``, like the regular UNIX ``/bin/cp``, is subtly + different depending upon the exact form of the arguments. In particular: + +* Trailing slashes indicate directories, but are not required. +* If the target object does not already exist: + * and if the source is a single file, it will be copied into the target; + * otherwise, the target will be created as a directory. +* If there are multiple sources, the target must be a directory. +* If the target is a pre-existing file, the source must be a single file. +* If the target is a directory, each source must be a named file, a named + directory, or an unnamed directory. It is not possible to copy an unnamed + file (e.g. a raw filecap) into a directory, as there is no way to know what + the new file should be named. + + ``tahoe unlink uploaded.txt`` ``tahoe unlink tahoe:uploaded.txt`` diff --git a/src/allmydata/scripts/cli.py b/src/allmydata/scripts/cli.py index e240c9ec..18ecc659 100644 --- a/src/allmydata/scripts/cli.py +++ b/src/allmydata/scripts/cli.py @@ -252,9 +252,14 @@ class CpOptions(FilesystemOptions): This command still has some limitations: symlinks and special files (device nodes, named pipes) are not handled very well. Arguments should - probably not have trailing slashes. 'tahoe cp' does not behave as much - like /bin/cp as you would wish, especially with respect to trailing - slashes. + not have trailing slashes (they are ignored for directory arguments, but + trigger errors for file arguments). When copying directories, it can be + unclear whether you mean to copy the contents of a source directory, or + the source directory itself (i.e. whether the output goes under the + target directory, or one directory lower). Tahoe's rule is that source + directories with names are referring to the directory as a whole, and + source directories without names (e.g. a raw dircap) are referring to the + contents. """ class UnlinkOptions(FilesystemOptions): -- 2.37.2