mbox series

[0/3] Add `-p' option to `git-mv', inspired by `mkdir'

Message ID 20231009233458.1371351-1-hugo@hsal.es (mailing list archive)
Headers show
Series Add `-p' option to `git-mv', inspired by `mkdir' | expand

Message

Hugo Sales Oct. 9, 2023, 11:34 p.m. UTC
Allow passing a new `-p'/`--parents' option to `git-mv' making it so
missing directories in the given target path get created if they don't
exist. This allows running `git mv -p foo bar/quux/' to first create
the `bar/' and `bar/quux/' directories if they don't exist, and then
move `foo' to `bar/quux/foo'.

This is inspired by `mkdir -p foo/bar/quux/' which will create the
`foo/', `foo/bar/', and `foo/bar/quux/' directories if they don't
exist.

Hugo Sales (3):
  mv: Add -p option to create parent directories
  mv: Add tests for new -p flag
  mv: Add documentation for new `-p' flag

 Documentation/git-mv.txt | 12 ++++--
 builtin/mv.c             | 27 +++++++++-----
 t/t7009-mv-parents.sh    | 79 ++++++++++++++++++++++++++++++++++++++++
 3 files changed, 105 insertions(+), 13 deletions(-)
 create mode 100755 t/t7009-mv-parents.sh


base-commit: 3a06386e314565108ad56a9bdb8f7b80ac52fb69

Comments

Junio C Hamano Oct. 10, 2023, 12:39 a.m. UTC | #1
Hugo Sales <hugo@hsal.es> writes:

