From 4e33535ea98ac16d2163e8e9fcbba5e015881e65 Mon Sep 17 00:00:00 2001 From: Glen Choo Date: Mon, 10 Apr 2023 22:18:50 +0000 Subject: clone: error specifically with --local and symlinked objects 6f054f9fb3 (builtin/clone.c: disallow --local clones with symlinks, 2022-07-28) gives a good error message when "git clone --local" fails when the repo to clone has symlinks in "$GIT_DIR/objects". In bffc762f87 (dir-iterator: prevent top-level symlinks without FOLLOW_SYMLINKS, 2023-01-24), we later extended this restriction to the case where "$GIT_DIR/objects" is itself a symlink, but we didn't update the error message then - bffc762f87's tests show that we print a generic "failed to start iterator over" message. This is exacerbated by the fact that Documentation/git-clone.txt mentions neither restriction, so users are left wondering if this is intentional behavior or not. Fix this by adding a check to builtin/clone.c: when doing a local clone, perform an extra check to see if "$GIT_DIR/objects" is a symlink, and if so, assume that that was the reason for the failure and report the relevant information. Ideally, dir_iterator_begin() would tell us that the real failure reason is the presence of the symlink, but (as far as I can tell) there isn't an appropriate errno value for that. Also, update Documentation/git-clone.txt to reflect that this restriction exists. Signed-off-by: Glen Choo Signed-off-by: Junio C Hamano --- builtin/clone.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'builtin/clone.c') diff --git a/builtin/clone.c b/builtin/clone.c index c171def1f3..ae2db8535a 100644 --- a/builtin/clone.c +++ b/builtin/clone.c @@ -331,8 +331,18 @@ static void copy_or_link_directory(struct strbuf *src, struct strbuf *dest, iter = dir_iterator_begin(src->buf, DIR_ITERATOR_PEDANTIC); - if (!iter) + if (!iter) { + if (errno == ENOTDIR) { + int saved_errno = errno; + struct stat st; + + if (!lstat(src->buf, &st) && S_ISLNK(st.st_mode)) + die(_("'%s' is a symlink, refusing to clone with --local"), + src->buf); + errno = saved_errno; + } die_errno(_("failed to start iterator over '%s'"), src->buf); + } strbuf_addch(src, '/'); src_len = src->len; -- cgit v1.3