From patchwork Tue Feb 26 05:18:00 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matheus Tavares X-Patchwork-Id: 10829445 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 2F09A139A for ; Tue, 26 Feb 2019 05:18:31 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 1BB9B2B156 for ; Tue, 26 Feb 2019 05:18:31 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 102412B33B; Tue, 26 Feb 2019 05:18:31 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id E73B12AF61 for ; Tue, 26 Feb 2019 05:18:29 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726205AbfBZFST (ORCPT ); Tue, 26 Feb 2019 00:18:19 -0500 Received: from mail-qt1-f194.google.com ([209.85.160.194]:39011 "EHLO mail-qt1-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725940AbfBZFSS (ORCPT ); Tue, 26 Feb 2019 00:18:18 -0500 Received: by mail-qt1-f194.google.com with SMTP id o6so13520854qtk.6 for ; Mon, 25 Feb 2019 21:18:17 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=usp-br.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=l1UmO68rcRUjWQ2/WVZqpWMUw4fV6lJQrZssc7u20ro=; b=eoJY7h5CCcdO//lfNOF4QpfkuWBzVCjwr9IipIHZRt0CIdgyNM2iriSPHksB6aJpmX Xciz5Fdp0mbPtqvwYycsJXmoL8YuBVI4rDy1lvgkMVD1c2dBbI8PdPdaFzpq5a1wPYdW 3u/jP1zCQllpnKFcUl3KAa+qm3Bec5BNEISjjvghPq3nlLlP6a4jFbHDQRcYxvjVSbT5 kuh3eWGhhp3r6zBkOw5DK36j6kj7tCoRfyTsMrXbr62dXdffCR1HljQMMcHS0sUEwx6h gLKmbeluRTUHNnJt3RXFCqnUfytyqVp4iMhW9BtekNk6v+1K316NiAkoICuOFxgjwFFz OVgg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=l1UmO68rcRUjWQ2/WVZqpWMUw4fV6lJQrZssc7u20ro=; b=BD6hkuV7SqEceDjWrc79GGEjrhfAWSI2nnwMRqxBC1wHdpy1yRJ+a6zYO2AGFNXBj+ KyMomUoamsyd23PlvMAaBoLGEbtyJcYuQqoS1kFhcAHxJXgYjaae78mlnYaXX7GgJsqd jmnT8iotoPhxakgc/sMIaVIzA/vdGNxec6ZsEAHm00fUAhZmN/lRWEXVUOgledehduO3 h3eRsrv7j1rdWGfZtuPYZ9ZerErZVbaYNb7yO4r4thks0kPiq+MknsQwsmlJVOeLAfnG /XXv/Wvz4W2PEMI7n3qhk4tsHVYt1aJc+s51nfamgGU7tr3BNPxhk8dy+2vLhzH7CyAZ gNlQ== X-Gm-Message-State: AHQUAuaFu6cClp/dM3JU5ShR4cWTHWog3AFy1fEyDzTVxQZf6vy67dnc 2E47rsyvwVgnsWhO6IRGaT1NtN7oiZc= X-Google-Smtp-Source: AHgI3IaDGrRwyEYK1Qde+m1UowQ6B3cC1cYHwA5AxUtWLVTrYQLftyGFHvbiu9gAp/nttbshuQOVvA== X-Received: by 2002:ac8:27ba:: with SMTP id w55mr16697968qtw.228.1551158296891; Mon, 25 Feb 2019 21:18:16 -0800 (PST) Received: from mango.spo.virtua.com.br ([2804:14c:81:942d::3]) by smtp.gmail.com with ESMTPSA id k39sm7698738qtb.37.2019.02.25.21.18.14 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 25 Feb 2019 21:18:16 -0800 (PST) From: Matheus Tavares To: git@vger.kernel.org Cc: Thomas Gummerer , =?utf-8?b?w4Z2YXIgQXJuZmrDtnI=?= =?utf-8?b?w7AgQmphcm1hc29u?= , Christian Couder , Michael Haggerty , Ramsay Jones , =?utf-8?b?Tmd1eeG7hW4gVGjDoWkg?= =?utf-8?b?Tmfhu41jIER1eQ==?= , Junio C Hamano Subject: [WIP RFC PATCH v2 1/5] dir-iterator: add flags parameter to dir_iterator_begin Date: Tue, 26 Feb 2019 02:18:00 -0300 Message-Id: <20190226051804.10631-2-matheus.bernardino@usp.br> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190226051804.10631-1-matheus.bernardino@usp.br> References: <20190226051804.10631-1-matheus.bernardino@usp.br> MIME-Version: 1.0 Sender: git-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Add the possibility of giving flags to dir_iterator_begin to initialize a dir-iterator with special options. Currently possible flags are DIR_ITERATOR_PEDANTIC, which makes dir_iterator_advance abort imediatelly in the case of an error while trying to fetch next entry; and DIR_ITERATOR_FOLLOW_SYMLINKS, which makes the iteration follow symlinks to directories and include its contents in the iteration. These new flags will be used in a subsequent patch. Also adjust refs/files-backend.c to the new dir_iterator_begin signature. Signed-off-by: Matheus Tavares --- dir-iterator.c | 28 +++++++++++++++++++++++++--- dir-iterator.h | 40 ++++++++++++++++++++++++++++++++-------- refs/files-backend.c | 2 +- 3 files changed, 58 insertions(+), 12 deletions(-) diff --git a/dir-iterator.c b/dir-iterator.c index f2dcd82fde..17aca8ea41 100644 --- a/dir-iterator.c +++ b/dir-iterator.c @@ -48,12 +48,16 @@ struct dir_iterator_int { * that will be included in this iteration. */ struct dir_iterator_level *levels; + + /* Combination of flags for this dir-iterator */ + unsigned flags; }; int dir_iterator_advance(struct dir_iterator *dir_iterator) { struct dir_iterator_int *iter = (struct dir_iterator_int *)dir_iterator; + int ret; while (1) { struct dir_iterator_level *level = @@ -71,6 +75,8 @@ int dir_iterator_advance(struct dir_iterator *dir_iterator) level->dir = opendir(iter->base.path.buf); if (!level->dir && errno != ENOENT) { + if (iter->flags & DIR_ITERATOR_PEDANTIC) + goto error_out; warning("error opening directory %s: %s", iter->base.path.buf, strerror(errno)); /* Popping the level is handled below */ @@ -122,6 +128,8 @@ int dir_iterator_advance(struct dir_iterator *dir_iterator) if (!de) { /* This level is exhausted; pop up a level. */ if (errno) { + if (iter->flags & DIR_ITERATOR_PEDANTIC) + goto error_out; warning("error reading directory %s: %s", iter->base.path.buf, strerror(errno)); } else if (closedir(level->dir)) @@ -138,11 +146,20 @@ int dir_iterator_advance(struct dir_iterator *dir_iterator) continue; strbuf_addstr(&iter->base.path, de->d_name); - if (lstat(iter->base.path.buf, &iter->base.st) < 0) { - if (errno != ENOENT) + + if (iter->flags & DIR_ITERATOR_FOLLOW_SYMLINKS) + ret = stat(iter->base.path.buf, &iter->base.st); + else + ret = lstat(iter->base.path.buf, &iter->base.st); + + if (ret < 0) { + if (errno != ENOENT) { + if (iter->flags & DIR_ITERATOR_PEDANTIC) + goto error_out; warning("error reading path '%s': %s", iter->base.path.buf, strerror(errno)); + } continue; } @@ -159,6 +176,10 @@ int dir_iterator_advance(struct dir_iterator *dir_iterator) return ITER_OK; } } + +error_out: + dir_iterator_abort(dir_iterator); + return ITER_ERROR; } int dir_iterator_abort(struct dir_iterator *dir_iterator) @@ -182,7 +203,7 @@ int dir_iterator_abort(struct dir_iterator *dir_iterator) return ITER_DONE; } -struct dir_iterator *dir_iterator_begin(const char *path) +struct dir_iterator *dir_iterator_begin(const char *path, unsigned flags) { struct dir_iterator_int *iter = xcalloc(1, sizeof(*iter)); struct dir_iterator *dir_iterator = &iter->base; @@ -195,6 +216,7 @@ struct dir_iterator *dir_iterator_begin(const char *path) ALLOC_GROW(iter->levels, 10, iter->levels_alloc); + iter->flags = flags; iter->levels_nr = 1; iter->levels[0].initialized = 0; diff --git a/dir-iterator.h b/dir-iterator.h index 970793d07a..fe9eb9a04b 100644 --- a/dir-iterator.h +++ b/dir-iterator.h @@ -6,9 +6,10 @@ /* * Iterate over a directory tree. * - * Iterate over a directory tree, recursively, including paths of all - * types and hidden paths. Skip "." and ".." entries and don't follow - * symlinks except for the original path. + * With no flags to modify behaviour, iterate over a directory tree, + * recursively, including paths of all types and hidden paths. Skip + * "." and ".." entries and don't follow symlinks except for the + * original path. * * Every time dir_iterator_advance() is called, update the members of * the dir_iterator structure to reflect the next path in the @@ -19,7 +20,7 @@ * A typical iteration looks like this: * * int ok; - * struct iterator *iter = dir_iterator_begin(path); + * struct iterator *iter = dir_iterator_begin(path, 0); * * while ((ok = dir_iterator_advance(iter)) == ITER_OK) { * if (want_to_stop_iteration()) { @@ -40,6 +41,20 @@ * dir_iterator_advance() again. */ +/* + * Flags for dir_iterator_begin: + * + * - DIR_ITERATOR_PEDANTIC: override dir-iterator's default behavior + * in case of an error while trying to fetch the next entry, which is + * to emit a warning and keep going. With this flag, resouces are + * freed and ITER_ERROR is return immediately. + * + * - DIR_ITERATOR_FOLLOW_SYMLINKS: make dir-iterator follow symlinks to + * directories, i.e., iterate over linked directories' contents. + */ +#define DIR_ITERATOR_PEDANTIC (1 << 0) +#define DIR_ITERATOR_FOLLOW_SYMLINKS (1 << 1) + struct dir_iterator { /* The current path: */ struct strbuf path; @@ -59,15 +74,19 @@ struct dir_iterator { }; /* - * Start a directory iteration over path. Return a dir_iterator that - * holds the internal state of the iteration. + * Start a directory iteration over path with the combination of + * options specified by flags. Return a dir_iterator that holds the + * internal state of the iteration. * * The iteration includes all paths under path, not including path * itself and not including "." or ".." entries. * - * path is the starting directory. An internal copy will be made. + * Parameters are: + * - path is the starting directory. An internal copy will be made. + * - flags is a combination of the possible flags to initialize a + * dir-iterator or 0 for default behaviour. */ -struct dir_iterator *dir_iterator_begin(const char *path); +struct dir_iterator *dir_iterator_begin(const char *path, unsigned flags); /* * Advance the iterator to the first or next item and return ITER_OK. @@ -76,6 +95,11 @@ struct dir_iterator *dir_iterator_begin(const char *path); * dir_iterator and associated resources and return ITER_ERROR. It is * a bug to use iterator or call this function again after it has * returned ITER_DONE or ITER_ERROR. + * + * Note that whether dir-iterator will return ITER_ERROR when failing + * to fetch the next entry or just emit a warning and try to fetch the + * next is defined by the 'pedantic' option at dir-iterator's + * initialization. */ int dir_iterator_advance(struct dir_iterator *iterator); diff --git a/refs/files-backend.c b/refs/files-backend.c index dd8abe9185..c3d3b6c454 100644 --- a/refs/files-backend.c +++ b/refs/files-backend.c @@ -2143,7 +2143,7 @@ static struct ref_iterator *reflog_iterator_begin(struct ref_store *ref_store, base_ref_iterator_init(ref_iterator, &files_reflog_iterator_vtable, 0); strbuf_addf(&sb, "%s/logs", gitdir); - iter->dir_iterator = dir_iterator_begin(sb.buf); + iter->dir_iterator = dir_iterator_begin(sb.buf, 0); iter->ref_store = ref_store; strbuf_release(&sb); From patchwork Tue Feb 26 05:18:01 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Matheus Tavares X-Patchwork-Id: 10829447 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 8FCDF17E6 for ; Tue, 26 Feb 2019 05:18:31 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 7B60D2AF61 for ; Tue, 26 Feb 2019 05:18:31 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 6F62B2B156; Tue, 26 Feb 2019 05:18:31 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 482E52B150 for ; Tue, 26 Feb 2019 05:18:30 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726355AbfBZFS1 (ORCPT ); Tue, 26 Feb 2019 00:18:27 -0500 Received: from mail-qk1-f194.google.com ([209.85.222.194]:39990 "EHLO mail-qk1-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725935AbfBZFSV (ORCPT ); Tue, 26 Feb 2019 00:18:21 -0500 Received: by mail-qk1-f194.google.com with SMTP id h28so6868563qkk.7 for ; Mon, 25 Feb 2019 21:18:20 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=usp-br.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=2VBCbEalpvej4pRqRGSoL0+qKiWUvVnXBsb1ZAEVVMg=; b=ILfArA5ejuIOfGJQHw7jaLLQSBAdtR32EcKDra299fV3DIlqwkhPNE/7FMxRvtSioe vJLSTDgKx8Wa7YkWf1mStBYrwH61W1bG/nCSmDCRO+OriFPhw4u9+1cvy94k08XZZSTW H7aVVOn6IrSukzPcE4haN0+fQXNZjkVi8IKmyyvcfVgLXsgvESQHnC4ezyHRIsceNww7 wlpQP2y//5GjnTPynuH0A/R9uDqBdthDZHOxkdMXE5fIO6aja+O5CmNLeGptahePwPNO KpdobxiO23Edr3MKBvUtISE/A407W+khXN9TCRC7hjVg8M3ORgjkJ8bXRfZvfGpxrEC2 5nrw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=2VBCbEalpvej4pRqRGSoL0+qKiWUvVnXBsb1ZAEVVMg=; b=Lqni6ZT4Afg4zS02J7dfLgcRWtQpYUxuCQgROmrx5fuoBzOAvwNreWbeFQq3LXkLMn blaJwBlrqQIpQNImoBbGf3UzjYx4sNm0cWa5BTPB/bmbm3OwTQYfoHkfaAg5lu1aqTBC ToaTHqxAKVsTX4oipxNez5zqMQNNvc8pXOjOMc2Rfds4sfibd5eGFDhDmGVcApn8Hd20 1XfacyiwtQEe+OdesO1MUg5vAleBSSIu+KdHEGrN0+khOvbFHC2L89OTMJ6qX2LcFdZD pFibBM4ZfCGaLeA/9AIe0YSPrURnPc3UZ3t7XkhjdH2yTJmiBXdMCQ4gU3OCVq+QqnMl l6Ow== X-Gm-Message-State: AHQUAubF4Y24YHQfNStZVNlj/0A5/gji+Kvd+0RcM0LuR791ICSJb+93 MBNM3ypGqlYgbnOhPDm2V6cdQ92cMUs= X-Google-Smtp-Source: AHgI3Ibb8b7s8CcW80pAx2tGmX5Cfa6QVR4D03JFhUVjmUXVGuodjukB26N9IZ/wslzUySchY00aPA== X-Received: by 2002:a37:de04:: with SMTP id h4mr15628073qkj.277.1551158299705; Mon, 25 Feb 2019 21:18:19 -0800 (PST) Received: from mango.spo.virtua.com.br ([2804:14c:81:942d::3]) by smtp.gmail.com with ESMTPSA id k39sm7698738qtb.37.2019.02.25.21.18.17 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 25 Feb 2019 21:18:19 -0800 (PST) From: Matheus Tavares To: git@vger.kernel.org Cc: Thomas Gummerer , =?utf-8?b?w4Z2YXIgQXJuZmrDtnI=?= =?utf-8?b?w7AgQmphcm1hc29u?= , Christian Couder , Junio C Hamano , Alex Riesen Subject: [WIP RFC PATCH v2 2/5] clone: test for our behavior on odd objects/* content Date: Tue, 26 Feb 2019 02:18:01 -0300 Message-Id: <20190226051804.10631-3-matheus.bernardino@usp.br> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190226051804.10631-1-matheus.bernardino@usp.br> References: <20190226051804.10631-1-matheus.bernardino@usp.br> MIME-Version: 1.0 Sender: git-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Ævar Arnfjörð Bjarmason We've implicitly supported .git/objects/* content of symlinks since approximately forever, and when we do a copy of the repo we transfer those over, but aren't very consistent about other random stuff we find depending on if it's a "hidden" file or not. Let's add a test for that, which shouldn't read as an endorsement of what we're doing now, just asserts current behavior. Signed-off-by: Ævar Arnfjörð Bjarmason --- t/t5604-clone-reference.sh | 60 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/t/t5604-clone-reference.sh b/t/t5604-clone-reference.sh index 4320082b1b..6f9c77049e 100755 --- a/t/t5604-clone-reference.sh +++ b/t/t5604-clone-reference.sh @@ -221,4 +221,64 @@ test_expect_success 'clone, dissociate from alternates' ' ( cd C && git fsck ) ' +test_expect_success SHA1,SYMLINKS 'setup repo with manually symlinked objects/*' ' + git init S && + ( + cd S && + test_commit A && + git gc && + test_commit B && + ( + cd .git/objects && + mv 22/3b7836fb19fdf64ba2d3cd6173c6a283141f78 . && + ln -s ../3b7836fb19fdf64ba2d3cd6173c6a283141f78 22/ && + mv 40 forty && + ln -s forty 40 && + mv pack packs && + ln -s packs pack && + >.some-hidden-file && + >some-file && + mkdir .some-hidden-dir && + >.some-hidden-dir/some-file && + >.some-hidden-dir/.some-dot-file && + mkdir some-dir && + >some-dir/some-file && + >some-dir/.some-dot-file + ) + ) +' + +test_expect_success SHA1,SYMLINKS 'clone repo with manually symlinked objects/*' ' + for option in --local --no-hardlinks --shared --dissociate + do + git clone $option S S$option || return 1 && + git -C S$option fsck || return 1 + done && + find S-* -type l | sort >actual && + cat >expected <<-EOF && + S--dissociate/.git/objects/22/3b7836fb19fdf64ba2d3cd6173c6a283141f78 + S--local/.git/objects/22/3b7836fb19fdf64ba2d3cd6173c6a283141f78 + EOF + test_cmp expected actual && + find S-* -name "*some*" | sort >actual && + cat >expected <<-EOF && + S--dissociate/.git/objects/.some-hidden-file + S--dissociate/.git/objects/some-dir + S--dissociate/.git/objects/some-dir/.some-dot-file + S--dissociate/.git/objects/some-dir/some-file + S--dissociate/.git/objects/some-file + S--local/.git/objects/.some-hidden-file + S--local/.git/objects/some-dir + S--local/.git/objects/some-dir/.some-dot-file + S--local/.git/objects/some-dir/some-file + S--local/.git/objects/some-file + S--no-hardlinks/.git/objects/.some-hidden-file + S--no-hardlinks/.git/objects/some-dir + S--no-hardlinks/.git/objects/some-dir/.some-dot-file + S--no-hardlinks/.git/objects/some-dir/some-file + S--no-hardlinks/.git/objects/some-file + EOF + test_cmp expected actual +' + test_done From patchwork Tue Feb 26 05:18:02 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Matheus Tavares X-Patchwork-Id: 10829451 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 249051390 for ; Tue, 26 Feb 2019 05:18:33 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 119942AF61 for ; Tue, 26 Feb 2019 05:18:33 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 064052B150; Tue, 26 Feb 2019 05:18:33 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 1E2A92B07E for ; Tue, 26 Feb 2019 05:18:30 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726354AbfBZFSZ (ORCPT ); Tue, 26 Feb 2019 00:18:25 -0500 Received: from mail-qt1-f196.google.com ([209.85.160.196]:32973 "EHLO mail-qt1-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726350AbfBZFSX (ORCPT ); Tue, 26 Feb 2019 00:18:23 -0500 Received: by mail-qt1-f196.google.com with SMTP id z39so13558283qtz.0 for ; Mon, 25 Feb 2019 21:18:22 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=usp-br.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=wfOGdJUiZvT2aoDcuRaI476AOwB+2at0V1yPERfuFEk=; b=ptOKQ+a4VXlwd1txG2XWM/h7mxp9Ojbdxza6/7H+m0CYSlioejbA1OdDlR8ILonhno 7IMgbPgHJEvfw5NkGBWg2cAl+1Ni/SvwUiLpXcUWepnGsXQkGhpVbNRrfXtf+o2ECKAk O98rjEyX8LY7R4NZLbcl0R5F6yucKF7FCHH8jqo/KbRYyGLYYdaQiCQMUhwEinWFktud ur0TRtIkQ/rY51LklTu9BTe3wKprOfe4iaoIgzq6ghFUD8dj2MlBIEsCgtx9Rl6/7Pe3 MxGzeaj5MOimtczvKWxvfAQfA9lqmOGz4FSNizbiMjEquSqlUOUwX50tStQZqPlTsbKz cuTw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=wfOGdJUiZvT2aoDcuRaI476AOwB+2at0V1yPERfuFEk=; b=HNFATKzJ6WwZFfq9gaAij7s61j5ghZAkYMRw5oIAM07C0HtxOPmc5LdwWxYBz+1eFW /rw7PWV+nrH53rs3GAkNGE81y6s2N8JNPbXCKyzlgfkvDx+K8ITUmAI8LLEjnRjqbbp2 z1WRADNLFFIOyNGmV2s29/PyrLKbdo9ZdcoYju6DFkE3SPWRvOCJLHWasuM+/mjgSJ88 Pi5TB8weL3O7zWpCIrMYuBuJchYwj15H4zkwQrOy2xe7Ys1CERIgREUFs98XX2RqiNkf o1eHN2KzCKxfPCXMUwgTNBR5WBkh6r1CGQfyMq6JswTYmS+BHdWvAxslhPPuqTw2PkkL FilA== X-Gm-Message-State: AHQUAub2AL5l+lc81Pk45c9IGQbnC0Xlq8KBvXaiuwXAeaEYl51LcWW7 Lt4dz4nNzM3pd16xcGXlgC4mTYt4EO8= X-Google-Smtp-Source: AHgI3Ib4Hc3/SnzyiGqWC3lJQ8xvdonY4n5K7FJPhfE4odWnGkklL1J76QxFVMqguCFWzBwK5iWtaw== X-Received: by 2002:aed:3aaa:: with SMTP id o39mr16882737qte.109.1551158302059; Mon, 25 Feb 2019 21:18:22 -0800 (PST) Received: from mango.spo.virtua.com.br ([2804:14c:81:942d::3]) by smtp.gmail.com with ESMTPSA id k39sm7698738qtb.37.2019.02.25.21.18.20 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 25 Feb 2019 21:18:21 -0800 (PST) From: Matheus Tavares To: git@vger.kernel.org Cc: Thomas Gummerer , =?utf-8?b?w4Z2YXIgQXJuZmrDtnI=?= =?utf-8?b?w7AgQmphcm1hc29u?= , Christian Couder , Junio C Hamano Subject: [WIP RFC PATCH v2 3/5] clone: copy hidden paths at local clone Date: Tue, 26 Feb 2019 02:18:02 -0300 Message-Id: <20190226051804.10631-4-matheus.bernardino@usp.br> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190226051804.10631-1-matheus.bernardino@usp.br> References: <20190226051804.10631-1-matheus.bernardino@usp.br> MIME-Version: 1.0 Sender: git-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Make the copy_or_link_directory function no longer skip hidden paths. This function, used to copy .git/objects, currently skips all hidden directories but not hidden files, which is an odd behaviour. The reason for that could be unintentional: probably the intention was to skip '.' and '..' only but it ended up accidentally skipping all directories starting with '.'. Besides being more natural, the new behaviour is more permissive to the user. Also adjusted tests to reflect this change. Signed-off-by: Matheus Tavares Signed-off-by: Ævar Arnfjörð Bjarmason --- builtin/clone.c | 2 +- t/t5604-clone-reference.sh | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/builtin/clone.c b/builtin/clone.c index 50bde99618..cae069f03b 100644 --- a/builtin/clone.c +++ b/builtin/clone.c @@ -428,7 +428,7 @@ static void copy_or_link_directory(struct strbuf *src, struct strbuf *dest, continue; } if (S_ISDIR(buf.st_mode)) { - if (de->d_name[0] != '.') + if (!is_dot_or_dotdot(de->d_name)) copy_or_link_directory(src, dest, src_repo, src_baselen); continue; diff --git a/t/t5604-clone-reference.sh b/t/t5604-clone-reference.sh index 6f9c77049e..f1a8e74c44 100755 --- a/t/t5604-clone-reference.sh +++ b/t/t5604-clone-reference.sh @@ -262,16 +262,25 @@ test_expect_success SHA1,SYMLINKS 'clone repo with manually symlinked objects/*' test_cmp expected actual && find S-* -name "*some*" | sort >actual && cat >expected <<-EOF && + S--dissociate/.git/objects/.some-hidden-dir + S--dissociate/.git/objects/.some-hidden-dir/.some-dot-file + S--dissociate/.git/objects/.some-hidden-dir/some-file S--dissociate/.git/objects/.some-hidden-file S--dissociate/.git/objects/some-dir S--dissociate/.git/objects/some-dir/.some-dot-file S--dissociate/.git/objects/some-dir/some-file S--dissociate/.git/objects/some-file + S--local/.git/objects/.some-hidden-dir + S--local/.git/objects/.some-hidden-dir/.some-dot-file + S--local/.git/objects/.some-hidden-dir/some-file S--local/.git/objects/.some-hidden-file S--local/.git/objects/some-dir S--local/.git/objects/some-dir/.some-dot-file S--local/.git/objects/some-dir/some-file S--local/.git/objects/some-file + S--no-hardlinks/.git/objects/.some-hidden-dir + S--no-hardlinks/.git/objects/.some-hidden-dir/.some-dot-file + S--no-hardlinks/.git/objects/.some-hidden-dir/some-file S--no-hardlinks/.git/objects/.some-hidden-file S--no-hardlinks/.git/objects/some-dir S--no-hardlinks/.git/objects/some-dir/.some-dot-file From patchwork Tue Feb 26 05:18:03 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matheus Tavares X-Patchwork-Id: 10829449 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 2B97D1390 for ; Tue, 26 Feb 2019 05:18:32 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 192A72AF61 for ; Tue, 26 Feb 2019 05:18:32 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 0D8382B156; Tue, 26 Feb 2019 05:18:32 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id AB6132AF61 for ; Tue, 26 Feb 2019 05:18:31 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726364AbfBZFS3 (ORCPT ); Tue, 26 Feb 2019 00:18:29 -0500 Received: from mail-qk1-f175.google.com ([209.85.222.175]:43857 "EHLO mail-qk1-f175.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726351AbfBZFSZ (ORCPT ); Tue, 26 Feb 2019 00:18:25 -0500 Received: by mail-qk1-f175.google.com with SMTP id f196so6856258qke.10 for ; Mon, 25 Feb 2019 21:18:25 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=usp-br.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=86wUssbtwenoScENzMPC3Yc0ZwSX1nx/hz6/nOehjQY=; b=fMvyPLiGS/AHWDhnLtCBPvQnDS/SFmR/hJuK65o0kUQsXbvn7Av/GeH+U5EK2jhieB 5nF8yQMW9nwup2tBuOU/6bC2v4mBckXQiWD6OsugNtCQfmRYeZrQgb0YKSY8JBnbuccL /2qssS3Ia2ALPqk51lBnNnWjdKcX7htcmLHZL92ot2dXq+Ai49+f4lsHaIMo6bCJjvsN llHjg0dDWAqArjbzuquD8pCF79YgTWowmhnmcOggUHRJ95FaNGzniKWh8QutNeWGLCRq 8cdl0rFcboEMf5pVzDOUqcOlgRGMWxq8C6zLzXUzSnmmv3OF1t1TcYLldsV9hZEfd0LX lkEA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=86wUssbtwenoScENzMPC3Yc0ZwSX1nx/hz6/nOehjQY=; b=tIKXVJrUHQTgsUzNqKp2ZYvsY6pRHcfJkEg2pnhPdMwVnNh0ZznoFSt0ibeh4BQPTG GaNY6wjyrgh8wmplOxgNGtpzDeiWGlbhCOBbDh9aT+VbHWmQPzugXu8BRaXwRAoeeYzL Xq4K4OhqyznIzObKRiUG34tYDo9G53I7DgsoyaERrmZ5TeRslswfuYO8newHOY7+Oojt +7MezUisuhhh7ThznC4ecG5LNtLjCYX3vc3+fYOBQdBhMe3uvhZa1t36wdC3lgx8rJur gKNLe/LlrhIfcNIOOFi9awXnG2k7JpYtb6GT6HXvomKl61RlMWITne97ZEAvMR3YHKFv FZyQ== X-Gm-Message-State: AHQUAubgSNR9BXdSnqnKk6UnxveBhsPLv7JqZ6yrxfAL1MoIKSnQ0ZRM A9occ4MQsi/6Idw/oaXNs7hqIP0AQzA= X-Google-Smtp-Source: AHgI3IaaT8OGMbUQSs09r+RWxVHQHNtRzqKL0HRZM0xq7r0Za8R6LEF2ZpI7HykxG9I2ifJOLVdpcQ== X-Received: by 2002:a37:d150:: with SMTP id s77mr15881483qki.334.1551158304414; Mon, 25 Feb 2019 21:18:24 -0800 (PST) Received: from mango.spo.virtua.com.br ([2804:14c:81:942d::3]) by smtp.gmail.com with ESMTPSA id k39sm7698738qtb.37.2019.02.25.21.18.22 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 25 Feb 2019 21:18:23 -0800 (PST) From: Matheus Tavares To: git@vger.kernel.org Cc: Thomas Gummerer , =?utf-8?b?w4Z2YXIgQXJuZmrDtnI=?= =?utf-8?b?w7AgQmphcm1hc29u?= , Christian Couder , Junio C Hamano Subject: [WIP RFC PATCH v2 4/5] clone: extract function from copy_or_link_directory Date: Tue, 26 Feb 2019 02:18:03 -0300 Message-Id: <20190226051804.10631-5-matheus.bernardino@usp.br> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190226051804.10631-1-matheus.bernardino@usp.br> References: <20190226051804.10631-1-matheus.bernardino@usp.br> MIME-Version: 1.0 Sender: git-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Extract dir creation code snippet from copy_or_link_directory to its own function named mkdir_if_missing. This change will help removing copy_or_link_directory's explicit recursion, which will be done in a following patch. Also makes code more readable. Signed-off-by: Matheus Tavares --- builtin/clone.c | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/builtin/clone.c b/builtin/clone.c index cae069f03b..fd580fa98d 100644 --- a/builtin/clone.c +++ b/builtin/clone.c @@ -392,6 +392,24 @@ static void copy_alternates(struct strbuf *src, struct strbuf *dst, fclose(in); } +static void mkdir_if_missing(const char *pathname, mode_t mode) +{ + /* + * Create a dir at pathname unless there's already one. + */ + struct stat st; + + if (mkdir(pathname, mode)) { + if (errno != EEXIST) + die_errno(_("failed to create directory '%s'"), + pathname); + else if (stat(pathname, &st)) + die_errno(_("failed to stat '%s'"), pathname); + else if (!S_ISDIR(st.st_mode)) + die(_("%s exists and is not a directory"), pathname); + } +} + static void copy_or_link_directory(struct strbuf *src, struct strbuf *dest, const char *src_repo, int src_baselen) { @@ -404,14 +422,7 @@ static void copy_or_link_directory(struct strbuf *src, struct strbuf *dest, if (!dir) die_errno(_("failed to open '%s'"), src->buf); - if (mkdir(dest->buf, 0777)) { - if (errno != EEXIST) - die_errno(_("failed to create directory '%s'"), dest->buf); - else if (stat(dest->buf, &buf)) - die_errno(_("failed to stat '%s'"), dest->buf); - else if (!S_ISDIR(buf.st_mode)) - die(_("%s exists and is not a directory"), dest->buf); - } + mkdir_if_missing(dest->buf, 0777); strbuf_addch(src, '/'); src_len = src->len; From patchwork Tue Feb 26 05:18:04 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matheus Tavares X-Patchwork-Id: 10829453 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 0E9AA139A for ; Tue, 26 Feb 2019 05:18:34 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id EFBF02AF61 for ; Tue, 26 Feb 2019 05:18:33 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id E41F02B156; Tue, 26 Feb 2019 05:18:33 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 753492AF61 for ; Tue, 26 Feb 2019 05:18:33 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726382AbfBZFSc (ORCPT ); Tue, 26 Feb 2019 00:18:32 -0500 Received: from mail-qt1-f195.google.com ([209.85.160.195]:46284 "EHLO mail-qt1-f195.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726356AbfBZFS2 (ORCPT ); Tue, 26 Feb 2019 00:18:28 -0500 Received: by mail-qt1-f195.google.com with SMTP id z25so13472690qti.13 for ; Mon, 25 Feb 2019 21:18:27 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=usp-br.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=qVm1/NUY9NbnABf9WlDCR44AvDf3yo7MK5/rODO+KJs=; b=lDga0dgNCdnxWCbq/sfSr4oRQv+IeCoy+UCAY36euL8vJu4mtYeobqd7UOrPJ7dlxL /8KaTTLuLacmnt8FCnm/FxcUzu5JTPa19VmeDASQIPWfax5Gh9gaAZkvFqJFZd2TEwLo GjBFOlYOb0+p9X18XG22+Lcd5zfBLLnZNQjdhrirp18ljAmQnSv6dHkzzw+AIQege4+H OsNBjjlC6XmigIwKEJigWisTlFfys+/CynHGjc9awf7D38O9Hq+ISu5yNWZT6iXoIi6K qJkWvhDe+GcO0W+/UNOBJL2KjYlrB8GCPghe62uhmrepap5PqvsNp/MMl1sjlmQ9RKAH LjSQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=qVm1/NUY9NbnABf9WlDCR44AvDf3yo7MK5/rODO+KJs=; b=gYuKLFXgco83C9S85JM5B/ZsTNlOjoH0q8Y7OVnoFRT8OMycXDJsn4euC9Mb+H4o9g +C6WUHvID/w4ZHJsleHV6NymRbxZXNJn9iEQmqAcLX+10xrnmkTUgv1jJhrCpEa0tn0k 77990VmX1Y6NwoZl2PgC719jkj9rujDP6iuFusfyHChSMahPhZHU+1jFRQ0TiNJf4iuk r7EbPBvQ3J0fDiEqAKOoWy2JkxUp3MajAy1K8Emtgkmsh7oA4rQ5GiNXiue07IsADcpi JLOUGVQTS4TQ6wanXLAVX49ip8ip+FS32FU07nHnlGqevoYSHV5K7T/14qxlGt/59J0u MDow== X-Gm-Message-State: AHQUAuaCYlCSleVIleevczhI8sF+ln5YlM6LXqxbWsXiRW3f7UL52CX4 0UVhbYingJPi3mI9NMu24ARJQPVM8Q8= X-Google-Smtp-Source: AHgI3IZxgdg1YuynNx3r7dO/UYYX/9KcLx+trc/ObHIqfDgAc7MJXhiQW4FIBBSUb/kYO5bKAmt/pA== X-Received: by 2002:ac8:3559:: with SMTP id z25mr10097073qtb.336.1551158307113; Mon, 25 Feb 2019 21:18:27 -0800 (PST) Received: from mango.spo.virtua.com.br ([2804:14c:81:942d::3]) by smtp.gmail.com with ESMTPSA id k39sm7698738qtb.37.2019.02.25.21.18.24 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 25 Feb 2019 21:18:26 -0800 (PST) From: Matheus Tavares To: git@vger.kernel.org Cc: Thomas Gummerer , =?utf-8?b?w4Z2YXIgQXJuZmrDtnI=?= =?utf-8?b?w7AgQmphcm1hc29u?= , Christian Couder , =?utf-8?b?Tmd1eeG7hW4gVGg=?= =?utf-8?b?w6FpIE5n4buNYyBEdXk=?= , Junio C Hamano Subject: [WIP RFC PATCH v2 5/5] clone: use dir-iterator to avoid explicit dir traversal Date: Tue, 26 Feb 2019 02:18:04 -0300 Message-Id: <20190226051804.10631-6-matheus.bernardino@usp.br> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190226051804.10631-1-matheus.bernardino@usp.br> References: <20190226051804.10631-1-matheus.bernardino@usp.br> MIME-Version: 1.0 Sender: git-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Replace usage of opendir/readdir/closedir API to traverse directories recursively, at copy_or_link_directory function, by the dir-iterator API. This simplifies the code and avoid recursive calls to copy_or_link_directory. This process also makes copy_or_link_directory call die() in case of an error on readdir or stat, inside dir_iterator_advance. Previously it would just print a warning for errors on stat and ignore errors on readdir, which isn't nice because a local git clone would end up successfully even though the .git/objects copy didn't fully succeeded. Signed-off-by: Matheus Tavares --- I can also make the change described in the last paragraph in a separate patch before this one, but I would have to undo it in this patch because dir-iterator already implements it. So, IMHO, it would be just noise and not worthy. builtin/clone.c | 45 +++++++++++++++++++++++---------------------- 1 file changed, 23 insertions(+), 22 deletions(-) diff --git a/builtin/clone.c b/builtin/clone.c index fd580fa98d..b23ba64c94 100644 --- a/builtin/clone.c +++ b/builtin/clone.c @@ -23,6 +23,8 @@ #include "transport.h" #include "strbuf.h" #include "dir.h" +#include "dir-iterator.h" +#include "iterator.h" #include "sigchain.h" #include "branch.h" #include "remote.h" @@ -411,42 +413,37 @@ static void mkdir_if_missing(const char *pathname, mode_t mode) } static void copy_or_link_directory(struct strbuf *src, struct strbuf *dest, - const char *src_repo, int src_baselen) + const char *src_repo) { - struct dirent *de; - struct stat buf; int src_len, dest_len; - DIR *dir; - - dir = opendir(src->buf); - if (!dir) - die_errno(_("failed to open '%s'"), src->buf); + struct dir_iterator *iter; + int iter_status; + struct stat st; + unsigned flags; mkdir_if_missing(dest->buf, 0777); + flags = DIR_ITERATOR_PEDANTIC | DIR_ITERATOR_FOLLOW_SYMLINKS; + iter = dir_iterator_begin(src->buf, flags); + strbuf_addch(src, '/'); src_len = src->len; strbuf_addch(dest, '/'); dest_len = dest->len; - while ((de = readdir(dir)) != NULL) { + while ((iter_status = dir_iterator_advance(iter)) == ITER_OK) { strbuf_setlen(src, src_len); - strbuf_addstr(src, de->d_name); + strbuf_addstr(src, iter->relative_path); strbuf_setlen(dest, dest_len); - strbuf_addstr(dest, de->d_name); - if (stat(src->buf, &buf)) { - warning (_("failed to stat %s\n"), src->buf); - continue; - } - if (S_ISDIR(buf.st_mode)) { - if (!is_dot_or_dotdot(de->d_name)) - copy_or_link_directory(src, dest, - src_repo, src_baselen); + strbuf_addstr(dest, iter->relative_path); + + if (S_ISDIR(iter->st.st_mode)) { + mkdir_if_missing(dest->buf, 0777); continue; } /* Files that cannot be copied bit-for-bit... */ - if (!strcmp(src->buf + src_baselen, "/info/alternates")) { + if (!strcmp(iter->relative_path, "info/alternates")) { copy_alternates(src, dest, src_repo); continue; } @@ -463,7 +460,11 @@ static void copy_or_link_directory(struct strbuf *src, struct strbuf *dest, if (copy_file_with_time(dest->buf, src->buf, 0666)) die_errno(_("failed to copy file to '%s'"), dest->buf); } - closedir(dir); + + if (iter_status != ITER_DONE) { + strbuf_setlen(src, src_len); + die(_("failed to iterate over '%s'"), src->buf); + } } static void clone_local(const char *src_repo, const char *dest_repo) @@ -481,7 +482,7 @@ static void clone_local(const char *src_repo, const char *dest_repo) get_common_dir(&dest, dest_repo); strbuf_addstr(&src, "/objects"); strbuf_addstr(&dest, "/objects"); - copy_or_link_directory(&src, &dest, src_repo, src.len); + copy_or_link_directory(&src, &dest, src_repo); strbuf_release(&src); strbuf_release(&dest); }