git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: [PATCH] clone: error specifically with --local and symlinked objects

From
Glen Choo <chooglen@google.com>
Date
Apr 5, 2023, 16:48 UTC
Message-ID
<kl6ly1n65l7t.fsf@chooglen-macbookpro.roam.corp.google.com>
In-Reply-To
<xmqq7curxk22.fsf@gitster.g>
Junio C Hamano <gitster@pobox.com> writes:
> If you want to do lstat(2) yourself, the canonical way to check its
> success is to see the returned value is 0, not "not negative", but
> let's first see how dir_iterator_begin() can fail.
Ah, thanks.
Show 19 quoted lines
>                                Unfortunately, if lstat(2) failed
>    with ENOTDIR (e.g. dir_iterator_begin() gets called with a path
>    whose leading component is not a directory), the caller will also
>    see ENOTDIR, but the distinction may not matter in practice.  I
>    haven't thought things through.
>
> ...
>
> 	if (!iter) {
> 		if (errno == ENOTDIR)
> 			die(_("'%s' is not a directory, refusing to clone with --local"),
> 			    src->buf);
> 		else
> 			die_errno(_("failed to stat '%s'"), src->buf);
> 	}
>
> may be sufficient.  But because this is an error codepath, it is not
> worth optimizing what happens there, and an extra lstat(2) is not
> too bad, if the code gains extra clarity.
Yeah, the considerations here make sense to me.

Since this is an error code path, I think the extra lstat() is probably worth it since it lets us be really specific about the error. Maybe:

	if (!iter) {
		struct stat st;
    if (errno == ENOTDIR && lstat(src->buf, &st) == 0 && S_ISLNK(st.st_mode))
			die(_("'%s' is a symlink, refusing to clone with --local"),
			    src->buf);
    die_errno(_("failed to start iterator over '%s'"), src->buf);
	}

Doing the extra lstat() only makes sense if we saw ENOTDIR orignally anyway.

Alternatively, since we do care about the distinction between ENOTDIR from lstat vs ENOTDIR because dir_iterator_begin() saw a symlink, maybe it's better to refactor dir_iterator_begin() so that we stop piggybacking on "errno = ENOTDIR" in these two cases. I didn't want to do this because I wasn't sure who might be relying on this behavior, but this check was pretty recently introduced anyway (bffc762f87 (dir-iterator: prevent top-level symlinks without FOLLOW_SYMLINKS, 2023-01-24), so maybe nobody needs it.

Previous: Junio C HamanoNext: Junio C Hamano
Message 3 of 14 in “clone: error specifically with --local and symlinked objects”
  1. clone: error specifically with --local and symlinked objectsGlen Choo via GitGitGadget, Apr 4, 2023
  2. Junio C HamanoApr 5, 2023
  3. Glen ChooApr 5, 2023
  4. Junio C HamanoApr 5, 2023
  5. Taylor BlauApr 6, 2023
  6. Glen ChooApr 6, 2023
  7. Taylor BlauApr 6, 2023
  8. clone: error specifically with --local and symlinked objectsGlen Choo via GitGitGadget, Apr 10, 2023
  9. Junio C HamanoApr 10, 2023
  10. Taylor BlauApr 10, 2023
  11. Taylor BlauApr 11, 2023
  12. clone: error specifically with --local and symlinked objectsGlen Choo via GitGitGadget, Apr 11, 2023
  13. Junio C HamanoApr 11, 2023
  14. Glen ChooApr 11, 2023

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.