Hi Peff,
On Thu, 2 Mar 2017, Jeff King wrote:
> On Fri, Mar 03, 2017 at 03:04:15AM +0100, Johannes Schindelin wrote:
>
> > diff --git a/cache.h b/cache.h
> > index 80b6372cf76..a104b76c02e 100644
> > --- a/cache.h
> > +++ b/cache.h
> > @@ -518,6 +518,7 @@ extern void set_git_work_tree(const char *tree);
> > #define ALTERNATE_DB_ENVIRONMENT "GIT_ALTERNATE_OBJECT_DIRECTORIES"
> >
> > extern void setup_work_tree(void);
> > +extern const char *discover_git_directory(struct strbuf *gitdir);
>
> Perhaps it's worth adding a short docstring describing the function.
Okay.
> > +const char *discover_git_directory(struct strbuf *gitdir)
> > +{
> > + struct strbuf dir = STRBUF_INIT;
> > + int len;
>
> Nit: please use size_t for storing strbuf lengths.
Okay.
> > + if (strbuf_getcwd())
> > + return NULL;
> > +
> > + len = dir.len;
> > + if (discover_git_directory_1(, gitdir) < 0) {
> > + strbuf_release();
> > + return NULL;
> > + }
> > +
> > + if (dir.len < len && !is_absolute_path(gitdir->buf)) {
> > + strbuf_addch(, '/');
> > + strbuf_insert(gitdir, 0, dir.buf, dir.len);
> > + }
> > + strbuf_release();
>
> I was confused by two things here.
>
> One is that because I was wondering whether "gitdir" was supposed to be
> passed empty or not, it wasn't clear that this insert is doing the right
> thing. If there _is_ something in it, then discover_git_directory_1()
> would just append to it, which makes sense. But then this insert blindly
> sticks the absolute-path bit at the front of the string, leaving
> whatever was originally there spliced into the middle of the path.
> Doing:
>
> size_t base = gitdir->len;
> ...
> strbuf_insert(gitdir, base, dir.buf, dir.len);
>
> would solve that.
And of course the is_absolute_path() call also needs to offset `gitdir->buf
+ base`.
> It's probably not that likely for somebody to do:
>
> strbuf_addstr(, "my git dir is ");
> discover_git_directory();
>
> but since it's not much effort, it might be worth making it work.
Plus, I have no assert()s in place to ensure any expectation to the
contrary. So I fixed it as you suggested.
> The second is that I don't quite understand why we only make the result
> absolute when we walked upwards. In git.git, the result of the function
> in various directories is:
>
> - ".git", when we're at the root of the worktree
> - "/home/peff/git/.git, when we're in "t/"
> - "." when we're already in ".git"
> - "/home/peff/git/.git/." when we're in ".git/objects"
> > I'm not sure if some of those cases are not behaving as intended, or
> there's some reason for the differences that I don't quite understand.
Yes, some of those cases do not behave as intended: it is true that
setup_git_directory() sets git_dir to "/home/peff/git/.git" when we
(actually, you, given that my home directory is different) are in "t/",
but setup_git_directory_gently_1() would set gitdir to ".git" and dir to
"/home/peff/git". But the current directory is still what cwd says it is:
"/home/peff/git/t".
I added a comment:
/*
* The returned gitdir is relative to dir, and if dir does not reflect
* the current working directory, we simply make the gitdir
* absolute.
*/
And thanks: you reminded me of another issue I wanted to address but
forgot: if gitdir is ".", I do not want the resulting absolute path to
have a trailing "/.". I fixed that, too.
Ciao,
Dscho