> Allow passing a new `-p'/`--parents' option to `git-mv' making it so
> missing directories in the given target path get created if they don't
> exist. This allows running `git mv -p foo bar/quux/' to first create
> the `bar/' and `bar/quux/' directories if they don't exist, and then
> move `foo' to `bar/quux/foo'.
>
> This is inspired by `mkdir -p foo/bar/quux/' which will create the
> `foo/', `foo/bar/', and `foo/bar/quux/' directories if they don't
> exist.

I'll step back and ask a related design question without reading the
patches (yet).

Is there a reason why somebody benefits by us retaining the current
behaviour, where

    $ git mv file no/such/dir/yet/file

fails with "No such file or directory", and they are forced to say
either

    $ mkdir -p no/such/dir/yet
    $ git mv file no/such/dir/yet/file

or

    $ git mv -p file no/such/dir/yet/file

Yes, what I am getting at is if it makes sense to just "fix" the
behaviour of "git mv" about missing leading directories and do what
the end-user wanted to do without requiring "-p".

Regardless of the "do we require, or is it sifficient to imply, the
'-p' option when we lack leading directories?" question, once we
start "auto-creating" the leading directory hierarchy, one worrysome
thing such a new feature introduces is an ambiguity and unexpected
behaviour.  Imagine there is no "no" directory (so nothing under it
exists), and you did this (you do have a regular file "file").

    $ git mv [-p] file no/such/dir/yet

What should happen?  Would we do the equivalent of

    $ mkdir -p no/such/dir && git mv file no/such/dir/yet

or are we doing

    $ mkdir -p no/such/dir/yet && git mv file no/such/dir/yet/file

Both are plausible, and "mkdir -p" does not have such a nasty
ambiguity.  That is what makes me unsure about the new feature
(again, either with required "-p" or with implied "-p").

Thanks.
Junio C Hamano Oct. 10, 2023, 12:59 a.m. UTC | #2
Junio C Hamano <gitster@pobox.com> writes:

> Regardless of the "do we require, or is it sifficient to imply, the
> '-p' option when we lack leading directories?" question, once we
> start "auto-creating" the leading directory hierarchy, one worrysome
> thing such a new feature introduces is an ambiguity and unexpected
> behaviour. ...
> Both are plausible, and "mkdir -p" does not have such a nasty
> ambiguity.  That is what makes me unsure about the new feature
> (again, either with required "-p" or with implied "-p").

I checked what POSIX, who does give "-p" to mkdir(1), has with
mv(1), and they do not have "-p".  Neither GNU, which tends to add
such "usability" enhancements on top of what everybody else has.

And I think they are being very sensible.  By not adding such an
option to "mv", they can sidestep the unnecessary ambiguity, and it
isn't too bad to do a "mkdir -p" separately before doing such a "mv"
into a (potential) new directory.

So, let's not do this patch.

Thanks.
Hugo Sales Oct. 11, 2023, 12:33 p.m. UTC | #3
> On 10/10/2023 12:39 AM GMT Junio C Hamano <gitster@pobox.com> wrote:
> 
> Is there a reason why somebody benefits by us retaining the current
> behaviour, where
> 
>     $ git mv file no/such/dir/yet/file
> 
> fails with "No such file or directory", and they are forced to say
> either
> 
>     $ mkdir -p no/such/dir/yet
>     $ git mv file no/such/dir/yet/file
> 
> or
> 
>     $ git mv -p file no/such/dir/yet/file

Somewhat, as it could be a typo, so if you actually want to create a new folder, you have to be explicit. I wouldn't be opposed to removing the need for the flag, but if we did, I think we should warn the user that a new directory was created.

> Imagine there is no "no" directory (so nothing under it
> exists), and you did this (you do have a regular file "file").
> 
>     $ git mv [-p] file no/such/dir/yet
> 
> What should happen?  Would we do the equivalent of
> 
>     $ mkdir -p no/such/dir && git mv file no/such/dir/yet
> 
> or are we doing
> 
>     $ mkdir -p no/such/dir/yet && git mv file no/such/dir/yet/file
> 
> Both are plausible, and "mkdir -p" does not have such a nasty
> ambiguity.  That is what makes me unsure about the new feature
> (again, either with required "-p" or with implied "-p").

I think the ambiguity is resolved by the inclusion of lack thereof of a trailing `/`. This is what the implementation already does, too, before this patch. So

     $ git mv [-p] file no/such/dir/yet

would be the same as

     $ mkdir -p no/such/dir && git mv file no/such/dir/yet

and

     $ git mv [-p] file no/such/dir/yet/

would be the same as

     $ mkdir -p no/such/dir/yet && git mv file no/such/dir/yet/

Moving `file` to `no/such/dir/yet/file`

Thanks for the feedback,
Hugo

P.S. Apologies for the duplicated email, Junio, I did a Reply instead of a Reply All
Junio C Hamano Oct. 31, 2023, 4:30 a.m. UTC | #4
Hugo Sales <hugo@hsal.es> writes:

>> Both are plausible, and "mkdir -p" does not have such a nasty
>> ambiguity.  That is what makes me unsure about the new feature
>> (again, either with required "-p" or with implied "-p").
>
> I think the ambiguity is resolved by the inclusion of lack thereof
> of a trailing `/`.

The question is not if we can come up with a rule that the user can
use to disambiguate.  It is if the user will find that such a rule
is a naturally acceptable way to disambiguate.

When both of

    git mv file there/exists/such/a/directory
    git mv file there/exists/such/a/directory/

create "there/exists/such/a/directory/file" and removes "file", with
or without a trailing slash, "you should add a slash if you want a
directory, and otherwise you should not add a slash" is a rather
arbitrary rule.  Let's not go there.  I still view the downside more
grave than having to occasionally do "mkdir".
Dragan Simic Oct. 31, 2023, 4:54 a.m. UTC | #5
On 2023-10-31 05:30, Junio C Hamano wrote:
> Hugo Sales <hugo@hsal.es> writes:
> 
>>> Both are plausible, and "mkdir -p" does not have such a nasty
>>> ambiguity.  That is what makes me unsure about the new feature
>>> (again, either with required "-p" or with implied "-p").
>> 
>> I think the ambiguity is resolved by the inclusion of lack thereof
>> of a trailing `/`.
> 
> The question is not if we can come up with a rule that the user can
> use to disambiguate.  It is if the user will find that such a rule
> is a naturally acceptable way to disambiguate.
> 
> When both of
> 
>     git mv file there/exists/such/a/directory
>     git mv file there/exists/such/a/directory/
> 
> create "there/exists/such/a/directory/file" and removes "file", with
> or without a trailing slash, "you should add a slash if you want a
> directory, and otherwise you should not add a slash" is a rather
> arbitrary rule.  Let's not go there.  I still view the downside more
> grave than having to occasionally do "mkdir".

Please note that the above-described git-mv operation succeeds with no 
trailing slash if "there/exists/such/a/directory" doesn't already exist 
as a directory, and creates "there/exists/such/a/directory" as a file.  
With the trailing slash, the git-mv operation succeeds only if 
"there/exists/such/a/directory" already exists as a directory, and fails 
otherwise.

A quite similar ambiguity exists in cp(1) in mv(1), which is also 
resolved by the use of the trailing slash character.  However, I've 
encountered only one person aware of that disambiguation, and in cp(1) 
only, but in the "I always include the trailing slash" way, without 
actually understanding it fully.  Maybe I need to encounter more people, 
I don't know.
Junio C Hamano Oct. 31, 2023, 5:58 a.m. UTC | #6
Dragan Simic <dsimic@manjaro.org> writes:

> A quite similar ambiguity exists in cp(1) in mv(1), which is also
> resolved by the use of the trailing slash character.  However, I've
> encountered only one person aware of that disambiguation, and in cp(1)
> only, but in the "I always include the trailing slash" way, without
> actually understanding it fully.  Maybe I need to encounter more
> people, I don't know.

If the majority of (perhaps new) users you already know find such
disambiguation method unfamiliar, that already is a good anecdata
without any need for you to meet more people to tell us that it is
not a very easy-to-understand thing for them, no?
Dragan Simic Oct. 31, 2023, 6:38 a.m. UTC | #7
On 2023-10-31 06:58, Junio C Hamano wrote:
> Dragan Simic <dsimic@manjaro.org> writes:
> 
>> A quite similar ambiguity exists in cp(1) in mv(1), which is also
>> resolved by the use of the trailing slash character.  However, I've
>> encountered only one person aware of that disambiguation, and in cp(1)
>> only, but in the "I always include the trailing slash" way, without
>> actually understanding it fully.  Maybe I need to encounter more
>> people, I don't know.
> 
> If the majority of (perhaps new) users you already know find such
> disambiguation method unfamiliar, that already is a good anecdata
> without any need for you to meet more people to tell us that it is
> not a very easy-to-understand thing for them, no?

Quite frankly, I'm divided there.  On the one hand, you're right that 
this disambiguation method is a bit confusing and it's absolutely not 
very well known.  On the other hand, it's already out there in the wild, 
including git, and it's actually quite useful when used properly.

If I had to vote, I'd give my vote to embracing this disambiguation 
method, but only with good documentation and some kind of education 
through an article or two.  I believe that proper education simply isn't 
present, or at least not in a user-friendly manner, which should be 
corrected, regardless of the new "git mv -p" feature being accepted or 
not.