Re: Bug: git worktree remove and overwritten directory
To
jonathanmueller.dev@gmail.com
Cc
git@vger.kernel.org
From
Shourya Shukla
See Also
Prev
Date
2020-05-20 13:38:20 UTC
Hello Jonathan!

> And both `git worktree remove .` and `git worktree remove ../test2`
> report an error `fatal: '../test2' is a main working tree`. I had to
> manually remove the corresponding folder from `.git/worktree` to get rid
> of it. The issue is especially annoying, because you can't check out
> `some-branch` anymore (as it's already checked out in the worktree).

If you refer to the documentation of `git worktree` you may find this:

    Multiple checkout in general is still experimental, and the support
    for submodules is incomplete. It is NOT recommended to make multiple
    checkouts of a superproject.

Alright, so if you were to do a checkout to `some-branch` even if you
never deleted anything, you won't be able to perform this action because
it's not possible, therefore *this* thing is not a bug. Why can't you
perform this you ask? Because this is the point of the whole command. If
you were allowed to checkout, then you would be able to have two
different copies of the same thing at one instant of time, which is
something we don't want.

Moving on, one may say, "I am technically in the same repo only, its
just that the folder names are changed, so I can technically do a
checkout now because my worktree is gone right?". No, we cannot,
because: technicalities. You see, that when you create a worktree,
you add an entry in `$GIT_DIR/worktrees/` that `test2` is a registered
worktree by you. Now if one does the mischief you did by renaming `test`
to `test2`, you confuse the system as to what exactly is going on. It
still thinks that we are on `test2`, but in fact we are on `test`.
Hence, the dual nature we have here. Please refer to this for more detail:
https://git-scm.com/docs/git-worktree#_details

Now, if you delete the `$GIT_DIR/worktrees/` folder (proceeding
further), you will be able to checkout to `some-branch` because the
confusion is gone now as Git is not aware of any worktrees you ever
created.

Therefore the final set of commands to overcome this will be:
    git init test
    cd test
    git commit --allow-empty -m"Initial commit"
    git branch some-branch
    git worktree add ../test2 some-branch
    cd ../
    rm -rf test2
    mv test test2
    rm -rf .git/worktrees
    git checkout some-branch
    ... we can checkout successfully now :)

Now, I can be wrong in some places in my explanation, but this is what
I could infer from the problem.

So, coming to the ultimate question:
    Is this a bug?
I don't really think so. Why you ask? Because this is the way things
should have functioned. It is more of a vulnerability.
You may want to refer to this:
https://stackoverflow.com/a/402944/10751129

But again, this doesn't mean that it can't be fixed.
Thanks to you I got introduced to a new git command (git worktree) :)

Regards,
Shourya Shukla