Skip to content

Commit a4a4db8

Browse files
committed
Merge branch 'gc/better-error-when-local-clone-fails-with-symlink'
"git clone --local" stops copying from an original repository that has symbolic links inside its $GIT_DIR; an error message when that happens has been updated. * gc/better-error-when-local-clone-fails-with-symlink: clone: error specifically with --local and symlinked objects
2 parents 98c496f + 4e33535 commit a4a4db8

File tree

3 files changed

+17
-2
lines changed

3 files changed

+17
-2
lines changed

Documentation/git-clone.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,11 @@ never use the local optimizations). Specifying `--no-local` will
5858
override the default when `/path/to/repo` is given, using the regular
5959
Git transport instead.
6060
+
61+
If the repository's `$GIT_DIR/objects` has symbolic links or is a
62+
symbolic link, the clone will fail. This is a security measure to
63+
prevent the unintentional copying of files by dereferencing the symbolic
64+
links.
65+
+
6166
*NOTE*: this operation can race with concurrent modification to the
6267
source repository, similar to running `cp -r src dst` while modifying
6368
`src`.

builtin/clone.c

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -331,8 +331,18 @@ static void copy_or_link_directory(struct strbuf *src, struct strbuf *dest,
331331

332332
iter = dir_iterator_begin(src->buf, DIR_ITERATOR_PEDANTIC);
333333

334-
if (!iter)
334+
if (!iter) {
335+
if (errno == ENOTDIR) {
336+
int saved_errno = errno;
337+
struct stat st;
338+
339+
if (!lstat(src->buf, &st) && S_ISLNK(st.st_mode))
340+
die(_("'%s' is a symlink, refusing to clone with --local"),
341+
src->buf);
342+
errno = saved_errno;
343+
}
335344
die_errno(_("failed to start iterator over '%s'"), src->buf);
345+
}
336346

337347
strbuf_addch(src, '/');
338348
src_len = src->len;

t/t5604-clone-reference.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -358,7 +358,7 @@ test_expect_success SYMLINKS 'clone repo with symlinked objects directory' '
358358
test_must_fail git clone --local malicious clone 2>err &&
359359
360360
test_path_is_missing clone &&
361-
grep "failed to start iterator over" err
361+
grep "is a symlink, refusing to clone with --local" err
362362
'
363363

364364
test_done

0 commit comments

Comments
 (0)