From patchwork Thu May 2 14:48:20 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Matheus Tavares X-Patchwork-Id: 10927015 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 F302817E6 for ; Thu, 2 May 2019 14:48:47 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id E0DC3285B0 for ; Thu, 2 May 2019 14:48:47 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id D4B2F285B3; Thu, 2 May 2019 14:48:47 +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 475E9285C3 for ; Thu, 2 May 2019 14:48:47 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726455AbfEBOsq (ORCPT ); Thu, 2 May 2019 10:48:46 -0400 Received: from mail-qt1-f193.google.com ([209.85.160.193]:37062 "EHLO mail-qt1-f193.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726197AbfEBOsq (ORCPT ); Thu, 2 May 2019 10:48:46 -0400 Received: by mail-qt1-f193.google.com with SMTP id e2so1145293qtb.4 for ; Thu, 02 May 2019 07:48:45 -0700 (PDT) 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=NiCRl9E184AC0nezd5RzjQnNgANF2yTHWJBF21CgeeE=; b=bgApjxZenseEIHl4eeQRSjyEDkka2SJyGGIWrBPEFN5l+auxN3U0gm3F3HfMAMu/un sNypCXDiWifd5axDN/Ezzr81b3RxVMlsq1WZld2m1J/L7sQdm9EKSra6lEtXm2dyKEJc mlSb9XKQhn6H2DhiIe6aMyV/5tJelbTbbSoGGDiZbUdXc5HZ6Z93q28ULRSvwzfsg1rZ KERZ4NIW5KtlaII4gmnLwegri9Hh6Gkb3YxYHjs2TWPt1Yymv/72xXg2TlgPFtWSlzAp Bkj6K5mUa/5irVVWvM0f+J/HuKCKKLsWFoEK7dbmp3L8ekfxeZ91ZLgvlmG4gLsJi1hK grzw== 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=NiCRl9E184AC0nezd5RzjQnNgANF2yTHWJBF21CgeeE=; b=ous/miQ06NY+PG7Tl45jdZ3j7Qur1Zb549doFLDT3qTLmbxhUbAX29Jl6prThGsm93 mtI2fL2fCw+DVGPvfZH43xyxhYZmC1LXjcyFsm8F9tkXWxIEDQBiXFjpJKLEJZQmuEib A8FbRvPQBj5In7kEeiHCmkgd0CRp5PFxUhRuV2Siqcx8d5B7qIe0IPaTWRwa8okJ3DI6 xq6xwbfd0MhWBsR+N70KR9ci2c4/UtKuXrww7moJlzmIvnzPC8Q3BqKOIyPxUmlzmFXB Kq3fNWDKw95g8GT6+HSXx9cAeyU05q3lqHC8Y36Duj/+8jI/LZrKxDfoY5kSlg+XU7KF CXbw== X-Gm-Message-State: APjAAAVZ1PxVVMEj3xrKnBspK9x6czNCDO1VjJ8uW23Aw1YzIDNuD9r7 cCeOVcGSUg5WlcvLouvVf1TkqtQL5Qs= X-Google-Smtp-Source: APXvYqxQinqhAB+oWMZCXgsdGMvny+1/zTQqwhcGpyePkIb//ELVK4P4k/O8FwqhSE4XNgZqE20udQ== X-Received: by 2002:aed:37e7:: with SMTP id j94mr3390165qtb.381.1556808524625; Thu, 02 May 2019 07:48:44 -0700 (PDT) Received: from mango.spo.virtua.com.br ([2804:14c:81:942d::1]) by smtp.gmail.com with ESMTPSA id s64sm22002880qkc.39.2019.05.02.07.48.41 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 02 May 2019 07:48:44 -0700 (PDT) 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=?= , =?utf-8?q?SZEDER_G?= =?utf-8?q?=C3=A1bor?= , kernel-usp@googlegroups.com, Junio C Hamano , Alex Riesen Subject: [GSoC][PATCH v6 01/10] clone: test for our behavior on odd objects/* content Date: Thu, 2 May 2019 11:48:20 -0300 Message-Id: <20190502144829.4394-2-matheus.bernardino@usp.br> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190502144829.4394-1-matheus.bernardino@usp.br> References: <20190330224907.3277-1-matheus.bernardino@usp.br> <20190502144829.4394-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 Add tests for what happens when we perform a local clone on a repo containing odd files at .git/object directory, such as symlinks to other dirs, or unknown files. I'm bending over backwards here to avoid a SHA-1 dependency. See [1] for an earlier and simpler version that hardcoded SHA-1s. This behavior has been the same for a *long* time, but hasn't been tested for. There's a good post-hoc argument to be made for copying over unknown things, e.g. I'd like a git version that doesn't know about the commit-graph to copy it under "clone --local" so a newer git version can make use of it. In follow-up commits we'll look at changing some of this behavior, but for now, let's just assert it as-is so we'll notice what we'll change later. 1. https://public-inbox.org/git/20190226002625.13022-5-avarab@gmail.com/ Signed-off-by: Ævar Arnfjörð Bjarmason [matheus.bernardino: improved and split tests in more than one patch] Helped-by: Matheus Tavares Signed-off-by: Matheus Tavares --- t/t5604-clone-reference.sh | 111 +++++++++++++++++++++++++++++++++++++ 1 file changed, 111 insertions(+) diff --git a/t/t5604-clone-reference.sh b/t/t5604-clone-reference.sh index 4320082b1b..207650cb95 100755 --- a/t/t5604-clone-reference.sh +++ b/t/t5604-clone-reference.sh @@ -221,4 +221,115 @@ test_expect_success 'clone, dissociate from alternates' ' ( cd C && git fsck ) ' +test_expect_success 'setup repo with garbage in objects/*' ' + git init S && + ( + cd S && + test_commit A && + + cd .git/objects && + >.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 'clone a repo with garbage in 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-* -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_expect_success SYMLINKS 'setup repo with manually symlinked dirs and unknown files at objects/' ' + git init T && + ( + cd T && + git config gc.auto 0 && + test_commit A && + git gc && + test_commit B && + + cd .git/objects && + mv pack packs && + ln -s packs pack && + find ?? -type d >loose-dirs && + last_loose=$(tail -n 1 loose-dirs) && + rm -f loose-dirs && + mv $last_loose a-loose-dir && + ln -s a-loose-dir $last_loose && + find . -type f | sort >../../../T.objects-files.raw && + echo unknown_content> unknown_file + ) && + git -C T fsck && + git -C T rev-list --all --objects >T.objects +' + + +test_expect_success SYMLINKS 'clone repo with symlinked dirs and unknown files at objects/' ' + for option in --local --no-hardlinks --shared --dissociate + do + git clone $option T T$option || return 1 && + git -C T$option fsck || return 1 && + git -C T$option rev-list --all --objects >T$option.objects && + test_cmp T.objects T$option.objects && + ( + cd T$option/.git/objects && + find . -type f | sort >../../../T$option.objects-files.raw + ) + done && + + for raw in $(ls T*.raw) + do + sed -e "s!/../!/Y/!; s![0-9a-f]\{38,\}!Z!" -e "/commit-graph/d" \ + -e "/multi-pack-index/d" <$raw >$raw.de-sha || return 1 + done && + + cat >expected-files <<-EOF && + ./Y/Z + ./Y/Z + ./a-loose-dir/Z + ./Y/Z + ./info/packs + ./pack/pack-Z.idx + ./pack/pack-Z.pack + ./packs/pack-Z.idx + ./packs/pack-Z.pack + ./unknown_file + EOF + + for option in --local --dissociate --no-hardlinks + do + test_cmp expected-files T$option.objects-files.raw.de-sha || return 1 + done && + + echo ./info/alternates >expected-files && + test_cmp expected-files T--shared.objects-files.raw +' + test_done From patchwork Thu May 2 14:48:21 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Matheus Tavares X-Patchwork-Id: 10927019 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 B28B81398 for ; Thu, 2 May 2019 14:48:51 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id A1DEE285B0 for ; Thu, 2 May 2019 14:48:51 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 95EFC285B5; Thu, 2 May 2019 14:48:51 +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 14DB5285B0 for ; Thu, 2 May 2019 14:48:51 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726462AbfEBOst (ORCPT ); Thu, 2 May 2019 10:48:49 -0400 Received: from mail-qt1-f194.google.com ([209.85.160.194]:33202 "EHLO mail-qt1-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726197AbfEBOst (ORCPT ); Thu, 2 May 2019 10:48:49 -0400 Received: by mail-qt1-f194.google.com with SMTP id g7so2811179qtc.0 for ; Thu, 02 May 2019 07:48:48 -0700 (PDT) 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=bFvO4wEM4HMFehMN7DNV1aj2/G+63hcDlFSqqOTdPOs=; b=SS36TTaWTdKNzbhk8C2gNx6dXY6wc6DBBxuTjp00jAn8rkTP92jqbSV1aM2fpZvd/S vjcMBmwYAXHA8nP2n5451gmnGaa2LYF/vyTcGn8rZkpBBYDo9wicpTA3pZcYlHHS5GC2 jbYi6ttjASnrZXIOgdPlNomSdXgkFZyUl7smpSHl1AXptoh+GV2P7bKrXWQHSU3fCAfT IYe0DjUwY0s6tozAwKYH3XA2O2UwVRXNlCNabWDukAsckbDoxtNb4Oh4BYTXOZEdz2wW 7H98YLuqykva067GjGxHteeRPtrVAU3FZAtvS7XrASXiOZwIbiVtWtYKTVwIwKkxVGJj 4oqQ== 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=bFvO4wEM4HMFehMN7DNV1aj2/G+63hcDlFSqqOTdPOs=; b=CaBlBR0sdSIuKWir4TTTbbl04N1HgxFXs7iiwRqGawaho+mERhuyYv/GJ5kFtz2qQJ 2CGnL7Ipu23Vfjm1fb8nOyBlrNMTwrCGwM+0kkl1Pp65k3O52d3mOSaLBao7Z2UOHVjz uq51VLJGl4hryF8YA0AhY9TZi03z2KqPFRvub+09WTFxPmhcKWYMfPq5gIh5JIBVkxcz n116O85xqTdauLueFl0+GoeFYR6PYRLbtUxfkNo0x+tTqgixGGHnEn0vxPWEGgHYeLZK pWeHJkAe49RQpp6kty/RHB6dUynUKWeWVnhwn9Ffr2UzUimGEn9OJvTYPzkvFr6Ba6Mm bfDw== X-Gm-Message-State: APjAAAU5iO7jxFbQ9iEcXNaiUjgRkWJZtxbZ8uZOPKd1UiG3P5v4lRky ITBloZqJDcT58vYCUVT8Fj7bo+LPmkw= X-Google-Smtp-Source: APXvYqyeMraZ0JOeuHQNuc8es5HB6IIByCNiQU9c8U0BIvAaGNrgaIVf3ljZ7zhNznswgxnJ5Zxbxw== X-Received: by 2002:a0c:bd2d:: with SMTP id m45mr3437227qvg.4.1556808528232; Thu, 02 May 2019 07:48:48 -0700 (PDT) Received: from mango.spo.virtua.com.br ([2804:14c:81:942d::1]) by smtp.gmail.com with ESMTPSA id s64sm22002880qkc.39.2019.05.02.07.48.45 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 02 May 2019 07:48:47 -0700 (PDT) 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=?= , =?utf-8?q?SZEDER_G?= =?utf-8?q?=C3=A1bor?= , kernel-usp@googlegroups.com, Junio C Hamano , Michael Haggerty Subject: [GSoC][PATCH v6 02/10] clone: better handle symlinked files at .git/objects/ Date: Thu, 2 May 2019 11:48:21 -0300 Message-Id: <20190502144829.4394-3-matheus.bernardino@usp.br> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190502144829.4394-1-matheus.bernardino@usp.br> References: <20190330224907.3277-1-matheus.bernardino@usp.br> <20190502144829.4394-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 There is currently an odd behaviour when locally cloning a repository with symlinks at .git/objects: using --no-hardlinks all symlinks are dereferenced but without it, Git will try to hardlink the files with the link() function, which has an OS-specific behaviour on symlinks. On OSX and NetBSD, it creates a hardlink to the file pointed by the symlink whilst on GNU/Linux, it creates a hardlink to the symlink itself. On Manjaro GNU/Linux: $ touch a $ ln -s a b $ link b c $ ls -li a b c 155 [...] a 156 [...] b -> a 156 [...] c -> a But on NetBSD: $ ls -li a b c 2609160 [...] a 2609164 [...] b -> a 2609160 [...] c It's not good to have the result of a local clone to be OS-dependent and besides that, the current behaviour on GNU/Linux may result in broken symlinks. So let's standardize this by making the hardlinks always point to dereferenced paths, instead of the symlinks themselves. Also, add tests for symlinked files at .git/objects/. Note: Git won't create symlinks at .git/objects itself, but it's better to handle this case and be friendly with users who manually create them. Signed-off-by: Matheus Tavares Signed-off-by: Ævar Arnfjörð Bjarmason Co-authored-by: Ævar Arnfjörð Bjarmason --- builtin/clone.c | 2 +- t/t5604-clone-reference.sh | 27 ++++++++++++++++++++------- 2 files changed, 21 insertions(+), 8 deletions(-) diff --git a/builtin/clone.c b/builtin/clone.c index 50bde99618..d1aba3b13f 100644 --- a/builtin/clone.c +++ b/builtin/clone.c @@ -443,7 +443,7 @@ static void copy_or_link_directory(struct strbuf *src, struct strbuf *dest, if (unlink(dest->buf) && errno != ENOENT) die_errno(_("failed to unlink '%s'"), dest->buf); if (!option_no_hardlinks) { - if (!link(src->buf, dest->buf)) + if (!link(real_path(src->buf), dest->buf)) continue; if (option_local > 0) die_errno(_("failed to create link '%s'"), dest->buf); diff --git a/t/t5604-clone-reference.sh b/t/t5604-clone-reference.sh index 207650cb95..0800c3853f 100755 --- a/t/t5604-clone-reference.sh +++ b/t/t5604-clone-reference.sh @@ -266,7 +266,7 @@ test_expect_success 'clone a repo with garbage in objects/*' ' test_cmp expected actual ' -test_expect_success SYMLINKS 'setup repo with manually symlinked dirs and unknown files at objects/' ' +test_expect_success SYMLINKS 'setup repo with manually symlinked or unknown files at objects/' ' git init T && ( cd T && @@ -280,10 +280,19 @@ test_expect_success SYMLINKS 'setup repo with manually symlinked dirs and unknow ln -s packs pack && find ?? -type d >loose-dirs && last_loose=$(tail -n 1 loose-dirs) && - rm -f loose-dirs && mv $last_loose a-loose-dir && ln -s a-loose-dir $last_loose && + first_loose=$(head -n 1 loose-dirs) && + rm -f loose-dirs && + + cd $first_loose && + obj=$(ls *) && + mv $obj ../an-object && + ln -s ../an-object $obj && + + cd ../ && find . -type f | sort >../../../T.objects-files.raw && + find . -type l | sort >../../../T.objects-symlinks.raw && echo unknown_content> unknown_file ) && git -C T fsck && @@ -291,7 +300,7 @@ test_expect_success SYMLINKS 'setup repo with manually symlinked dirs and unknow ' -test_expect_success SYMLINKS 'clone repo with symlinked dirs and unknown files at objects/' ' +test_expect_success SYMLINKS 'clone repo with symlinked or unknown files at objects/' ' for option in --local --no-hardlinks --shared --dissociate do git clone $option T T$option || return 1 && @@ -300,7 +309,8 @@ test_expect_success SYMLINKS 'clone repo with symlinked dirs and unknown files a test_cmp T.objects T$option.objects && ( cd T$option/.git/objects && - find . -type f | sort >../../../T$option.objects-files.raw + find . -type f | sort >../../../T$option.objects-files.raw && + find . -type l | sort >../../../T$option.objects-symlinks.raw ) done && @@ -314,6 +324,7 @@ test_expect_success SYMLINKS 'clone repo with symlinked dirs and unknown files a ./Y/Z ./Y/Z ./a-loose-dir/Z + ./an-object ./Y/Z ./info/packs ./pack/pack-Z.idx @@ -323,13 +334,15 @@ test_expect_success SYMLINKS 'clone repo with symlinked dirs and unknown files a ./unknown_file EOF - for option in --local --dissociate --no-hardlinks + for option in --local --no-hardlinks --dissociate do - test_cmp expected-files T$option.objects-files.raw.de-sha || return 1 + test_cmp expected-files T$option.objects-files.raw.de-sha || return 1 && + test_must_be_empty T$option.objects-symlinks.raw.de-sha || return 1 done && echo ./info/alternates >expected-files && - test_cmp expected-files T--shared.objects-files.raw + test_cmp expected-files T--shared.objects-files.raw && + test_must_be_empty T--shared.objects-symlinks.raw ' test_done From patchwork Thu May 2 14:48:22 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matheus Tavares X-Patchwork-Id: 10927021 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 29F081398 for ; Thu, 2 May 2019 14:48:55 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 182FD285A4 for ; Thu, 2 May 2019 14:48:55 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 0CB6E285B5; Thu, 2 May 2019 14:48:55 +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 80FDC285B3 for ; Thu, 2 May 2019 14:48:54 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726463AbfEBOsx (ORCPT ); Thu, 2 May 2019 10:48:53 -0400 Received: from mail-qk1-f170.google.com ([209.85.222.170]:46927 "EHLO mail-qk1-f170.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726197AbfEBOsx (ORCPT ); Thu, 2 May 2019 10:48:53 -0400 Received: by mail-qk1-f170.google.com with SMTP id a132so1570837qkb.13 for ; Thu, 02 May 2019 07:48:52 -0700 (PDT) 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=mB5n3JEQy1vhFi3YcxAhOu5gfDalXMjUl148ZnzohqE=; b=s7R7tHVMvyoMdbt2DTDQvVJHlfgWTJppz0o2GMEkmi5t474JBQcATOLUWTqja7O5SP Tb/N8BtMLMnF3Ofqm6spL5jTyu7sye1iTHPMmFBO/WF1gMfTax2Fufwk7jTdRDNLKYQg 3uq+JGsYAOjNJ2BzjoPC2nM1PyXeFXs0hEOhptB5csrOb41OgyZs//3Clus3CBnmn8ox bVU/dzvLbju7gvENCTRxldjL8CCMFxSgGQCHOkASfPdGR5QFjZ/+P+gVyk2yGCBdApGD s6fB9HrzDofvTe20ZxnCLcxpZnp/xf0Sn0HV2SPHqjL6F8gUhjghz78Yy2x+qRbajS/m QmXw== 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=mB5n3JEQy1vhFi3YcxAhOu5gfDalXMjUl148ZnzohqE=; b=HtQLBVf6KtqfHgLpBTNzUcSZb0zyWoVJF4XSDoiRyFR2eJhCCF5tXNSF6wwpWxRYoK H63pvA64aqdJhl4Y8ZLxkKcecCsngBYjmRuvBqtv1Ccrw8pfAnmufX+S9FVKY2X7AB4c gaeh9Qf4A8xy48k4elAvzp9iGx9ILbZ9qjqtmlHgkw7eOU8f/rHAQ7v0YcFP2ZpScK7U MSB/cDSMSPvL/UuzfUFXwhlIZVdpWuXoC5pjWmPmpVFElXx3Yb0cV1QEzTEqim7WsxVa 5buqoom2WgVF+X47ei7Nn3LPHnoWPe8IGuuGOnk0RJh4TlRH4m+V0cDSxnd1zSTqo9Rm vovg== X-Gm-Message-State: APjAAAVhpYq5gVTIHEidtANeyMsTQ9hGANhkV4te3soOtXqcSCGhqAFT lgkm8SlkUUzYdjOwEYPxisC32qrdpZI= X-Google-Smtp-Source: APXvYqx6P+fmk8L1m1DL/mH0mF3hkybbFDph3ho6xFZDBygqFnxNBZh+FOcD7GMyBHqugvu0Pd4iVA== X-Received: by 2002:a05:620a:143c:: with SMTP id k28mr3051317qkj.278.1556808531569; Thu, 02 May 2019 07:48:51 -0700 (PDT) Received: from mango.spo.virtua.com.br ([2804:14c:81:942d::1]) by smtp.gmail.com with ESMTPSA id s64sm22002880qkc.39.2019.05.02.07.48.48 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 02 May 2019 07:48:51 -0700 (PDT) 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=?= , =?utf-8?q?SZEDER_G?= =?utf-8?q?=C3=A1bor?= , kernel-usp@googlegroups.com, Daniel Ferreira , Junio C Hamano Subject: [GSoC][PATCH v6 03/10] dir-iterator: add tests for dir-iterator API Date: Thu, 2 May 2019 11:48:22 -0300 Message-Id: <20190502144829.4394-4-matheus.bernardino@usp.br> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190502144829.4394-1-matheus.bernardino@usp.br> References: <20190330224907.3277-1-matheus.bernardino@usp.br> <20190502144829.4394-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: Daniel Ferreira Create t/helper/test-dir-iterator.c, which prints relevant information about a directory tree iterated over with dir-iterator. Create t/t0066-dir-iterator.sh, which tests that dir-iterator does iterate through a whole directory tree as expected. Signed-off-by: Daniel Ferreira [matheus.bernardino: update to use test-tool and some minor aesthetics] Helped-by: Matheus Tavares Signed-off-by: Matheus Tavares --- Makefile | 1 + t/helper/test-dir-iterator.c | 33 ++++++++++++++++++++++ t/helper/test-tool.c | 1 + t/helper/test-tool.h | 1 + t/t0066-dir-iterator.sh | 55 ++++++++++++++++++++++++++++++++++++ 5 files changed, 91 insertions(+) create mode 100644 t/helper/test-dir-iterator.c create mode 100755 t/t0066-dir-iterator.sh diff --git a/Makefile b/Makefile index 9f1b6e8926..61da7e4f35 100644 --- a/Makefile +++ b/Makefile @@ -713,6 +713,7 @@ TEST_BUILTINS_OBJS += test-config.o TEST_BUILTINS_OBJS += test-ctype.o TEST_BUILTINS_OBJS += test-date.o TEST_BUILTINS_OBJS += test-delta.o +TEST_BUILTINS_OBJS += test-dir-iterator.o TEST_BUILTINS_OBJS += test-drop-caches.o TEST_BUILTINS_OBJS += test-dump-cache-tree.o TEST_BUILTINS_OBJS += test-dump-fsmonitor.o diff --git a/t/helper/test-dir-iterator.c b/t/helper/test-dir-iterator.c new file mode 100644 index 0000000000..84f50bed8c --- /dev/null +++ b/t/helper/test-dir-iterator.c @@ -0,0 +1,33 @@ +#include "test-tool.h" +#include "git-compat-util.h" +#include "strbuf.h" +#include "iterator.h" +#include "dir-iterator.h" + +/* Argument is a directory path to iterate over */ +int cmd__dir_iterator(int argc, const char **argv) +{ + struct strbuf path = STRBUF_INIT; + struct dir_iterator *diter; + + if (argc < 2) + die("BUG: test-dir-iterator needs one argument"); + + strbuf_add(&path, argv[1], strlen(argv[1])); + + diter = dir_iterator_begin(path.buf); + + while (dir_iterator_advance(diter) == ITER_OK) { + if (S_ISDIR(diter->st.st_mode)) + printf("[d] "); + else if (S_ISREG(diter->st.st_mode)) + printf("[f] "); + else + printf("[?] "); + + printf("(%s) [%s] %s\n", diter->relative_path, diter->basename, + diter->path.buf); + } + + return 0; +} diff --git a/t/helper/test-tool.c b/t/helper/test-tool.c index 53c06932c4..89b3bfcad8 100644 --- a/t/helper/test-tool.c +++ b/t/helper/test-tool.c @@ -13,6 +13,7 @@ static struct test_cmd cmds[] = { { "ctype", cmd__ctype }, { "date", cmd__date }, { "delta", cmd__delta }, + { "dir-iterator", cmd__dir_iterator }, { "drop-caches", cmd__drop_caches }, { "dump-cache-tree", cmd__dump_cache_tree }, { "dump-fsmonitor", cmd__dump_fsmonitor }, diff --git a/t/helper/test-tool.h b/t/helper/test-tool.h index ffab4d19d7..0a831c839c 100644 --- a/t/helper/test-tool.h +++ b/t/helper/test-tool.h @@ -9,6 +9,7 @@ int cmd__config(int argc, const char **argv); int cmd__ctype(int argc, const char **argv); int cmd__date(int argc, const char **argv); int cmd__delta(int argc, const char **argv); +int cmd__dir_iterator(int argc, const char **argv); int cmd__drop_caches(int argc, const char **argv); int cmd__dump_cache_tree(int argc, const char **argv); int cmd__dump_fsmonitor(int argc, const char **argv); diff --git a/t/t0066-dir-iterator.sh b/t/t0066-dir-iterator.sh new file mode 100755 index 0000000000..6e06dc038d --- /dev/null +++ b/t/t0066-dir-iterator.sh @@ -0,0 +1,55 @@ +#!/bin/sh + +test_description='Test the dir-iterator functionality' + +. ./test-lib.sh + +test_expect_success 'setup' ' + mkdir -p dir && + mkdir -p dir/a/b/c/ && + >dir/b && + >dir/c && + mkdir -p dir/d/e/d/ && + >dir/a/b/c/d && + >dir/a/e && + >dir/d/e/d/a && + + mkdir -p dir2/a/b/c/ && + >dir2/a/b/c/d +' + +test_expect_success 'dir-iterator should iterate through all files' ' + cat >expected-iteration-sorted-output <<-EOF && + [d] (a) [a] ./dir/a + [d] (a/b) [b] ./dir/a/b + [d] (a/b/c) [c] ./dir/a/b/c + [d] (d) [d] ./dir/d + [d] (d/e) [e] ./dir/d/e + [d] (d/e/d) [d] ./dir/d/e/d + [f] (a/b/c/d) [d] ./dir/a/b/c/d + [f] (a/e) [e] ./dir/a/e + [f] (b) [b] ./dir/b + [f] (c) [c] ./dir/c + [f] (d/e/d/a) [a] ./dir/d/e/d/a + EOF + + test-tool dir-iterator ./dir >out && + sort ./actual-iteration-sorted-output && + + test_cmp expected-iteration-sorted-output actual-iteration-sorted-output +' + +test_expect_success 'dir-iterator should list files in the correct order' ' + cat >expected-pre-order-output <<-EOF && + [d] (a) [a] ./dir2/a + [d] (a/b) [b] ./dir2/a/b + [d] (a/b/c) [c] ./dir2/a/b/c + [f] (a/b/c/d) [d] ./dir2/a/b/c/d + EOF + + test-tool dir-iterator ./dir2 >actual-pre-order-output && + + test_cmp expected-pre-order-output actual-pre-order-output +' + +test_done From patchwork Thu May 2 14:48:23 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matheus Tavares X-Patchwork-Id: 10927023 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 17CCD14B6 for ; Thu, 2 May 2019 14:48:58 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 071BA285A4 for ; Thu, 2 May 2019 14:48:58 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id EF895285B5; Thu, 2 May 2019 14:48:57 +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 9186E285A4 for ; Thu, 2 May 2019 14:48:57 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726468AbfEBOs4 (ORCPT ); Thu, 2 May 2019 10:48:56 -0400 Received: from mail-qt1-f193.google.com ([209.85.160.193]:41914 "EHLO mail-qt1-f193.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726466AbfEBOs4 (ORCPT ); Thu, 2 May 2019 10:48:56 -0400 Received: by mail-qt1-f193.google.com with SMTP id c13so2759606qtn.8 for ; Thu, 02 May 2019 07:48:55 -0700 (PDT) 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=a2gW/CcdAiDBBt30D2AqoHyC+lsYwURGdt3xL3StYGU=; b=hdr3QiqH2Q5aow6tKa27B4FQ1YPyzKbQHcAEu+53xhnigUJQxYW9HmRI0zXuXgLuJO IF3lR4H30TkYQvYep2DHcAg8YTYs/kJgoHd4+xCKAEJFYWm6m5Uo6U++JGuYhkIFHHwF bxOh9wQ3qQ/1s59ymaaRFqo7Dqyo5zo+2nZh8BH/6jsM+rEVkiFy8dTZ2peXZ12Ls9u4 F/wQxn/LAzyzMpk8OHcK5rwfnDkWaqC+r2AahVRfJwJyJO5HUYB32woAl5peUJPpKQ2P KlclwxghtcU1gro/oDDS6E8LuHTpZ4rFiXRli+iK78KcG6RpSc8qNrTVzf1jZnWMGhqe y2Dg== 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=a2gW/CcdAiDBBt30D2AqoHyC+lsYwURGdt3xL3StYGU=; b=Zoshvp1II4J+n+OxeCFK7ch87RtAdsn4N6N0MEn12CmR8eTbh6/LyxF7qPTFIJnKXF P/H99VhRFDHjLGt++o8QW8C8eTmPVa46CSwAia6D/k4yl9iy+JqknG+HWqCLZ7nbiyS9 YFML90y+nWFrcEszfjO/JFZf6s1urnzCNB9asjesK8AfSjJkIU4UjIEy8wIaNdB0HGjH H/eoLvylI0gJPQQnWPRWHhI8dbvCvMuwnEYX/dKe4qpaWDwetn75y6drobm1lHL6sGsX Zz79AGpxqMZTAIZJnizsBy53A6q361fOVkTRoYfLPgRo5bb5qUHfj8YWvmEQe1RdU6zZ RtpQ== X-Gm-Message-State: APjAAAWdGLHyLdvFo8Ao6u86uzpwD/zvDJ36D9B6X2Wc6RbGGDMK74/o 1HKz9c4/Z1yIe+VIZpxO91qrzt2LGD0= X-Google-Smtp-Source: APXvYqzW0/8X1g9MoM3gxIDbrGYnEUFcecWwBFRw4xbp1NjyBJMqkJcR0NFRshW2BvZ6Eu5kgAyqag== X-Received: by 2002:ac8:548:: with SMTP id c8mr3474096qth.54.1556808534683; Thu, 02 May 2019 07:48:54 -0700 (PDT) Received: from mango.spo.virtua.com.br ([2804:14c:81:942d::1]) by smtp.gmail.com with ESMTPSA id s64sm22002880qkc.39.2019.05.02.07.48.51 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 02 May 2019 07:48:54 -0700 (PDT) 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=?= , =?utf-8?q?SZEDER_G?= =?utf-8?q?=C3=A1bor?= , kernel-usp@googlegroups.com, Junio C Hamano , Michael Haggerty Subject: [GSoC][PATCH v6 04/10] dir-iterator: use warning_errno when possible Date: Thu, 2 May 2019 11:48:23 -0300 Message-Id: <20190502144829.4394-5-matheus.bernardino@usp.br> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190502144829.4394-1-matheus.bernardino@usp.br> References: <20190330224907.3277-1-matheus.bernardino@usp.br> <20190502144829.4394-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 Change warning(..., strerror(errno)) by warning_errno(...). This helps to unify warning display besides simplifying a bit the code. Also, improve warning messages by surrounding paths with quotation marks and using more meaningful statements. Signed-off-by: Matheus Tavares --- dir-iterator.c | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/dir-iterator.c b/dir-iterator.c index f2dcd82fde..0c8880868a 100644 --- a/dir-iterator.c +++ b/dir-iterator.c @@ -71,8 +71,8 @@ int dir_iterator_advance(struct dir_iterator *dir_iterator) level->dir = opendir(iter->base.path.buf); if (!level->dir && errno != ENOENT) { - warning("error opening directory %s: %s", - iter->base.path.buf, strerror(errno)); + warning_errno("error opening directory '%s'", + iter->base.path.buf); /* Popping the level is handled below */ } @@ -122,11 +122,11 @@ int dir_iterator_advance(struct dir_iterator *dir_iterator) if (!de) { /* This level is exhausted; pop up a level. */ if (errno) { - warning("error reading directory %s: %s", - iter->base.path.buf, strerror(errno)); + warning_errno("error reading directory '%s'", + iter->base.path.buf); } else if (closedir(level->dir)) - warning("error closing directory %s: %s", - iter->base.path.buf, strerror(errno)); + warning_errno("error closing directory '%s'", + iter->base.path.buf); level->dir = NULL; if (--iter->levels_nr == 0) @@ -140,9 +140,8 @@ int dir_iterator_advance(struct dir_iterator *dir_iterator) strbuf_addstr(&iter->base.path, de->d_name); if (lstat(iter->base.path.buf, &iter->base.st) < 0) { if (errno != ENOENT) - warning("error reading path '%s': %s", - iter->base.path.buf, - strerror(errno)); + warning_errno("failed to stat '%s'", + iter->base.path.buf); continue; } @@ -170,9 +169,11 @@ int dir_iterator_abort(struct dir_iterator *dir_iterator) &iter->levels[iter->levels_nr - 1]; if (level->dir && closedir(level->dir)) { + int saved_errno = errno; strbuf_setlen(&iter->base.path, level->prefix_len); - warning("error closing directory %s: %s", - iter->base.path.buf, strerror(errno)); + errno = saved_errno; + warning_errno("error closing directory '%s'", + iter->base.path.buf); } } From patchwork Thu May 2 14:48:24 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matheus Tavares X-Patchwork-Id: 10927025 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 58E1514B6 for ; Thu, 2 May 2019 14:49:03 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 455AC285B5 for ; Thu, 2 May 2019 14:49:03 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 392F8285C3; Thu, 2 May 2019 14:49:03 +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 27284285B5 for ; Thu, 2 May 2019 14:49:02 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726466AbfEBOtB (ORCPT ); Thu, 2 May 2019 10:49:01 -0400 Received: from mail-qt1-f194.google.com ([209.85.160.194]:36715 "EHLO mail-qt1-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726300AbfEBOtA (ORCPT ); Thu, 2 May 2019 10:49:00 -0400 Received: by mail-qt1-f194.google.com with SMTP id c35so2792840qtk.3 for ; Thu, 02 May 2019 07:48:59 -0700 (PDT) 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=DpsXK9quOF4ZsKBx5tiDWvZVbiJ9VkN26LrMxXJAXqk=; b=dbSc92WUhsFjjYtLkRfS1oB486l4lvk6qU+TEmMco0G0fK/h2dQb9jt7/AASxjRQbU lyF5l2qU9Y48/qB78Vs6AvX6vAklw+khBpnEyozAUoh57Xn45cDJ75KtBNIYURLkwpe5 mU1aNv/xerplA4Lzm0v/9w1tdM+NJpIXu9U3lyQdJVIm2ZDQVKD7Nx+FI6ImRbDPEe6p vP6Ad+8I4duKaVJTfSu5cWacGlL2z58zizAFrp197DoIx/vw32Pn/JaaDV9z3UQbgNsm pBKUUMfGZXeO1HWjx9JLAiv+War6l0lFb0wDs3t8ANsVw02Xi9aK5W3JQrYoSHY7qHHm f+cA== 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=DpsXK9quOF4ZsKBx5tiDWvZVbiJ9VkN26LrMxXJAXqk=; b=d7j+VqD+hgeqqNgfW9iegmQkakl+NteDvEIEVPFCrvXL2L7en5xOGXCvnvl5o1bIt5 isl0degv/4NVvOLZ3Cs/qoOrSv2Gx8NfYAoEkHmSUc0bvNJLoEDrdQBlCUQ/f1b3acGe 3D5ceuaBbwbrkAvHi5ShghbTGHtFkDGzQmtZ32BeXrvlPaxOlS4oUrqykONAZNjKS3h7 IbB2BnQEb1mgB2y0W3MtROinRuHCakRef+Yhh8ktZ0gU/OWUYzUxiqcJWpvHLtzMZ/ty dOUal9J/1pidOugNS6hHmIMR73BM1hgl9NUPyDo62+lhaNBGr+2IfIFoOqhiDx4nKL3p YH0g== X-Gm-Message-State: APjAAAWtLr1bFLyuE2OnQ6/Fa2dCHi1go2N6TqqC5e6o5PXC9CNSom6L T8xa62X9C5C0Nj9gxxc/juWjyk618rI= X-Google-Smtp-Source: APXvYqzSkgoeLFpcyA2DCGCCkqW7l00/ZkXCSALUv7telamB+ZkFoj14jnE/1U2C49O+mJ1/dGlPuA== X-Received: by 2002:a0c:a944:: with SMTP id z4mr3356933qva.119.1556808539066; Thu, 02 May 2019 07:48:59 -0700 (PDT) Received: from mango.spo.virtua.com.br ([2804:14c:81:942d::1]) by smtp.gmail.com with ESMTPSA id s64sm22002880qkc.39.2019.05.02.07.48.55 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 02 May 2019 07:48:58 -0700 (PDT) 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=?= , =?utf-8?q?SZEDER_G?= =?utf-8?q?=C3=A1bor?= , kernel-usp@googlegroups.com, Daniel Ferreira , Michael Haggerty , Ramsay Jones , Junio C Hamano , Jeff King , Johannes Schindelin Subject: [GSoC][PATCH v6 05/10] dir-iterator: refactor state machine model Date: Thu, 2 May 2019 11:48:24 -0300 Message-Id: <20190502144829.4394-6-matheus.bernardino@usp.br> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190502144829.4394-1-matheus.bernardino@usp.br> References: <20190330224907.3277-1-matheus.bernardino@usp.br> <20190502144829.4394-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 dir_iterator_advance() is a large function with two nested loops. Let's improve its readability factoring out three functions and simplifying its mechanics. The refactored model will no longer depend on level.initialized and level.dir_state to keep track of the iteration state and will perform on a single loop. Also, dir_iterator_begin() currently does not check if the given string represents a valid directory path. Since the refactored model will have to stat() the given path at initialization, let's also check for this kind of error and make dir_iterator_begin() return NULL, on failures, with errno appropriately set. And add tests for this new behavior. Improve documentation at dir-iteration.h and code comments at dir-iterator.c to reflect the changes and eliminate possible ambiguities. Finally, adjust refs/files-backend.c to check for now possible dir_iterator_begin() failures. Original-patch-by: Daniel Ferreira Signed-off-by: Matheus Tavares --- When dir_iterator_begin() fails at refs/files-backend.c, I used the same idea Daniel proposed, which is to initialize an empty iterator with empty_ref_iterator_begin(). Still, I'm not sure wether we shouldn't abort execution there instead of returning an empty iterator. dir_iterator_begin() will fail if the give argument is an empty string, NULL, an invalid path, a non directory path or on some other stat() errors. Maybe, on these kind of errors, we don't want the users of refs/files-backend.c, and therefore should call die() right there? (Also, NULL and empty string arguments were considered a bug in the previous version of dir_iterator_begin) dir-iterator.c | 234 ++++++++++++++++++----------------- dir-iterator.h | 15 ++- refs/files-backend.c | 17 ++- t/helper/test-dir-iterator.c | 5 + t/t0066-dir-iterator.sh | 13 ++ 5 files changed, 163 insertions(+), 121 deletions(-) diff --git a/dir-iterator.c b/dir-iterator.c index 0c8880868a..594fe4d67b 100644 --- a/dir-iterator.c +++ b/dir-iterator.c @@ -4,8 +4,6 @@ #include "dir-iterator.h" struct dir_iterator_level { - int initialized; - DIR *dir; /* @@ -13,16 +11,6 @@ struct dir_iterator_level { * (including a trailing '/'): */ size_t prefix_len; - - /* - * The last action that has been taken with the current entry - * (needed for directories, which have to be included in the - * iteration and also iterated into): - */ - enum { - DIR_STATE_ITER, - DIR_STATE_RECURSE - } dir_state; }; /* @@ -34,9 +22,11 @@ struct dir_iterator_int { struct dir_iterator base; /* - * The number of levels currently on the stack. This is always - * at least 1, because when it becomes zero the iteration is - * ended and this struct is freed. + * The number of levels currently on the stack. After the first + * call to dir_iterator_begin(), if it succeeds to open the + * first level's dir, this will always be at least 1. Then, + * when it comes to zero the iteration is ended and this + * struct is freed. */ size_t levels_nr; @@ -50,113 +40,118 @@ struct dir_iterator_int { struct dir_iterator_level *levels; }; +/* + * Push a level in the iter stack and initialize it with information from + * the directory pointed by iter->base->path. It is assumed that this + * strbuf points to a valid directory path. Return 0 on success and -1 + * otherwise, leaving the stack unchanged. + */ +static int push_level(struct dir_iterator_int *iter) +{ + struct dir_iterator_level *level; + + ALLOC_GROW(iter->levels, iter->levels_nr + 1, iter->levels_alloc); + level = &iter->levels[iter->levels_nr++]; + + if (!is_dir_sep(iter->base.path.buf[iter->base.path.len - 1])) + strbuf_addch(&iter->base.path, '/'); + level->prefix_len = iter->base.path.len; + + level->dir = opendir(iter->base.path.buf); + if (!level->dir) { + if (errno != ENOENT) { + warning_errno("error opening directory '%s'", + iter->base.path.buf); + } + iter->levels_nr--; + return -1; + } + + return 0; +} + +/* + * Pop the top level on the iter stack, releasing any resources associated + * with it. Return the new value of iter->levels_nr. + */ +static int pop_level(struct dir_iterator_int *iter) +{ + struct dir_iterator_level *level = + &iter->levels[iter->levels_nr - 1]; + + if (level->dir && closedir(level->dir)) + warning_errno("error closing directory '%s'", + iter->base.path.buf); + level->dir = NULL; + + return --iter->levels_nr; +} + +/* + * Populate iter->base with the necessary information on the next iteration + * entry, represented by the given dirent de. Return 0 on success and -1 + * otherwise. + */ +static int prepare_next_entry_data(struct dir_iterator_int *iter, + struct dirent *de) +{ + strbuf_addstr(&iter->base.path, de->d_name); + /* + * We have to reset these because the path strbuf might have + * been realloc()ed at the previous strbuf_addstr(). + */ + iter->base.relative_path = iter->base.path.buf + + iter->levels[0].prefix_len; + iter->base.basename = iter->base.path.buf + + iter->levels[iter->levels_nr - 1].prefix_len; + + if (lstat(iter->base.path.buf, &iter->base.st)) { + if (errno != ENOENT) + warning_errno("failed to stat '%s'", iter->base.path.buf); + return -1; + } + + return 0; +} + int dir_iterator_advance(struct dir_iterator *dir_iterator) { struct dir_iterator_int *iter = (struct dir_iterator_int *)dir_iterator; + if (S_ISDIR(iter->base.st.st_mode)) { + if (push_level(iter) && iter->levels_nr == 0) { + /* Pushing the first level failed */ + return dir_iterator_abort(dir_iterator); + } + } + + /* Loop until we find an entry that we can give back to the caller. */ while (1) { + struct dirent *de; struct dir_iterator_level *level = &iter->levels[iter->levels_nr - 1]; - struct dirent *de; - if (!level->initialized) { - /* - * Note: dir_iterator_begin() ensures that - * path is not the empty string. - */ - if (!is_dir_sep(iter->base.path.buf[iter->base.path.len - 1])) - strbuf_addch(&iter->base.path, '/'); - level->prefix_len = iter->base.path.len; - - level->dir = opendir(iter->base.path.buf); - if (!level->dir && errno != ENOENT) { - warning_errno("error opening directory '%s'", + strbuf_setlen(&iter->base.path, level->prefix_len); + errno = 0; + de = readdir(level->dir); + + if (!de) { + if (errno) + warning_errno("error reading directory '%s'", iter->base.path.buf); - /* Popping the level is handled below */ - } - - level->initialized = 1; - } else if (S_ISDIR(iter->base.st.st_mode)) { - if (level->dir_state == DIR_STATE_ITER) { - /* - * The directory was just iterated - * over; now prepare to iterate into - * it. - */ - level->dir_state = DIR_STATE_RECURSE; - ALLOC_GROW(iter->levels, iter->levels_nr + 1, - iter->levels_alloc); - level = &iter->levels[iter->levels_nr++]; - level->initialized = 0; - continue; - } else { - /* - * The directory has already been - * iterated over and iterated into; - * we're done with it. - */ - } + else if (pop_level(iter) == 0) + return dir_iterator_abort(dir_iterator); + continue; } - if (!level->dir) { - /* - * This level is exhausted (or wasn't opened - * successfully); pop up a level. - */ - if (--iter->levels_nr == 0) - return dir_iterator_abort(dir_iterator); + if (is_dot_or_dotdot(de->d_name)) + continue; + if (prepare_next_entry_data(iter, de)) continue; - } - /* - * Loop until we find an entry that we can give back - * to the caller: - */ - while (1) { - strbuf_setlen(&iter->base.path, level->prefix_len); - errno = 0; - de = readdir(level->dir); - - if (!de) { - /* This level is exhausted; pop up a level. */ - if (errno) { - warning_errno("error reading directory '%s'", - iter->base.path.buf); - } else if (closedir(level->dir)) - warning_errno("error closing directory '%s'", - iter->base.path.buf); - - level->dir = NULL; - if (--iter->levels_nr == 0) - return dir_iterator_abort(dir_iterator); - break; - } - - if (is_dot_or_dotdot(de->d_name)) - continue; - - strbuf_addstr(&iter->base.path, de->d_name); - if (lstat(iter->base.path.buf, &iter->base.st) < 0) { - if (errno != ENOENT) - warning_errno("failed to stat '%s'", - iter->base.path.buf); - continue; - } - - /* - * We have to set these each time because - * the path strbuf might have been realloc()ed. - */ - iter->base.relative_path = - iter->base.path.buf + iter->levels[0].prefix_len; - iter->base.basename = - iter->base.path.buf + level->prefix_len; - level->dir_state = DIR_STATE_ITER; - - return ITER_OK; - } + return ITER_OK; } } @@ -187,17 +182,32 @@ struct dir_iterator *dir_iterator_begin(const char *path) { struct dir_iterator_int *iter = xcalloc(1, sizeof(*iter)); struct dir_iterator *dir_iterator = &iter->base; - - if (!path || !*path) - BUG("empty path passed to dir_iterator_begin()"); + int saved_errno; strbuf_init(&iter->base.path, PATH_MAX); strbuf_addstr(&iter->base.path, path); ALLOC_GROW(iter->levels, 10, iter->levels_alloc); + iter->levels_nr = 0; - iter->levels_nr = 1; - iter->levels[0].initialized = 0; + /* + * Note: stat already checks for NULL or empty strings and + * inexistent paths. + */ + if (stat(iter->base.path.buf, &iter->base.st) < 0) { + saved_errno = errno; + goto error_out; + } + + if (!S_ISDIR(iter->base.st.st_mode)) { + saved_errno = ENOTDIR; + goto error_out; + } return dir_iterator; + +error_out: + dir_iterator_abort(dir_iterator); + errno = saved_errno; + return NULL; } diff --git a/dir-iterator.h b/dir-iterator.h index 970793d07a..0822821e56 100644 --- a/dir-iterator.h +++ b/dir-iterator.h @@ -8,19 +8,23 @@ * * 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. + * symlinks except for the original path. Note that the original path + * is not included in the iteration. * * Every time dir_iterator_advance() is called, update the members of * the dir_iterator structure to reflect the next path in the * iteration. The order that paths are iterated over within a - * directory is undefined, but directory paths are always iterated - * over before the subdirectory contents. + * directory is undefined, directory paths are always given before + * their contents. * * A typical iteration looks like this: * * int ok; * struct iterator *iter = dir_iterator_begin(path); * + * if (!iter) + * goto error_handler; + * * while ((ok = dir_iterator_advance(iter)) == ITER_OK) { * if (want_to_stop_iteration()) { * ok = dir_iterator_abort(iter); @@ -59,8 +63,9 @@ 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. On success, return a + * dir_iterator that holds the internal state of the iteration. + * In case of failure, return NULL and set errno accordingly. * * The iteration includes all paths under path, not including path * itself and not including "." or ".." entries. diff --git a/refs/files-backend.c b/refs/files-backend.c index 63e55e6773..97a54532e3 100644 --- a/refs/files-backend.c +++ b/refs/files-backend.c @@ -2143,13 +2143,22 @@ static struct ref_iterator_vtable files_reflog_iterator_vtable = { static struct ref_iterator *reflog_iterator_begin(struct ref_store *ref_store, const char *gitdir) { - struct files_reflog_iterator *iter = xcalloc(1, sizeof(*iter)); - struct ref_iterator *ref_iterator = &iter->base; + struct dir_iterator *diter; + struct files_reflog_iterator *iter; + struct ref_iterator *ref_iterator; struct strbuf sb = STRBUF_INIT; - 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); + + diter = dir_iterator_begin(sb.buf); + if (!diter) + return empty_ref_iterator_begin(); + + iter = xcalloc(1, sizeof(*iter)); + ref_iterator = &iter->base; + + base_ref_iterator_init(ref_iterator, &files_reflog_iterator_vtable, 0); + iter->dir_iterator = diter; iter->ref_store = ref_store; strbuf_release(&sb); diff --git a/t/helper/test-dir-iterator.c b/t/helper/test-dir-iterator.c index 84f50bed8c..fab1ff6237 100644 --- a/t/helper/test-dir-iterator.c +++ b/t/helper/test-dir-iterator.c @@ -17,6 +17,11 @@ int cmd__dir_iterator(int argc, const char **argv) diter = dir_iterator_begin(path.buf); + if (!diter) { + printf("dir_iterator_begin failure: %d\n", errno); + exit(EXIT_FAILURE); + } + while (dir_iterator_advance(diter) == ITER_OK) { if (S_ISDIR(diter->st.st_mode)) printf("[d] "); diff --git a/t/t0066-dir-iterator.sh b/t/t0066-dir-iterator.sh index 6e06dc038d..c739ed7911 100755 --- a/t/t0066-dir-iterator.sh +++ b/t/t0066-dir-iterator.sh @@ -52,4 +52,17 @@ test_expect_success 'dir-iterator should list files in the correct order' ' test_cmp expected-pre-order-output actual-pre-order-output ' +test_expect_success 'begin should fail upon inexistent paths' ' + test_must_fail test-tool dir-iterator ./inexistent-path \ + >actual-inexistent-path-output && + echo "dir_iterator_begin failure: 2" >expected-inexistent-path-output && + test_cmp expected-inexistent-path-output actual-inexistent-path-output +' + +test_expect_success 'begin should fail upon non directory paths' ' + test_must_fail test-tool dir-iterator ./dir/b >actual-non-dir-output && + echo "dir_iterator_begin failure: 20" >expected-non-dir-output && + test_cmp expected-non-dir-output actual-non-dir-output +' + test_done From patchwork Thu May 2 14:48:25 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matheus Tavares X-Patchwork-Id: 10927027 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 97DA91398 for ; Thu, 2 May 2019 14:49:08 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 84300285A4 for ; Thu, 2 May 2019 14:49:08 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 782AE285B7; Thu, 2 May 2019 14:49:08 +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 554D0285A4 for ; Thu, 2 May 2019 14:49:07 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726470AbfEBOtG (ORCPT ); Thu, 2 May 2019 10:49:06 -0400 Received: from mail-qt1-f194.google.com ([209.85.160.194]:36735 "EHLO mail-qt1-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726300AbfEBOtG (ORCPT ); Thu, 2 May 2019 10:49:06 -0400 Received: by mail-qt1-f194.google.com with SMTP id c35so2793236qtk.3 for ; Thu, 02 May 2019 07:49:05 -0700 (PDT) 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=Nt25lzGVUOpQiwKaoxjJXVCU/V1p0ovgoj8zT/QQmlU=; b=xGJhH1XxXOHRgNAGxKqa9+vmUgF1x34Z36we02sbGEoVQM3ngKC2Drvp9l3Ykv01tv rmekUH/S6DqVtpiSKNLYLWtNu3QvMlYgtXvT9VESzINsQKvTSYfmchy+qv0mROe7YdC0 4XBG6hkGX5BLSZZ51Qh4Nvtpxl/9W8eslVbC7tCTQA0Jz+BHOxcAF9Ovszv2c+9lyMNi NbIqCMwkwSefhSPWDJV0rnHB18aUsYH2hFrAQpdKdVotQ7xA6xiwcJ1BjDcpdT5pTxs+ ENN1gTGrFsc9jeBBHZd+ARQbdJsj03xeScvrNWaskHloSxiEfGdpA9nyr3rCSUVSHMWT m8YQ== 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=Nt25lzGVUOpQiwKaoxjJXVCU/V1p0ovgoj8zT/QQmlU=; b=Xr7xi3ahEafdbA4ruGeygKB47mvfWwYLLYgFgY5nNq4dm/nQctNfzsFvYwZXOaLo40 MjSiHrB7G7CUxue41ARA+bzUmcNCgLnrxzV3aBNXnrZmZpWzC1tXC0RYYmA1a90lnkfv 7Vr5yrC4CKMtWt6oWA0sBWAMldkiO2mWEe6Fox8d/ol8GSvX3gWA8nOQyPizyXQDjKGV TAYPYbac5lTGeDAwo2bl8jtBcmXemPdqymA72Av1b6ep2ZieRK3IcdxC+1DpR7avTWHd CSzO9fg6WW3IsGDndhqaaas5OeohwGcCci7C1zTIZ09ggLlPIfuezeZkuE3jfYjLnaZ9 gOSw== X-Gm-Message-State: APjAAAXPuv+WpsQDvpiFxCXDV7Elq11m3pUWj46g0jD+tI/0AfdbFLzW I4pO/TigzJ2CXxe5hU0z0JGoA1/obXE= X-Google-Smtp-Source: APXvYqwXq5AGVJIOrh/gRI+l+yg9HeLdxzNi2EUMpMHM62ilQ/vWrm04Bq+cRxblkMzxyQoxJbyJAQ== X-Received: by 2002:aed:37e7:: with SMTP id j94mr3391437qtb.381.1556808543016; Thu, 02 May 2019 07:49:03 -0700 (PDT) Received: from mango.spo.virtua.com.br ([2804:14c:81:942d::1]) by smtp.gmail.com with ESMTPSA id s64sm22002880qkc.39.2019.05.02.07.48.59 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 02 May 2019 07:49:02 -0700 (PDT) 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=?= , =?utf-8?q?SZEDER_G?= =?utf-8?q?=C3=A1bor?= , kernel-usp@googlegroups.com, Michael Haggerty , Daniel Ferreira , Ramsay Jones , Junio C Hamano Subject: [GSoC][PATCH v6 06/10] dir-iterator: add flags parameter to dir_iterator_begin Date: Thu, 2 May 2019 11:48:25 -0300 Message-Id: <20190502144829.4394-7-matheus.bernardino@usp.br> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190502144829.4394-1-matheus.bernardino@usp.br> References: <20190330224907.3277-1-matheus.bernardino@usp.br> <20190502144829.4394-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 immediately in the case of an error, instead of keep looking for the next valid entry; - DIR_ITERATOR_FOLLOW_SYMLINKS, which makes the iterator follow symlinks and include linked directories' contents in the iteration. These new flags will be used in a subsequent patch. Also add tests for the flags' usage and adjust refs/files-backend.c to the new dir_iterator_begin signature. Signed-off-by: Matheus Tavares --- refs/files_backend.c is currently using no flags at the place it calls dir_iterator_begin(), to keep the same behavior it previously had. But as ITER_ERROR will now only be possibly returned by dir_iterator_avance() when DIR_ITERATOR_PEDANTIC is used and as refs/files_backend.c already checks for ITER_ERRORs, should we, perhaps, use this flag when initializing an iterator here? Another uncertainty I had is why we ignore ENOENT at dir-iterator. Is it so that files may be remove during iteration? If not, maybe we should consider to start looking for them, as, for example, broken symlinks will simply be ignored in this current version as an ENOENT will be returned when trying to dereference them. dir-iterator.c | 82 +++++++++++++++++++++++++------ dir-iterator.h | 50 ++++++++++++++----- refs/files-backend.c | 2 +- t/helper/test-dir-iterator.c | 34 ++++++++++--- t/t0066-dir-iterator.sh | 95 ++++++++++++++++++++++++++++++++++++ 5 files changed, 228 insertions(+), 35 deletions(-) diff --git a/dir-iterator.c b/dir-iterator.c index 594fe4d67b..52db87bdc9 100644 --- a/dir-iterator.c +++ b/dir-iterator.c @@ -6,6 +6,9 @@ struct dir_iterator_level { DIR *dir; + /* The inode number of this level's directory. */ + ino_t ino; + /* * The length of the directory part of path at this level * (including a trailing '/'): @@ -38,13 +41,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 int flags; }; /* * Push a level in the iter stack and initialize it with information from * the directory pointed by iter->base->path. It is assumed that this * strbuf points to a valid directory path. Return 0 on success and -1 - * otherwise, leaving the stack unchanged. + * otherwise, setting errno accordingly and leaving the stack unchanged. */ static int push_level(struct dir_iterator_int *iter) { @@ -56,14 +62,17 @@ static int push_level(struct dir_iterator_int *iter) if (!is_dir_sep(iter->base.path.buf[iter->base.path.len - 1])) strbuf_addch(&iter->base.path, '/'); level->prefix_len = iter->base.path.len; + level->ino = iter->base.st.st_ino; level->dir = opendir(iter->base.path.buf); if (!level->dir) { + int saved_errno = errno; if (errno != ENOENT) { warning_errno("error opening directory '%s'", iter->base.path.buf); } iter->levels_nr--; + errno = saved_errno; return -1; } @@ -90,11 +99,13 @@ static int pop_level(struct dir_iterator_int *iter) /* * Populate iter->base with the necessary information on the next iteration * entry, represented by the given dirent de. Return 0 on success and -1 - * otherwise. + * otherwise, setting errno accordingly. */ static int prepare_next_entry_data(struct dir_iterator_int *iter, struct dirent *de) { + int err, saved_errno; + strbuf_addstr(&iter->base.path, de->d_name); /* * We have to reset these because the path strbuf might have @@ -105,12 +116,34 @@ static int prepare_next_entry_data(struct dir_iterator_int *iter, iter->base.basename = iter->base.path.buf + iter->levels[iter->levels_nr - 1].prefix_len; - if (lstat(iter->base.path.buf, &iter->base.st)) { - if (errno != ENOENT) - warning_errno("failed to stat '%s'", iter->base.path.buf); - return -1; - } + if (iter->flags & DIR_ITERATOR_FOLLOW_SYMLINKS) + err = stat(iter->base.path.buf, &iter->base.st); + else + err = lstat(iter->base.path.buf, &iter->base.st); + + saved_errno = errno; + if (err && errno != ENOENT) + warning_errno("failed to stat '%s'", iter->base.path.buf); + + errno = saved_errno; + return err; +} + +/* + * Look for a recursive symlink at iter->base.path pointing to any directory on + * the previous stack levels. If it is found, return 1. If not, return 0. + */ +static int find_recursive_symlinks(struct dir_iterator_int *iter) +{ + int i; + + if (!(iter->flags & DIR_ITERATOR_FOLLOW_SYMLINKS) || + !S_ISDIR(iter->base.st.st_mode)) + return 0; + for (i = 0; i < iter->levels_nr; ++i) + if (iter->base.st.st_ino == iter->levels[i].ino) + return 1; return 0; } @@ -119,11 +152,11 @@ int dir_iterator_advance(struct dir_iterator *dir_iterator) struct dir_iterator_int *iter = (struct dir_iterator_int *)dir_iterator; - if (S_ISDIR(iter->base.st.st_mode)) { - if (push_level(iter) && iter->levels_nr == 0) { - /* Pushing the first level failed */ - return dir_iterator_abort(dir_iterator); - } + if (S_ISDIR(iter->base.st.st_mode) && push_level(iter)) { + if (errno != ENOENT && iter->flags & DIR_ITERATOR_PEDANTIC) + goto error_out; + if (iter->levels_nr == 0) + goto error_out; } /* Loop until we find an entry that we can give back to the caller. */ @@ -137,22 +170,38 @@ int dir_iterator_advance(struct dir_iterator *dir_iterator) de = readdir(level->dir); if (!de) { - if (errno) + if (errno) { warning_errno("error reading directory '%s'", iter->base.path.buf); - else if (pop_level(iter) == 0) + if (iter->flags & DIR_ITERATOR_PEDANTIC) + goto error_out; + } else if (pop_level(iter) == 0) { return dir_iterator_abort(dir_iterator); + } continue; } if (is_dot_or_dotdot(de->d_name)) continue; - if (prepare_next_entry_data(iter, de)) + if (prepare_next_entry_data(iter, de)) { + if (errno != ENOENT && iter->flags & DIR_ITERATOR_PEDANTIC) + goto error_out; continue; + } + + if (find_recursive_symlinks(iter)) { + warning("ignoring recursive symlink at '%s'", + iter->base.path.buf); + continue; + } return ITER_OK; } + +error_out: + dir_iterator_abort(dir_iterator); + return ITER_ERROR; } int dir_iterator_abort(struct dir_iterator *dir_iterator) @@ -178,7 +227,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 int flags) { struct dir_iterator_int *iter = xcalloc(1, sizeof(*iter)); struct dir_iterator *dir_iterator = &iter->base; @@ -189,6 +238,7 @@ struct dir_iterator *dir_iterator_begin(const char *path) ALLOC_GROW(iter->levels, 10, iter->levels_alloc); iter->levels_nr = 0; + iter->flags = flags; /* * Note: stat already checks for NULL or empty strings and diff --git a/dir-iterator.h b/dir-iterator.h index 0822821e56..28e50dabdb 100644 --- a/dir-iterator.h +++ b/dir-iterator.h @@ -20,7 +20,8 @@ * A typical iteration looks like this: * * int ok; - * struct iterator *iter = dir_iterator_begin(path); + * unsigned int flags = DIR_ITERATOR_PEDANTIC; + * struct iterator *iter = dir_iterator_begin(path, flags); * * if (!iter) * goto error_handler; @@ -44,6 +45,24 @@ * dir_iterator_advance() again. */ +/* + * Flags for dir_iterator_begin: + * + * - DIR_ITERATOR_PEDANTIC: override dir-iterator's default behavior + * in case of an error at dir_iterator_advance(), which is to keep + * looking for a next valid entry. With this flag, resources are freed + * and ITER_ERROR is returned immediately. In both cases, a meaningful + * warning is emitted. + * + * - DIR_ITERATOR_FOLLOW_SYMLINKS: make dir-iterator follow symlinks. + * i.e., linked directories' contents will be iterated over and + * iter->base.st will contain information on the referred files, + * not the symlinks themselves, which is the default behavior. + * Recursive symlinks are skipped. + */ +#define DIR_ITERATOR_PEDANTIC (1 << 0) +#define DIR_ITERATOR_FOLLOW_SYMLINKS (1 << 1) + struct dir_iterator { /* The current path: */ struct strbuf path; @@ -58,29 +77,38 @@ struct dir_iterator { /* The current basename: */ const char *basename; - /* The result of calling lstat() on path: */ + /* + * The result of calling lstat() on path; or stat(), if the + * DIR_ITERATOR_FOLLOW_SYMLINKS flag was set at + * dir_iterator's initialization. + */ struct stat st; }; /* - * Start a directory iteration over path. On success, return a - * dir_iterator that holds the internal state of the iteration. - * In case of failure, return NULL and set errno accordingly. + * Start a directory iteration over path with the combination of + * options specified by flags. On success, return a dir_iterator + * that holds the internal state of the iteration. In case of + * failure, return NULL and set errno accordingly. * * 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 behavior. */ -struct dir_iterator *dir_iterator_begin(const char *path); +struct dir_iterator *dir_iterator_begin(const char *path, unsigned int flags); /* * Advance the iterator to the first or next item and return ITER_OK. * If the iteration is exhausted, free the dir_iterator and any - * resources associated with it and return ITER_DONE. On error, free - * 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. + * resources associated with it and return ITER_DONE. + * + * It is a bug to use iterator or call this function again after it + * has returned ITER_DONE or ITER_ERROR (which may be returned iff + * the DIR_ITERATOR_PEDANTIC flag was set). */ int dir_iterator_advance(struct dir_iterator *iterator); diff --git a/refs/files-backend.c b/refs/files-backend.c index 97a54532e3..ce78656823 100644 --- a/refs/files-backend.c +++ b/refs/files-backend.c @@ -2150,7 +2150,7 @@ static struct ref_iterator *reflog_iterator_begin(struct ref_store *ref_store, strbuf_addf(&sb, "%s/logs", gitdir); - diter = dir_iterator_begin(sb.buf); + diter = dir_iterator_begin(sb.buf, 0); if (!diter) return empty_ref_iterator_begin(); diff --git a/t/helper/test-dir-iterator.c b/t/helper/test-dir-iterator.c index fab1ff6237..a5b96cb0dc 100644 --- a/t/helper/test-dir-iterator.c +++ b/t/helper/test-dir-iterator.c @@ -4,29 +4,44 @@ #include "iterator.h" #include "dir-iterator.h" -/* Argument is a directory path to iterate over */ +/* + * usage: + * tool-test dir-iterator [--follow-symlinks] [--pedantic] directory_path + */ int cmd__dir_iterator(int argc, const char **argv) { struct strbuf path = STRBUF_INIT; struct dir_iterator *diter; + unsigned int flags = 0; + int iter_status; + + for (++argv, --argc; *argv && starts_with(*argv, "--"); ++argv, --argc) { + if (strcmp(*argv, "--follow-symlinks") == 0) + flags |= DIR_ITERATOR_FOLLOW_SYMLINKS; + else if (strcmp(*argv, "--pedantic") == 0) + flags |= DIR_ITERATOR_PEDANTIC; + else + die("invalid option '%s'", *argv); + } - if (argc < 2) - die("BUG: test-dir-iterator needs one argument"); - - strbuf_add(&path, argv[1], strlen(argv[1])); + if (!*argv || argc != 1) + die("dir-iterator needs exactly one non-option argument"); - diter = dir_iterator_begin(path.buf); + strbuf_add(&path, *argv, strlen(*argv)); + diter = dir_iterator_begin(path.buf, flags); if (!diter) { printf("dir_iterator_begin failure: %d\n", errno); exit(EXIT_FAILURE); } - while (dir_iterator_advance(diter) == ITER_OK) { + while ((iter_status = dir_iterator_advance(diter)) == ITER_OK) { if (S_ISDIR(diter->st.st_mode)) printf("[d] "); else if (S_ISREG(diter->st.st_mode)) printf("[f] "); + else if (S_ISLNK(diter->st.st_mode)) + printf("[s] "); else printf("[?] "); @@ -34,5 +49,10 @@ int cmd__dir_iterator(int argc, const char **argv) diter->path.buf); } + if (iter_status != ITER_DONE) { + printf("dir_iterator_advance failure\n"); + return 1; + } + return 0; } diff --git a/t/t0066-dir-iterator.sh b/t/t0066-dir-iterator.sh index c739ed7911..8f996a31fa 100755 --- a/t/t0066-dir-iterator.sh +++ b/t/t0066-dir-iterator.sh @@ -65,4 +65,99 @@ test_expect_success 'begin should fail upon non directory paths' ' test_cmp expected-non-dir-output actual-non-dir-output ' +test_expect_success POSIXPERM,SANITY 'advance should not fail on errors by default' ' + cat >expected-no-permissions-output <<-EOF && + [d] (a) [a] ./dir3/a + EOF + + mkdir -p dir3/a && + > dir3/a/b && + chmod 0 dir3/a && + + test-tool dir-iterator ./dir3 >actual-no-permissions-output && + test_cmp expected-no-permissions-output actual-no-permissions-output && + chmod 755 dir3/a && + rm -rf dir3 +' + +test_expect_success POSIXPERM,SANITY 'advance should fail on errors, w/ pedantic flag' ' + cat >expected-no-permissions-pedantic-output <<-EOF && + [d] (a) [a] ./dir3/a + dir_iterator_advance failure + EOF + + mkdir -p dir3/a && + > dir3/a/b && + chmod 0 dir3/a && + + test_must_fail test-tool dir-iterator --pedantic ./dir3 \ + >actual-no-permissions-pedantic-output && + test_cmp expected-no-permissions-pedantic-output \ + actual-no-permissions-pedantic-output && + chmod 755 dir3/a && + rm -rf dir3 +' + +test_expect_success SYMLINKS 'setup dirs with symlinks' ' + mkdir -p dir4/a && + mkdir -p dir4/b/c && + >dir4/a/d && + ln -s d dir4/a/e && + ln -s ../b dir4/a/f && + + mkdir -p dir5/a/b && + mkdir -p dir5/a/c && + ln -s ../c dir5/a/b/d && + ln -s ../ dir5/a/b/e && + ln -s ../../ dir5/a/b/f +' + +test_expect_success SYMLINKS 'dir-iterator should not follow symlinks by default' ' + cat >expected-no-follow-sorted-output <<-EOF && + [d] (a) [a] ./dir4/a + [d] (b) [b] ./dir4/b + [d] (b/c) [c] ./dir4/b/c + [f] (a/d) [d] ./dir4/a/d + [s] (a/e) [e] ./dir4/a/e + [s] (a/f) [f] ./dir4/a/f + EOF + + test-tool dir-iterator ./dir4 >out && + sort actual-no-follow-sorted-output && + + test_cmp expected-no-follow-sorted-output actual-no-follow-sorted-output +' + +test_expect_success SYMLINKS 'dir-iterator should follow symlinks w/ follow flag' ' + cat >expected-follow-sorted-output <<-EOF && + [d] (a) [a] ./dir4/a + [d] (a/f) [f] ./dir4/a/f + [d] (a/f/c) [c] ./dir4/a/f/c + [d] (b) [b] ./dir4/b + [d] (b/c) [c] ./dir4/b/c + [f] (a/d) [d] ./dir4/a/d + [f] (a/e) [e] ./dir4/a/e + EOF + + test-tool dir-iterator --follow-symlinks ./dir4 >out && + sort actual-follow-sorted-output && + + test_cmp expected-follow-sorted-output actual-follow-sorted-output +' + + +test_expect_success SYMLINKS 'dir-iterator should ignore recursive symlinks w/ follow flag' ' + cat >expected-rec-symlinks-sorted-output <<-EOF && + [d] (a) [a] ./dir5/a + [d] (a/b) [b] ./dir5/a/b + [d] (a/b/d) [d] ./dir5/a/b/d + [d] (a/c) [c] ./dir5/a/c + EOF + + test-tool dir-iterator --follow-symlinks ./dir5 >out && + sort actual-rec-symlinks-sorted-output && + + test_cmp expected-rec-symlinks-sorted-output actual-rec-symlinks-sorted-output +' + test_done From patchwork Thu May 2 14:48:26 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Matheus Tavares X-Patchwork-Id: 10927029 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 A43F714B6 for ; Thu, 2 May 2019 14:49:10 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 941A7285A4 for ; Thu, 2 May 2019 14:49:10 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 85B7F285B7; Thu, 2 May 2019 14:49:10 +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 1DF18285A4 for ; Thu, 2 May 2019 14:49:10 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726475AbfEBOtJ (ORCPT ); Thu, 2 May 2019 10:49:09 -0400 Received: from mail-qt1-f196.google.com ([209.85.160.196]:43908 "EHLO mail-qt1-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726300AbfEBOtI (ORCPT ); Thu, 2 May 2019 10:49:08 -0400 Received: by mail-qt1-f196.google.com with SMTP id g4so2753952qtq.10 for ; Thu, 02 May 2019 07:49:08 -0700 (PDT) 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=IYd5YDaAwJDR062n3C3UV1FSLxEX0e3rRHYQmw3S5+4=; b=cuHeAilbaCLzAY2uax5FQxVobKOmMt84TgFKcrnwHc9E4sz/oz/cwS4B7dso+sTMlT XINT4bmIYHomKBEipcAt0NVUBlXf3lisMe0BY7thNvaAg+A7AZyiYv3fFZiXzapxQhls PTfh0JJBAv8OYQXFcS+aBKuzytT6YNTgPBcvMY6Ewo8HpMsjb665tSyRq95AS1J6iz0T DOlJ0wAmye42QdG5bjI7erdsFKhAeE50kC5H8LtQhZ6kLzJD1+IN5AfQgXXR8QCXNzLw 8WU0rMlgpxGiJ5YoTDyCfL182wtqiS4BERSvf9UgP6gxpivm2j6Wd5qvQz+vtVlLV55y KEnQ== 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=IYd5YDaAwJDR062n3C3UV1FSLxEX0e3rRHYQmw3S5+4=; b=QDYfDSDvZQawuma+3hzfDGgHAnsDLGipxbkCPHwLFyFgXIfiP+wuK+a7DYCAHJjj+g dC2Q+loaBeeWvEHgUWvHEnicbUXrgI0V72Hayc9DcUW/1uME++WxS4gC3nUuZmzjCHKl TljIanOYjKEXjSsc039rPJ9KVGjkAH0uT+nUruvCjDFvg9V/TjOMKIaPF2CNXME0m1yY Yh33qoGfXkYIbAh2azYpl0IemvXlw4vrePl/maT++MiOTmcX3JLlprBifzOOoZAOgvoK VmeZAi2L0/Y3Ctpq0VxSBIbHVmwzrKyS7Aacd3Ip9oq7+VmahXZLLH1GABILvJhOJ973 1Vpg== X-Gm-Message-State: APjAAAXlfq+fqjykcw+fpteixFNLuChIiEQWwisHusJXR1Cl4IP71RPy mKKcIWtjaihmppU/PTcJURGzQ/3aEbE= X-Google-Smtp-Source: APXvYqw7lpo2Eu27RaBhvbDE06LCZD117ea0RlA3ird4tDPJDp27OrltKV0SZUoO7p9RPaiPke9zqg== X-Received: by 2002:ac8:66d6:: with SMTP id m22mr3413964qtp.323.1556808546168; Thu, 02 May 2019 07:49:06 -0700 (PDT) Received: from mango.spo.virtua.com.br ([2804:14c:81:942d::1]) by smtp.gmail.com with ESMTPSA id s64sm22002880qkc.39.2019.05.02.07.49.03 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 02 May 2019 07:49:05 -0700 (PDT) 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=?= , =?utf-8?q?SZEDER_G?= =?utf-8?q?=C3=A1bor?= , kernel-usp@googlegroups.com, Junio C Hamano , Michael Haggerty Subject: [GSoC][PATCH v6 07/10] clone: copy hidden paths at local clone Date: Thu, 2 May 2019 11:48:26 -0300 Message-Id: <20190502144829.4394-8-matheus.bernardino@usp.br> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190502144829.4394-1-matheus.bernardino@usp.br> References: <20190330224907.3277-1-matheus.bernardino@usp.br> <20190502144829.4394-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 directories. 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 adjust tests to reflect this behaviour change. Signed-off-by: Matheus Tavares Signed-off-by: Ævar Arnfjörð Bjarmason Co-authored-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 d1aba3b13f..f117a6b206 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 0800c3853f..c3998f2f9e 100755 --- a/t/t5604-clone-reference.sh +++ b/t/t5604-clone-reference.sh @@ -247,16 +247,25 @@ test_expect_success 'clone a repo with garbage in objects/*' ' done && 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 Thu May 2 14:48:27 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matheus Tavares X-Patchwork-Id: 10927031 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 BAF2414B6 for ; Thu, 2 May 2019 14:49:13 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id AACEC285B5 for ; Thu, 2 May 2019 14:49:13 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 9F435285C3; Thu, 2 May 2019 14:49:13 +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 4428C285B5 for ; Thu, 2 May 2019 14:49:13 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726477AbfEBOtM (ORCPT ); Thu, 2 May 2019 10:49:12 -0400 Received: from mail-qt1-f195.google.com ([209.85.160.195]:46682 "EHLO mail-qt1-f195.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726297AbfEBOtL (ORCPT ); Thu, 2 May 2019 10:49:11 -0400 Received: by mail-qt1-f195.google.com with SMTP id i31so2734330qti.13 for ; Thu, 02 May 2019 07:49:11 -0700 (PDT) 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=bWCV+CWpi3XnwtnI5CIUo+JQ1nhJiKlP+GPCB1eYga4=; b=JFVta34k+qi+my0WI+awnYgdPccTOtCrROhkW+Cop7QGO9HUTQXoVpYQs9sZQjQzsk uQ9Dsle/i24dHqwzwpY5epLfErtqbsLDnOSEzlCbiMjE4ABcZ8g1P08szXZC0pcPt6K1 U7nyHhidbeYywp1neM9klrC9gomvHycqUhMql8WHzBcIzlt850uIjma3GdIUn33Dwryh oLiWvNUGcz+pIsAHdMic73a2m21L3DpUs/mt73LmHeSt0/QtfxJvz+aQ6mldc8zkEWfV F3Qfhhm8bgjWbtXzlMEXU5uN7Cjk2sGLmzUX+NjwKfwi6oQf87f5Eal465tBJ/4Ho3mN LAQQ== 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=bWCV+CWpi3XnwtnI5CIUo+JQ1nhJiKlP+GPCB1eYga4=; b=pKRanV3dofSB77bd6MZ4NQT9vXks4OUIOBxrpAF6xMgQ0VcPzkrJd8kz6ur/Ck+IbR 0r1w+fAUOGCreRylYoznwFZdWqltpS/cQ7OTLmta7RoI7XmG7bAMSBIdEShPl3SUXvjD AcHjBioSoiQWoIOrcl1/ABynfPTIATjWCR35NPF2+EoVCsscsRvERx7gDRowuPLHMw3d RS845AUo16HVV2ykPSXiSYjMJfwRRBvxHy6DVE+7sX6hybUo+HbUb/3XvLR7IS8l8Ej3 dl67x0m02dF1y+RQXQXsqN/3jgRV46yZRznd2fkj5pmhwXcOTfcLM28Uu3vi1DqRU3Pl gKCg== X-Gm-Message-State: APjAAAUHsqSy/g44293yvj59cKCb4fiMz1Ms3xOVq+goTl6stAZclVwt KLud2YATfF5+P7O+gh21GCILoJV9HgI= X-Google-Smtp-Source: APXvYqyzsVQMYjh+W0yU1Q9d3D8oT+Lbz1yNEJYbuqAPZttqNYJTxkEQmyf9Ul0wHnkVjOyS+u6/oA== X-Received: by 2002:aed:3522:: with SMTP id a31mr3356037qte.269.1556808549347; Thu, 02 May 2019 07:49:09 -0700 (PDT) Received: from mango.spo.virtua.com.br ([2804:14c:81:942d::1]) by smtp.gmail.com with ESMTPSA id s64sm22002880qkc.39.2019.05.02.07.49.06 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 02 May 2019 07:49:08 -0700 (PDT) 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=?= , =?utf-8?q?SZEDER_G?= =?utf-8?q?=C3=A1bor?= , kernel-usp@googlegroups.com, Junio C Hamano , Michael Haggerty Subject: [GSoC][PATCH v6 08/10] clone: extract function from copy_or_link_directory Date: Thu, 2 May 2019 11:48:27 -0300 Message-Id: <20190502144829.4394-9-matheus.bernardino@usp.br> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190502144829.4394-1-matheus.bernardino@usp.br> References: <20190330224907.3277-1-matheus.bernardino@usp.br> <20190502144829.4394-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 to remove copy_or_link_directory's explicit recursion, which will be done in a following patch. Also makes the code more readable. Signed-off-by: Matheus Tavares --- builtin/clone.c | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/builtin/clone.c b/builtin/clone.c index f117a6b206..1ee6d6050e 100644 --- a/builtin/clone.c +++ b/builtin/clone.c @@ -392,6 +392,21 @@ static void copy_alternates(struct strbuf *src, struct strbuf *dst, fclose(in); } +static void mkdir_if_missing(const char *pathname, mode_t mode) +{ + struct stat st; + + if (!mkdir(pathname, mode)) + return; + + 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 +419,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 Thu May 2 14:48:28 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matheus Tavares X-Patchwork-Id: 10927033 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 3A1031398 for ; Thu, 2 May 2019 14:49:16 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 28FC4285B7 for ; Thu, 2 May 2019 14:49:16 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 1D531285E5; Thu, 2 May 2019 14:49:16 +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 9DD4D285B7 for ; Thu, 2 May 2019 14:49:15 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726480AbfEBOtO (ORCPT ); Thu, 2 May 2019 10:49:14 -0400 Received: from mail-qt1-f194.google.com ([209.85.160.194]:34643 "EHLO mail-qt1-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726283AbfEBOtO (ORCPT ); Thu, 2 May 2019 10:49:14 -0400 Received: by mail-qt1-f194.google.com with SMTP id j6so2809580qtq.1 for ; Thu, 02 May 2019 07:49:13 -0700 (PDT) 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=lPjxZkJsQDvJPO172O4AQCR9eAPcBvA1hjIQrPgUKzM=; b=L1cg9lbTAFW6SUDgps+IuRyY9EnSGzUGW90KTWPv45vmzmMfGTILCOaAXXiDiKjRR4 YsrZYC/pXnH1kmInXArFET7RxjFpCs9uB2Vbp/3jsHtpGIxuTESai4FT1E/60f305zfl RZD0XqWTxjbzVguwN5+HVP6+FYy1ohAEqE3ulhjTE1wzEW5Lk7TZWUQUGytk3vCV/yi1 cPXqV0qaV4o9rDc8HmvUkOVz3/3iMe+08N0DlH1L443V+9TQ4uazH/6S4YJdVnr1xBr2 MQHwqZPznggegWhy8hz6/xyDMh8gVGrqqFDS651b3mR5tjb+ql2veexwr++QW/TqqAkC Bsig== 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=lPjxZkJsQDvJPO172O4AQCR9eAPcBvA1hjIQrPgUKzM=; b=J1E17ybIJ2HLlrtEacf2qDYg3tZh/5oyO0IPU8lhH1nSEXwlxYi1o6yc72INLGSnuM m6Lwxu0D8yCD58+gR8LvX8fK/P0uOtql/7ucwhR/fSsnPLBObnGMVJ/twK9xkh9jxWQD CLr/cz7H2MbdOnqZKrfwBuOpM36JPlCe2EsOAa8lhOK4Zvjx5S492LZ4rf+YeIkJvmIJ uJwMNe32ZK0S1c93WMnxl58+BsxXSBRNDMgbnmmFLxKFLf3DWVCgFJsBF4CPlIcQ2HhO s9a+XHIcF2uGfiJMpC5VsdSXOblfxwHC165bUrXnvUCdrJirMI3slqCxuF8ND5HrJ14Y XF6g== X-Gm-Message-State: APjAAAWmmQZB3mR9S+BB4/C3Qnh2wIJwoOFZ+CcpSKyPVwvza1+dSNUT Z0GJB38DHTJsF8/ybpx7nIXQsqIkB6c= X-Google-Smtp-Source: APXvYqwUjYU2nFffV0uW6V5SAoOAX5veuvorFA7yiQoqjE32UWTMX6n3BR+VuJhoTyy7t7iZJFhcqQ== X-Received: by 2002:a0c:9b01:: with SMTP id b1mr3459235qve.100.1556808552576; Thu, 02 May 2019 07:49:12 -0700 (PDT) Received: from mango.spo.virtua.com.br ([2804:14c:81:942d::1]) by smtp.gmail.com with ESMTPSA id s64sm22002880qkc.39.2019.05.02.07.49.09 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 02 May 2019 07:49:12 -0700 (PDT) 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=?= , =?utf-8?q?SZEDER_G?= =?utf-8?q?=C3=A1bor?= , kernel-usp@googlegroups.com, Michael Haggerty , Junio C Hamano Subject: [GSoC][PATCH v6 09/10] clone: use dir-iterator to avoid explicit dir traversal Date: Thu, 2 May 2019 11:48:28 -0300 Message-Id: <20190502144829.4394-10-matheus.bernardino@usp.br> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190502144829.4394-1-matheus.bernardino@usp.br> References: <20190330224907.3277-1-matheus.bernardino@usp.br> <20190502144829.4394-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 avoids 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 could succeed even though the .git/objects copy didn't fully succeed. Also, with the dir-iterator API, recursive symlinks will be detected and skipped. This is another behavior improvement, since the current version would continue to copy the same content over and over until stat() returned an ELOOP error. Signed-off-by: Matheus Tavares --- builtin/clone.c | 47 +++++++++++++++++++++++++---------------------- 1 file changed, 25 insertions(+), 22 deletions(-) diff --git a/builtin/clone.c b/builtin/clone.c index 1ee6d6050e..f99acd878f 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" @@ -408,42 +410,39 @@ 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; + unsigned int flags; mkdir_if_missing(dest->buf, 0777); + flags = DIR_ITERATOR_PEDANTIC | DIR_ITERATOR_FOLLOW_SYMLINKS; + iter = dir_iterator_begin(src->buf, flags); + + if (!iter) + die_errno(_("failed to start iterator over '%s'"), src->buf); + 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; } @@ -460,7 +459,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) @@ -478,7 +481,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); } From patchwork Thu May 2 14:48:29 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Matheus Tavares X-Patchwork-Id: 10927035 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 DADB214B6 for ; Thu, 2 May 2019 14:49:18 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id CAA46285B7 for ; Thu, 2 May 2019 14:49:18 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id BF25C285E5; Thu, 2 May 2019 14:49:18 +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 4DD3B285B7 for ; Thu, 2 May 2019 14:49:18 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726485AbfEBOtR (ORCPT ); Thu, 2 May 2019 10:49:17 -0400 Received: from mail-qk1-f196.google.com ([209.85.222.196]:37250 "EHLO mail-qk1-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726282AbfEBOtR (ORCPT ); Thu, 2 May 2019 10:49:17 -0400 Received: by mail-qk1-f196.google.com with SMTP id c1so1602141qkk.4 for ; Thu, 02 May 2019 07:49:16 -0700 (PDT) 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=DCNwQ0xRP+5inD0eWz03EA3NndimqjIs1EhXIu81xYk=; b=RMF2rVPvrI8uK0hCGNgJXIhWHnnczCMUsEKp4pbjgW3W6redFbSE+VVx5fXDkNOjoo RTVXChbfRAN/e+3AwPGLHCd+ARpg0sw53YV0TkAW5a3m/XRmEFZ36DkS4ZxR4iq/oQB3 HqISWLjUdGmhPXVRE93+1dRPxF3IfrkpSck5xAiIwoR4CytYTRVEUFa6UDKmLmpsmj2e oLcFKrDahSeX5tvHLMEoEvs6tsZQ1HfQqGkI0Sl4iJ+sEs8eSgiFge0NW+j9lBxFI6LV QdP8g7b1SmzH6XqsASDSqkn/nTXe5X4Vw0ks5qX9VMLlv9osQbE/+CZBwhWdeHcdQfg/ NWBA== 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=DCNwQ0xRP+5inD0eWz03EA3NndimqjIs1EhXIu81xYk=; b=pYM4d2gTqQdx0UKaBmC7w7jFeeOgYL53FgQPHYVxNBEXgZXO8yIt0I8pmovOO+VojB Qv07rIvFYMVaKI3jIOuP/N8TIGBqhSbGSMkqkMbpTmvdqd30LjA6q3aK6Tejcr0SI1ur rHo/CMj4elvKkigFSAc3uUElTzh0CsCfHeeVoWeNVvQ6OUjeAZwvzzUYgjRt6bg5eag8 kpd8j/Co/ha1Br5Ka9FEH3biiKZYWCgrFFezD3d71Dj77S6iXEp4sadSyYTQuJSUEym7 zHv/Ot0nnTiCrZl7YlatNAsP0rAz4QOoM8dxSZE2fD0l1lA4fzbG01CVf4+obCzRb0Fm XXHA== X-Gm-Message-State: APjAAAW8xWNpmZ+mZpCd0vjO3JBfdz4t7ZoI4efr6eTeYOYOpHGb8pqW lH8jJ5NTCXKXAbO7flD/U7a6KINtNQw= X-Google-Smtp-Source: APXvYqwD0lmsn+qiyv3D6LuQM1ahO/j0S88zRzB8AxY3Rwnnh18juIlN+8b/KbnWamJW+Xpgu+Y0AQ== X-Received: by 2002:a37:6087:: with SMTP id u129mr3338110qkb.300.1556808555953; Thu, 02 May 2019 07:49:15 -0700 (PDT) Received: from mango.spo.virtua.com.br ([2804:14c:81:942d::1]) by smtp.gmail.com with ESMTPSA id s64sm22002880qkc.39.2019.05.02.07.49.13 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 02 May 2019 07:49:15 -0700 (PDT) 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=?= , =?utf-8?q?SZEDER_G?= =?utf-8?q?=C3=A1bor?= , kernel-usp@googlegroups.com, Junio C Hamano , Michael Haggerty Subject: [GSoC][PATCH v6 10/10] clone: replace strcmp by fspathcmp Date: Thu, 2 May 2019 11:48:29 -0300 Message-Id: <20190502144829.4394-11-matheus.bernardino@usp.br> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190502144829.4394-1-matheus.bernardino@usp.br> References: <20190330224907.3277-1-matheus.bernardino@usp.br> <20190502144829.4394-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 the use of strcmp by fspathcmp at copy_or_link_directory, which is more permissive/friendly to case-insensitive file systems. Signed-off-by: Matheus Tavares Suggested-by: Nguyễn Thái Ngọc Duy --- builtin/clone.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/builtin/clone.c b/builtin/clone.c index f99acd878f..6e0f194c3b 100644 --- a/builtin/clone.c +++ b/builtin/clone.c @@ -442,7 +442,7 @@ static void copy_or_link_directory(struct strbuf *src, struct strbuf *dest, } /* Files that cannot be copied bit-for-bit... */ - if (!strcmp(iter->relative_path, "info/alternates")) { + if (!fspathcmp(iter->relative_path, "info/alternates")) { copy_alternates(src, dest, src_repo); continue; }