Subject: Re: Git submodule remove

From: Ævar Arnfjörð Bjarmason <[email-masked]>
Date: Fri, 22 Oct 2021 14:12:11 +0200

On Thu, Oct 21 2021, Junio C Hamano wrote:

> Matheus Tavares <[email-masked]> writes:
>
>> On Thu, Oct 21, 2021 at 7:47 PM Junio C Hamano <[email-masked]> wrote:
>>>
>>> "brian m. carlson" <[email-masked]> writes:
>>>
>>> > On 2021-10-21 at 17:25:38, Kalyan Sriram wrote:
>>> >> Hello,
>>> >>
>>> >> I was curious why git-submodule does not have an `rm` command. Currently
>>> >> I have to manually delete it from .gitmodules, .git/config,
>>> >> .git/modules/, etc. See [0].
>>> >>
>> [...]
>>> I'd imagine that the happy-case implementation should be fairly
>>> straight-forward.  You would:
>>>
>>>  - ensure that the submodule is "absorbed" already;
>>>
>>>  - run "git rm -f" the submodule to remove the gitlink from the index
>>>    and remove the directory from the working tree; and
>>>
>>>  - remove the .gitmodules entry for the submodule.
>>
>> I think "git rm <submodule>" already does these three steps, doesn't it?
>
> Wow, that is a unnerving layering violation, but I suspect it is too
> late to fix it. So perhaps "git submodule rm" would just become a
> synonym for "git rm"?
>
> Thanks.

Why would it be a good thing to change it even if we could? We added
that section with "git submodule add", it makes sense to have it removed
on "git init". The user could have added it manually, but the same goes
for manually added config that "git remote remove" would remove.

If anything I think it would make sense to extend this behavior. E.g. if
we "git rm" a <path> and notice that the <path> was the only thing that
matched a given entry in .gitignore we should remove that entry.

Or e.g. warn if we notice that the non-ext name of the removed file is
the only thing matching non-ext-versions of .gitignore, i.e. to catch
the common case of removing a "foo.c", but leaving a "foo.o" gitignore
entry behind.

See 95c16418f03 (rm: delete .gitmodules entry of submodules removed from
the work tree, 2013-08-06) for the commit that gave "git rm" these
smarts.

I used to think that "git rm" was a bad layering violation, i.e. what's
the point of it over:

    rm foo
    git add foo

And in the early days having it at all is IMO one of the things that
confused a lot of users about git's data model, i.e. they'd re-do their
moves or removals with the "git mv" or "git rm", thinking the SCM cared
about being informed of things like that.

But those commands are worthwhile, because they interact nicely with
other native git features, pathspecs, .gitmodules etc.

FWIW I think one thing that might make the "git submodule" interface
less confusing is to go in the opposite direction, not to add a "git
submodule rm" or whatever, but think about whether we need something
like "git submodule add" at all, i.e. shouldn't that ideally just be
some special-case of "git add" or "git clone"?

I.e. Either you "git clone" to the working tree and it Just Works (adds
.gitmodules and all), or "git add" on a directory with a .git dir in it
will (perhps after asking) shimmy up the relevant submodule scaffolding.