Re: [PATCH] init: disallow --separate-git-dir with bare repository
- From
Eric Sunshine <sunshine@sunshineco.com>
- Date
- Aug 11, 2020, 05:44 UTC
- Message-ID
- <CAPig+cSMzEuMYNnHhMGwqGFgjWfX0+j1KoOSK8V7Wav97p+UVw@mail.gmail.com>
- In-Reply-To
- <20200810095648.GA37030@coredump.intra.peff.net>
On Mon, Aug 10, 2020 at 5:56 AM Jeff King <peff@peff.net> wrote:
Show 9 quoted lines
> On Sun, Aug 09, 2020 at 06:53:16PM -0400, Eric Sunshine wrote: > > However, an outright bare repository (such as one created by "git init > > --bare"), has no worktree, so using --separate-git-dir to separate it > > from its non-existent worktree is nonsensical. Therefore, make it an > > error to use --separate-git-dir on a bare repository. > > I agree that it seems like nonsense. I'm a little curious what it > happens to do today, just because I'd wonder if it could possibly be of > any use to somebody.
The current behavior does some goofy stuff which I can't imagine being useful to anyone. For instance:
% git init --bare --separate-git-dir bar.git foo.git
% ls -1
bar.git
foo.git
% cat foo.git
gitdir: /.../bar.git
%So, I just initialized a bare repository "foo.git" which isn't actually a directory at all but instead is just a 'gitlink' file. What can I do with file "foo.git"? Not a whole lot. "bar.git" is the actual repository.
The case of re-initializing a bare repository with --separate-git-dir is even weirder:
% rm -rf foo.git bar.git
% git init --bare foo.git
% # ... add some commits ...
% git -C foo.git rev-parse master
86e28bed5ac8f5ea774690b4fc0eddb434800e9e
% git -C foo.git init --separate-git-dir ../bar.git
% ls -FA bar.git
HEAD config hooks/ objects/
branches/ description info/ refs/
% ls -FA foo.git
.git branches/ description info/ refs/
HEAD config hooks/ objects/
% cat foo.git/.git
gitdir: /.../bar.git
% git -C bar.git rev-parse master --
fatal: bad revision 'master'
% git -C foo.git rev-parse master --
fatal: bad revision 'master'
% rm foo.git/.git
% git -C foo.git rev-parse master
86e28bed5ac8f5ea774690b4fc0eddb434800e9e
%So, the repository doesn't actually move at all; it stays at "foo.git". And "bar.git", even though it looks like a repository, is actually empty; all the objects are still in "foo.git". Plus "foo.git" is _broken_ by the ".git" file which --separate-git-dir placed there.
So, it's meaningless and perhaps destructive behavior using --separate-git-dir with a bare repository,
Show 13 quoted lines
> > Implementation note: "git init" considers a repository bare if told so
> > explicitly via --bare or if it guesses it to be so based upon
> > heuristics. In the explicit --bare case, a conflict with
> > --separate-git-dir is easy to detect early. In the guessed case,
> > however, the conflict can only be detected once "bareness" is guessed,
> > which happens after "git init" has begun creating the repository.
> > Technically, we can get by with a single late check which would cover
> > both cases, however, erroring out early, when possible, without leaving
> > detritus provides a better user experience.
>
> I think we'd clean up that detritus with our atexit handler, but I like
> the extra check here. It lets us give a slightly more specific message
> when we can catch it early ("these two options are incompatible").With only the latter (after-the-fact) check:
% git init --bare --separate-git-dir bar.git foo.git
fatal: --separate-git-dir incompatible with bare repository
% ls -1
foo.git
% ls -A foo.git/
%It leaves the directory "foo.git" around, though the directory is empty. With the earlier check in place, it avoids leaving that empty directory.
> The patch itself looks good, assuming my "I'd wonder..." line of inquiry > above produces nothing of value. :)
I can't find any value in the current behavior, so I'm pretty well convinced that this patch is desirable (even if I don't quite like repeating the check).
I didn't add any of the above explanation-by-examples to the commit message because it seemed too much detail.