From patchwork Thu Sep 10 17:21:20 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matheus Tavares X-Patchwork-Id: 11768417 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 4FD07139F for ; Thu, 10 Sep 2020 17:42:51 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 2BD85221E3 for ; Thu, 10 Sep 2020 17:42:51 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=usp-br.20150623.gappssmtp.com header.i=@usp-br.20150623.gappssmtp.com header.b="P/hJDkS6" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726776AbgIJRma (ORCPT ); Thu, 10 Sep 2020 13:42:30 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:54950 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725935AbgIJRVm (ORCPT ); Thu, 10 Sep 2020 13:21:42 -0400 Received: from mail-qv1-xf32.google.com (mail-qv1-xf32.google.com [IPv6:2607:f8b0:4864:20::f32]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8ABA1C061757 for ; Thu, 10 Sep 2020 10:21:41 -0700 (PDT) Received: by mail-qv1-xf32.google.com with SMTP id cr8so3708280qvb.10 for ; Thu, 10 Sep 2020 10:21:41 -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=OwHyUezafLtE2AXnzr/cZDF+mCgHLxtf+oKcpVzOsn4=; b=P/hJDkS6HI5Mm5aCSsBxEIJmmCAKY0cBopXZmQefpv7Yaj/SVZy+D/Gf8vS0b4qpj4 0+ITnL+9IQEZYoMfktqUbtnGAKF6k/BgKz/HyE1ybx2qx74Mpgv0cqYID4sBc1Nfzpjb ZvpkXAU0oNGIrHzxVVaBBQr4wokKJ+p8LxaMU2SfAUwNvZzltjAWwwPXGotKpNHAzOLL opbFLHrNQ5vprSQxkfTuH9+wkm/tlutk3PayGEknjLhduEvG/dB0eC67Urmn7UqTypAw WaK4lAW10Dp9cRubEmPrfGeO7jyIhMbldT8EH18pBE7jpc9PVitnVN2CZtIVBpp2SFEg K9Tg== 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=OwHyUezafLtE2AXnzr/cZDF+mCgHLxtf+oKcpVzOsn4=; b=GZ//ZsmBXpPsSM8Q+dvdUoVrIJy+IcrRlaWFnB2Ew82c2RcsB/VPevi259O9cTOBMk tPjhZONJw2vjLstvsTs8mbn+QmZ1ip+jgO1zk/7KTAbD5mSwZtOGxu28A6XFg0zbZhTK mt50t4iY7X/swNSc4DKasKnpfvnMgIFwiVyaR9/RIrGBssXiS2dIy/RENwCDet6btyxK OO2j15WtBVaXJmxA9shfXL78/RcVrmyNwlD7shO/VMa0BYdp8dMof/kULz5CuMaOVGaC kHTY2jig/2PepN9AcfyfoqQZYwpJVzxvtrLHeHZ19NLAB9CBPTuqYKMGP6NT3Ju0UglQ ASQQ== X-Gm-Message-State: AOAM532Rv28ntAkl/LTMuv6d2kYRPVsMW3khyZvuvSEyl7IEd1olZwH3 8AdZ5zTdUZn2iNoPUEW6HZPJVDgszysWuQ== X-Google-Smtp-Source: ABdhPJx/rZqEItH6AAc9S7VyZ5v22hdJ7NjXTmpvAzR2JdiLyHxk/QuxEsAUVpOnMvmfaOV7q3DhAg== X-Received: by 2002:a0c:99c8:: with SMTP id y8mr9866105qve.53.1599758499838; Thu, 10 Sep 2020 10:21:39 -0700 (PDT) Received: from localhost.localdomain ([2804:14c:81:83eb::1001]) by smtp.gmail.com with ESMTPSA id h18sm7037437qkl.12.2020.09.10.10.21.37 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 10 Sep 2020 10:21:39 -0700 (PDT) From: Matheus Tavares To: git@vger.kernel.org Cc: gitster@pobox.com, stolee@gmail.com, newren@gmail.com, jonathantanmy@google.com, jrnieder@gmail.com, sunshine@sunshineco.com Subject: [PATCH v6 1/9] doc: grep: unify info on configuration variables Date: Thu, 10 Sep 2020 14:21:20 -0300 Message-Id: <70c9a4e7415f532c2aa6fdd460a927b5e677cd97.1599758167.git.matheus.bernardino@usp.br> X-Mailer: git-send-email 2.28.0 In-Reply-To: References: MIME-Version: 1.0 Sender: git-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org Explanations about the configuration variables for git-grep are duplicated in "Documentation/git-grep.txt" and "Documentation/config/grep.txt", which can make maintenance difficult. The first also contains a definition not present in the latter (grep.fullName). To avoid problems like this, let's unify the information in the second file and include it in the first. Signed-off-by: Matheus Tavares --- Documentation/config/grep.txt | 10 ++++++++-- Documentation/git-grep.txt | 36 ++++++----------------------------- 2 files changed, 14 insertions(+), 32 deletions(-) diff --git a/Documentation/config/grep.txt b/Documentation/config/grep.txt index 44abe45a7c..dd51db38e1 100644 --- a/Documentation/config/grep.txt +++ b/Documentation/config/grep.txt @@ -16,8 +16,14 @@ grep.extendedRegexp:: other than 'default'. grep.threads:: - Number of grep worker threads to use. - See `grep.threads` in linkgit:git-grep[1] for more information. + Number of grep worker threads to use. See `--threads` +ifndef::git-grep[] + in linkgit:git-grep[1] +endif::git-grep[] + for more information. + +grep.fullName:: + If set to true, enable `--full-name` option by default. grep.fallbackToNoIndex:: If set to true, fall back to git grep --no-index if git grep diff --git a/Documentation/git-grep.txt b/Documentation/git-grep.txt index a7f9bc99ea..9bdf807584 100644 --- a/Documentation/git-grep.txt +++ b/Documentation/git-grep.txt @@ -41,34 +41,8 @@ characters. An empty string as search expression matches all lines. CONFIGURATION ------------- -grep.lineNumber:: - If set to true, enable `-n` option by default. - -grep.column:: - If set to true, enable the `--column` option by default. - -grep.patternType:: - Set the default matching behavior. Using a value of 'basic', 'extended', - 'fixed', or 'perl' will enable the `--basic-regexp`, `--extended-regexp`, - `--fixed-strings`, or `--perl-regexp` option accordingly, while the - value 'default' will return to the default matching behavior. - -grep.extendedRegexp:: - If set to true, enable `--extended-regexp` option by default. This - option is ignored when the `grep.patternType` option is set to a value - other than 'default'. - -grep.threads:: - Number of grep worker threads to use. If unset (or set to 0), Git will - use as many threads as the number of logical cores available. - -grep.fullName:: - If set to true, enable `--full-name` option by default. - -grep.fallbackToNoIndex:: - If set to true, fall back to git grep --no-index if git grep - is executed outside of a git repository. Defaults to false. - +:git-grep: 1 +include::config/grep.txt[] OPTIONS ------- @@ -269,8 +243,10 @@ providing this option will cause it to die. found. --threads :: - Number of grep worker threads to use. - See `grep.threads` in 'CONFIGURATION' for more information. + Number of grep worker threads to use. If not provided (or set to + 0), Git will use as many worker threads as the number of logical + cores available. The default value can also be set with the + `grep.threads` configuration. -f :: Read patterns from , one per line. From patchwork Thu Sep 10 17:21:21 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matheus Tavares X-Patchwork-Id: 11768255 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id EE5C292C for ; Thu, 10 Sep 2020 17:23:17 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id C7032208E4 for ; Thu, 10 Sep 2020 17:23:17 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=usp-br.20150623.gappssmtp.com header.i=@usp-br.20150623.gappssmtp.com header.b="RtViOGYk" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726434AbgIJRW6 (ORCPT ); Thu, 10 Sep 2020 13:22:58 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:54984 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726841AbgIJRVy (ORCPT ); Thu, 10 Sep 2020 13:21:54 -0400 Received: from mail-qv1-xf41.google.com (mail-qv1-xf41.google.com [IPv6:2607:f8b0:4864:20::f41]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7810EC061786 for ; Thu, 10 Sep 2020 10:21:53 -0700 (PDT) Received: by mail-qv1-xf41.google.com with SMTP id q10so3734108qvs.1 for ; Thu, 10 Sep 2020 10:21:53 -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=4f1kw0Re5Sk3KDMu/uikPLoRDuLXA2hNMJrYbQ7PV7U=; b=RtViOGYk1iIAFsB9FI4omHOXpN+P2W2EZfkTPxz9AeJaeumlWbadYz5rP3jW+u3nLi 2dy8JyRNZ3MuARBewcSm1fc8Z9Ry0m9EZat8b8sOUqm/qZKKSsAxSysKk5OJrGX3g/4q xZCuwQ8q8nRFoLcGXVrvsEhgMyxetNAbWy4Gx4h8JbATanbHM0JWSi/QRLyvsAZD4gX5 d6cwr034SPOQIGPNUdapuSDjLTmtrrGhXMqXYY37hY4fLmlEW/2mD/ZfwUConi9F1Yy8 OYryn5ZIjhfhGyLXCL8rwT8cGNe2VdSQcbfs3gyiwZ1pqQlZqVzYWugjMjV+2bIHBJLc qTaw== 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=4f1kw0Re5Sk3KDMu/uikPLoRDuLXA2hNMJrYbQ7PV7U=; b=K1h7h2ax42AiNVLwy1tmkE7K8oMRtoU5CxGqNMVMuhMWmiKvI8CZqOcr9BmXldJJlg m2HG0nBGwCQooFRVelJh4Xb+wPgIaaZyRepz5L2TOHvlSwqhKzRbe7u3zA6p9JeZ1azt 4yUUMMNe6YSqAewdUW4KRpwRmk2e3i1NG4OESrHuU8v+UweaGxy+MmsNYOqrBn7CJg7J fCC/CWcwfvJiMXjRHwACPaz2Mp3/aUGXAXYrR1kT5BIniWfVBH87z95HbIyx6wqEOn2F lzim+l4brrtR/M0cPgqUwvm8IYLCl7HBCTR/NDAe64SF/kunaNmFGKIligkqX7r0sKSq n4xA== X-Gm-Message-State: AOAM531aYhxR7QXqSErbQpD/oiyMGHEEnfvNO9NysSMuyAytXJ2KdDxJ +otALyYt1PpUIQSHluMQU+ElrULlXEBxnA== X-Google-Smtp-Source: ABdhPJwUhzH/NgX37ZGrg1zFOptpbvzBCqSxKdTzRJWWZtO5pAClxaSf2HczNeOAU569fHF5Z1JuHw== X-Received: by 2002:a0c:b2d4:: with SMTP id d20mr9639349qvf.1.1599758506608; Thu, 10 Sep 2020 10:21:46 -0700 (PDT) Received: from localhost.localdomain ([2804:14c:81:83eb::1001]) by smtp.gmail.com with ESMTPSA id h18sm7037437qkl.12.2020.09.10.10.21.43 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 10 Sep 2020 10:21:45 -0700 (PDT) From: Matheus Tavares To: git@vger.kernel.org Cc: gitster@pobox.com, stolee@gmail.com, newren@gmail.com, jonathantanmy@google.com, jrnieder@gmail.com, sunshine@sunshineco.com Subject: [PATCH v6 2/9] t1308-config-set: avoid false positives when using test-config Date: Thu, 10 Sep 2020 14:21:21 -0300 Message-Id: <3c2d722152575d8a4f7aa01d958823a66c5ba26e.1599758167.git.matheus.bernardino@usp.br> X-Mailer: git-send-email 2.28.0 In-Reply-To: References: MIME-Version: 1.0 Sender: git-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org One test in t1308 expects test-config to fail with exit code 128 due to a parsing error in the config machinery. But test-config might also exit with 128 for any other reason that leads it to call die(). Therefore the test can potentially succeed for the wrong reason. To avoid false positives, let's check test-config's stderr, in addition to the exit code, and make sure that the cause of the error is the one we expect in this test. Moreover, the test was using the auxiliary function check_config, which optionally takes a number to compare with test-config's exit code, and a string to compare with its stdout. Because the function does not check stderr, it can induce improper uses, like the one corrected in this patch. To avoid this, remove the optional expect_code parameter, disallowing tests that expect an error from test-config to use this helper function. There is one error, though, which is printed to stdout despite returning a non-zero code: "value not found" (exit code 1). For this one, let's add another function which properly checks stdout and the code. Helped-by: Eric Sunshine Signed-off-by: Matheus Tavares --- t/t1308-config-set.sh | 28 +++++++++++++--------------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/t/t1308-config-set.sh b/t/t1308-config-set.sh index 3a527e3a84..66c6363080 100755 --- a/t/t1308-config-set.sh +++ b/t/t1308-config-set.sh @@ -7,18 +7,15 @@ test_description='Test git config-set API in different settings' # 'check_config get_* section.key value' verifies that the entry for # section.key is 'value' check_config () { - if test "$1" = expect_code - then - expect_code="$2" && shift && shift - else - expect_code=0 - fi && - op=$1 key=$2 && shift && shift && - if test $# != 0 - then - printf "%s\n" "$@" - fi >expect && - test_expect_code $expect_code test-tool config "$op" "$key" >actual && + test-tool config "$1" "$2" >actual && + shift && shift && + printf "%s\n" "$@" >expect && + test_cmp expect actual +} + +check_not_found () { + test_expect_code 1 test-tool config "$1" "$2" >actual && + echo "Value not found for \"$2\"" >expect && test_cmp expect actual } @@ -108,7 +105,7 @@ test_expect_success 'key with case insensitive section header & variable' ' ' test_expect_success 'find value with misspelled key' ' - check_config expect_code 1 get_value "my.fOo Bar.hi" "Value not found for \"my.fOo Bar.hi\"" + check_not_found get_value "my.fOo Bar.hi" ' test_expect_success 'find value with the highest priority' ' @@ -121,7 +118,7 @@ test_expect_success 'find integer value for a key' ' test_expect_success 'find string value for a key' ' check_config get_string case.baz hask && - check_config expect_code 1 get_string case.ba "Value not found for \"case.ba\"" + check_not_found get_string case.ba ' test_expect_success 'check line error when NULL string is queried' ' @@ -130,7 +127,8 @@ test_expect_success 'check line error when NULL string is queried' ' ' test_expect_success 'find integer if value is non parse-able' ' - check_config expect_code 128 get_int lamb.head + test_expect_code 128 test-tool config get_int lamb.head 2>result && + test_i18ngrep "fatal: bad numeric config value .none. for .lamb\.head." result ' test_expect_success 'find bool value for the entered key' ' From patchwork Thu Sep 10 17:21:22 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matheus Tavares X-Patchwork-Id: 11768455 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id E1CA6139F for ; Thu, 10 Sep 2020 17:52:07 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id BFBDC20C09 for ; Thu, 10 Sep 2020 17:52:07 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=usp-br.20150623.gappssmtp.com header.i=@usp-br.20150623.gappssmtp.com header.b="V7OvSWjU" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1725974AbgIJRlw (ORCPT ); Thu, 10 Sep 2020 13:41:52 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:54972 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725951AbgIJRVv (ORCPT ); Thu, 10 Sep 2020 13:21:51 -0400 Received: from mail-qk1-x742.google.com (mail-qk1-x742.google.com [IPv6:2607:f8b0:4864:20::742]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 976F6C0613ED for ; Thu, 10 Sep 2020 10:21:50 -0700 (PDT) Received: by mail-qk1-x742.google.com with SMTP id d20so6878122qka.5 for ; Thu, 10 Sep 2020 10:21:50 -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=i4y+U4GTGlNUPsaLRPbaZMHdUUBXALPwCNHtrAHuNn4=; b=V7OvSWjU5alzdRXWKlhbtd8Bd5shnTdyeSG81HeZJv6txyhVRHjR+8cXcvyIF22Ng6 XYCJwxBFwrCJJzqtHSxer+wV2KIDPgR1HGO8ZE1VulZ5cNh341yDVMsTVnohPINd3+/7 FUuzZAUTP3jbOXMFuMX2AbozB0VOJobPBg81pJDzNNrlfGdhOY5SqZAvjpojNe9LP25k 28kq8fuvT0gCjnDfnVfd1lQy1TAl5ZdD+wNL0bv7RKMuCYhHM5RDQHlBy4B5zlbnlpYe IeTKvR2CX4sn2gpZ2GJf+QsMnaas7Q9LyXPe2ILtfgYxptG8/n0+UsMxZkhnLCt2muGN 69Mg== 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=i4y+U4GTGlNUPsaLRPbaZMHdUUBXALPwCNHtrAHuNn4=; b=b2NSv68WK1NuoW6GcmdcP1V2fcgc0etv1wiTkFlYZovS+kJP8NjlXec2JGxpiTJKTN M7m1C3ri5pJVx62WkxCTW3NhjpAJlf5c4ILZRV93/I2AVkvw/BEeA4owlD3CI7Os2qjl 1vljoCc86zZnJ40o+UPawwcdKMtITRzbSuf5Uv/tPxQjH3uqj7/rRIgCMGt8XRpHEfef jtU6z0ZRYBtHpeEUqUSK9apWVlIN5zYQ8Lht6aytXZlNb41rh6RTkSLpN09j8Fpa7Axq DlpLfZC+bG9sA6UJUT0lc9N4K0LkCc1KZcc6qlkK2I5muOGyO+2RPhwqexI1oRnPpPHI LmsA== X-Gm-Message-State: AOAM531mkSS8voei7OASrdUs9BuNQi+PzN+Zs9PqGRznUK0xF8zBkUW/ bE0L1ZwQdRttdcKcyRZRgV2hFq5YUn5stQ== X-Google-Smtp-Source: ABdhPJyDJFjN18ZFcat/G/kW/i2V67D+PodpyGAl5Ca5oiYHWG1S0ugpV+L2uj+mlPA4UG8CZTlVGQ== X-Received: by 2002:a37:8ec3:: with SMTP id q186mr8838951qkd.233.1599758509450; Thu, 10 Sep 2020 10:21:49 -0700 (PDT) Received: from localhost.localdomain ([2804:14c:81:83eb::1001]) by smtp.gmail.com with ESMTPSA id h18sm7037437qkl.12.2020.09.10.10.21.46 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 10 Sep 2020 10:21:48 -0700 (PDT) From: Matheus Tavares To: git@vger.kernel.org Cc: gitster@pobox.com, stolee@gmail.com, newren@gmail.com, jonathantanmy@google.com, jrnieder@gmail.com, sunshine@sunshineco.com Subject: [PATCH v6 3/9] t/helper/test-config: be consistent with exit codes Date: Thu, 10 Sep 2020 14:21:22 -0300 Message-Id: <45d13744b7849ec485f76e0a67e972fdd01ba21a.1599758167.git.matheus.bernardino@usp.br> X-Mailer: git-send-email 2.28.0 In-Reply-To: References: MIME-Version: 1.0 Sender: git-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org The test-config helper can return at least three different exit codes to reflect the status of the requested operation. And these codes are checked in some of the tests. But there is an inconsistent place in the helper where an usage error returns the same code as a "value not found" error. Let's fix that and, while we are here, document the meaning of each exit code in the file's header. Signed-off-by: Matheus Tavares --- t/helper/test-config.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/t/helper/test-config.c b/t/helper/test-config.c index a6e936721f..9e9d50099a 100644 --- a/t/helper/test-config.c +++ b/t/helper/test-config.c @@ -30,6 +30,11 @@ * iterate -> iterate over all values using git_config(), and print some * data for each * + * Exit codes: + * 0: success + * 1: value not found for the given config key + * 2: config file path given as argument is inaccessible or doesn't exist + * * Examples: * * To print the value with highest priority for key "foo.bAr Baz.rock": @@ -80,10 +85,10 @@ int cmd__config(int argc, const char **argv) git_configset_init(&cs); - if (argc < 2) { - fprintf(stderr, "Please, provide a command name on the command-line\n"); - goto exit1; - } else if (argc == 3 && !strcmp(argv[1], "get_value")) { + if (argc < 2) + die("Please, provide a command name on the command-line"); + + if (argc == 3 && !strcmp(argv[1], "get_value")) { if (!git_config_get_value(argv[2], &v)) { if (!v) printf("(NULL)\n"); From patchwork Thu Sep 10 17:21:23 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matheus Tavares X-Patchwork-Id: 11768257 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id DABF292C for ; Thu, 10 Sep 2020 17:23:24 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id B94A120770 for ; Thu, 10 Sep 2020 17:23:24 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=usp-br.20150623.gappssmtp.com header.i=@usp-br.20150623.gappssmtp.com header.b="lXiYHPwt" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726848AbgIJRXT (ORCPT ); Thu, 10 Sep 2020 13:23:19 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:54986 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726893AbgIJRVy (ORCPT ); Thu, 10 Sep 2020 13:21:54 -0400 Received: from mail-qk1-x744.google.com (mail-qk1-x744.google.com [IPv6:2607:f8b0:4864:20::744]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 24F16C061795 for ; Thu, 10 Sep 2020 10:21:54 -0700 (PDT) Received: by mail-qk1-x744.google.com with SMTP id 16so6860268qkf.4 for ; Thu, 10 Sep 2020 10:21:54 -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=0J6TixHuhkP+ec6olUDedm/4dAzFDoGAvs6N2S5ptn0=; b=lXiYHPwt8Bkv1hEwj4/4YNZwMEOXbdVnZKPBzS0bMVObw6c9J0vRix+XnIv1h6mwOV qv3mSsBs8JsIjeMf/1pvzesww4XCUuE79a6EbqagoIkKzY8IFJKyejskWw8cPcqtj6C2 sqxpNpxuH0o3WW9twPFOlGdupchm2/dsPTsHmKFWsXz+yqY6r3Sev6vnXtzg/RLDCG0O n6dqhRSg/4zU7BKd8XrjBBsTqYaAUhiEAZaUApEi2wp8aoJ+k3Yo+DiQyUBjPXcIltMh feJudXgeFofqfccpBxo8oMWahsrikgFYqi0E9uDjzvUbr2rdV3QptRx2UwkgLGtXFB/6 YLbQ== 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=0J6TixHuhkP+ec6olUDedm/4dAzFDoGAvs6N2S5ptn0=; b=U3bifH/J7eMbWgSx3tyAbT5r6cHJNtmUxstZaoVhh9ph35FJV9e3pBT9zVQlCdsYOh QQqQhsHo6agm7USYoXb/imxzWEbkPP4rykd49XXRy0x37rCCLVOoCtiBU7tmdh8ktx/u A+eg933b1kf5VOpcQ8yS7sAcq+Zql37eAZYWp3oaugF1TSqQqBp7+/MzDOw21Xanbmef AzTeelYJB4yZrow65LR+ONQfaJjraSOfwQnIF5qWlyIm8YIBnllpYHc0sRtPK4ws9gYx 33UkOIlSjqEPwgtJXvgWplnuYouTPgLmTz7OXa8EtjrTaQOZhc9ELVnIpEnRhwWnRNQ5 sKmg== X-Gm-Message-State: AOAM533T2pJvVZ/2qYcy0YW1DPvhjbUE1yDvNRAf7dQtOF9G3/Dj0r4F ab/7jq95WLjCZvHxrJlYpjQmkr7J2Stkyw== X-Google-Smtp-Source: ABdhPJy56R9AFtfomdOyacwPYTlKz8c8Fky3+dDS9YgwsLPrmhNGj3+zeatXc9kogzl9uBkQQ0+ZRQ== X-Received: by 2002:a37:38c:: with SMTP id 134mr8624898qkd.193.1599758513010; Thu, 10 Sep 2020 10:21:53 -0700 (PDT) Received: from localhost.localdomain ([2804:14c:81:83eb::1001]) by smtp.gmail.com with ESMTPSA id h18sm7037437qkl.12.2020.09.10.10.21.49 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 10 Sep 2020 10:21:51 -0700 (PDT) From: Matheus Tavares To: git@vger.kernel.org Cc: gitster@pobox.com, stolee@gmail.com, newren@gmail.com, jonathantanmy@google.com, jrnieder@gmail.com, sunshine@sunshineco.com Subject: [PATCH v6 4/9] t/helper/test-config: diagnose missing arguments Date: Thu, 10 Sep 2020 14:21:23 -0300 Message-Id: <51656e43c35e5b83a004dcd7ed34499a0ebed137.1599758167.git.matheus.bernardino@usp.br> X-Mailer: git-send-email 2.28.0 In-Reply-To: References: MIME-Version: 1.0 Sender: git-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org test-config verifies that the correct number of arguments was given for all of its commands except for 'configset_get_value' and 'configset_get_value_multi'. Add the check to these two, so that we properly report missing arguments and prevent out-of-bounds access to argv[]. Signed-off-by: Matheus Tavares --- t/helper/test-config.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/t/helper/test-config.c b/t/helper/test-config.c index 9e9d50099a..26d9c2ac4c 100644 --- a/t/helper/test-config.c +++ b/t/helper/test-config.c @@ -138,7 +138,7 @@ int cmd__config(int argc, const char **argv) printf("Value not found for \"%s\"\n", argv[2]); goto exit1; } - } else if (!strcmp(argv[1], "configset_get_value")) { + } else if (argc >= 3 && !strcmp(argv[1], "configset_get_value")) { for (i = 3; i < argc; i++) { int err; if ((err = git_configset_add_file(&cs, argv[i]))) { @@ -156,7 +156,7 @@ int cmd__config(int argc, const char **argv) printf("Value not found for \"%s\"\n", argv[2]); goto exit1; } - } else if (!strcmp(argv[1], "configset_get_value_multi")) { + } else if (argc >= 3 && !strcmp(argv[1], "configset_get_value_multi")) { for (i = 3; i < argc; i++) { int err; if ((err = git_configset_add_file(&cs, argv[i]))) { From patchwork Thu Sep 10 17:21:24 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matheus Tavares X-Patchwork-Id: 11768261 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 4CB8792C for ; Thu, 10 Sep 2020 17:23:40 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 2A9A2208E4 for ; Thu, 10 Sep 2020 17:23:40 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=usp-br.20150623.gappssmtp.com header.i=@usp-br.20150623.gappssmtp.com header.b="bvWMBO3e" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726474AbgIJRXd (ORCPT ); Thu, 10 Sep 2020 13:23:33 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:55018 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726811AbgIJRWK (ORCPT ); Thu, 10 Sep 2020 13:22:10 -0400 Received: from mail-qk1-x741.google.com (mail-qk1-x741.google.com [IPv6:2607:f8b0:4864:20::741]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 47550C061796 for ; Thu, 10 Sep 2020 10:21:57 -0700 (PDT) Received: by mail-qk1-x741.google.com with SMTP id f142so6811915qke.13 for ; Thu, 10 Sep 2020 10:21:57 -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=EK27lZ324OgqS0qIvd2X9pmkmZc2U3JsTfC8sb6036E=; b=bvWMBO3e4AOSikkACEwhOITVQcryzhsay5sv3U0leCJYakep/7mBQPovvqEVtElqlF 9m0csvQdXR3X0xBbDnalXP8RHAGYE8DggchkE57z6ywNOKCkvYJJ4FQK+hOh52gtMlGs ZBqZQ+RYkBWKYFv4oNDPyUrJxazCQJ5I11WvpnSfMJ10CsYBx+sNaD2ZMyYWuKTaGu96 Xh7YeipY4EWktFY/ZhwE5/6PC39wbPTtnYLBByPQfRKjmM2D9ndHUDaKDpAIdacHiwk8 28RXFSk40XL9Q24bcYu6K3SY3jZWj3Ik9YO6/YuITPEEmyw4FqypWFf01laiW9UGmrLQ CqEA== 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=EK27lZ324OgqS0qIvd2X9pmkmZc2U3JsTfC8sb6036E=; b=jxlh2yqXWjdruimA7V8r4slNN9gIW817HwwZtI7uvNdbcDg0NLS9uWSBAxGjJiJ9i1 ydw2F2fqfmtRu30QM0dg3a0RlBRQBzOrno7U0ZCWXdDcHNZhZvpu7qqpxfTiFg+oVq7S bYDH+xaKvlS5Grm6SCuZDgpxQt4UZWq23orh4VnX2W0GB4P3hZbkqP2JFftXXLc5XrU7 6WgmvLbnuNPa/VdIn0qMWoSnw7TTT+PanGKhyyAxz6RXfNVmgEakVPltEGXDVkZ0adLo 0JEnJjIokSuOpcN370EP/24dOVQc8KpzkYi1qmUB7+6Tlwbtbao16Ricuyt9sjZWHcbD 4gFw== X-Gm-Message-State: AOAM532uOq/MzP3DYelO/Sa0XFWVP5YCdTGLtmqGx8swdJP0r4/dc6gS DeIjFOhoCLyr2bm3mCLlzsjDSeJmaBBVvA== X-Google-Smtp-Source: ABdhPJwEfcXSB183jupbhNIEoPAsl1wTj2tU5oOHG0Ztf4BV5TGlamuoG7HBVvjznP7+/DUKO7SL4A== X-Received: by 2002:a37:8047:: with SMTP id b68mr8423889qkd.299.1599758516068; Thu, 10 Sep 2020 10:21:56 -0700 (PDT) Received: from localhost.localdomain ([2804:14c:81:83eb::1001]) by smtp.gmail.com with ESMTPSA id h18sm7037437qkl.12.2020.09.10.10.21.53 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 10 Sep 2020 10:21:55 -0700 (PDT) From: Matheus Tavares To: git@vger.kernel.org Cc: gitster@pobox.com, stolee@gmail.com, newren@gmail.com, jonathantanmy@google.com, jrnieder@gmail.com, sunshine@sunshineco.com Subject: [PATCH v6 5/9] t/helper/test-config: unify exit labels Date: Thu, 10 Sep 2020 14:21:24 -0300 Message-Id: <924d2e8ceb8b2131a13bafa356c5dc98eccae806.1599758167.git.matheus.bernardino@usp.br> X-Mailer: git-send-email 2.28.0 In-Reply-To: References: MIME-Version: 1.0 Sender: git-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org test-config's main function has three different exit labels, all of which have to perform the same cleanup code before returning. Unify the labels in preparation for a future patch which will increase the cleanup section. Signed-off-by: Matheus Tavares --- t/helper/test-config.c | 49 ++++++++++++++++-------------------------- 1 file changed, 19 insertions(+), 30 deletions(-) diff --git a/t/helper/test-config.c b/t/helper/test-config.c index 26d9c2ac4c..06c61d91e1 100644 --- a/t/helper/test-config.c +++ b/t/helper/test-config.c @@ -69,9 +69,12 @@ static int early_config_cb(const char *var, const char *value, void *vdata) return 0; } +#define TC_VALUE_NOT_FOUND 1 +#define TC_CONFIG_FILE_ERROR 2 + int cmd__config(int argc, const char **argv) { - int i, val; + int i, val, ret = 0; const char *v; const struct string_list *strptr; struct config_set cs; @@ -94,10 +97,9 @@ int cmd__config(int argc, const char **argv) printf("(NULL)\n"); else printf("%s\n", v); - goto exit0; } else { printf("Value not found for \"%s\"\n", argv[2]); - goto exit1; + ret = TC_VALUE_NOT_FOUND; } } else if (argc == 3 && !strcmp(argv[1], "get_value_multi")) { strptr = git_config_get_value_multi(argv[2]); @@ -109,41 +111,38 @@ int cmd__config(int argc, const char **argv) else printf("%s\n", v); } - goto exit0; } else { printf("Value not found for \"%s\"\n", argv[2]); - goto exit1; + ret = TC_VALUE_NOT_FOUND; } } else if (argc == 3 && !strcmp(argv[1], "get_int")) { if (!git_config_get_int(argv[2], &val)) { printf("%d\n", val); - goto exit0; } else { printf("Value not found for \"%s\"\n", argv[2]); - goto exit1; + ret = TC_VALUE_NOT_FOUND; } } else if (argc == 3 && !strcmp(argv[1], "get_bool")) { if (!git_config_get_bool(argv[2], &val)) { printf("%d\n", val); - goto exit0; } else { printf("Value not found for \"%s\"\n", argv[2]); - goto exit1; + ret = TC_VALUE_NOT_FOUND; } } else if (argc == 3 && !strcmp(argv[1], "get_string")) { if (!git_config_get_string_tmp(argv[2], &v)) { printf("%s\n", v); - goto exit0; } else { printf("Value not found for \"%s\"\n", argv[2]); - goto exit1; + ret = TC_VALUE_NOT_FOUND; } } else if (argc >= 3 && !strcmp(argv[1], "configset_get_value")) { for (i = 3; i < argc; i++) { int err; if ((err = git_configset_add_file(&cs, argv[i]))) { fprintf(stderr, "Error (%d) reading configuration file %s.\n", err, argv[i]); - goto exit2; + ret = TC_CONFIG_FILE_ERROR; + goto out; } } if (!git_configset_get_value(&cs, argv[2], &v)) { @@ -151,17 +150,17 @@ int cmd__config(int argc, const char **argv) printf("(NULL)\n"); else printf("%s\n", v); - goto exit0; } else { printf("Value not found for \"%s\"\n", argv[2]); - goto exit1; + ret = TC_VALUE_NOT_FOUND; } } else if (argc >= 3 && !strcmp(argv[1], "configset_get_value_multi")) { for (i = 3; i < argc; i++) { int err; if ((err = git_configset_add_file(&cs, argv[i]))) { fprintf(stderr, "Error (%d) reading configuration file %s.\n", err, argv[i]); - goto exit2; + ret = TC_CONFIG_FILE_ERROR; + goto out; } } strptr = git_configset_get_value_multi(&cs, argv[2]); @@ -173,27 +172,17 @@ int cmd__config(int argc, const char **argv) else printf("%s\n", v); } - goto exit0; } else { printf("Value not found for \"%s\"\n", argv[2]); - goto exit1; + ret = TC_VALUE_NOT_FOUND; } } else if (!strcmp(argv[1], "iterate")) { git_config(iterate_cb, NULL); - goto exit0; + } else { + die("%s: Please check the syntax and the function name", argv[0]); } - die("%s: Please check the syntax and the function name", argv[0]); - -exit0: - git_configset_clear(&cs); - return 0; - -exit1: - git_configset_clear(&cs); - return 1; - -exit2: +out: git_configset_clear(&cs); - return 2; + return ret; } From patchwork Thu Sep 10 17:21:25 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matheus Tavares X-Patchwork-Id: 11768267 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 6996092C for ; Thu, 10 Sep 2020 17:24:42 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 37EAA208E4 for ; Thu, 10 Sep 2020 17:24:42 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=usp-br.20150623.gappssmtp.com header.i=@usp-br.20150623.gappssmtp.com header.b="VD1G7X0p" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1725372AbgIJRYL (ORCPT ); Thu, 10 Sep 2020 13:24:11 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:55020 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726780AbgIJRWK (ORCPT ); Thu, 10 Sep 2020 13:22:10 -0400 Received: from mail-qv1-xf42.google.com (mail-qv1-xf42.google.com [IPv6:2607:f8b0:4864:20::f42]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 25050C061798 for ; Thu, 10 Sep 2020 10:22:01 -0700 (PDT) Received: by mail-qv1-xf42.google.com with SMTP id di5so3703198qvb.13 for ; Thu, 10 Sep 2020 10:22:01 -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=oayVrQH3pQ2cdsPw+ZgD1w3Ks4FQKxxK6EmlqvxzQZo=; b=VD1G7X0pY3LLlvUTfhYkCjSNQXHWF3h+Zl1Ed3W2hLV+UmwCpwA3mloyx1aQ3OvUfe 4wQ5M483sW8Kmm+6Ae+AUVtF7tDUfM096x4HgDjEO5fQdEONb0xu3sOBJPmTQvw0UJ+z GlgCRAC7Jzw7mDhshYGQ3PuNGTRJs8gZ76sxBIHcVRo27QS9agNDu/4XNrZnhY7OG3/Y zqlhi0GUgCc6m5dgYzBo8BH02SsoDe3nLaT7uh3Jp0nMyOnv5utbxIgUiFWWsHeWxgsM g15TovSFUiYuQXfcoJmggqlr4axNresXGUGs2qpfFJfynzmxpQXvyCV+c/0HznTkHOMo fEjg== 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=oayVrQH3pQ2cdsPw+ZgD1w3Ks4FQKxxK6EmlqvxzQZo=; b=nPwtNhpVQoJN90V41q6R8IjSZGbfesgDsxc4CvUBIcZAmQnEK/KZ4ywE+6oI63gaxJ cJY/HUV9TFXXysCuB2GjRG3PQBGEdnCSYBjqKZ0DU6ete7ZQm1qwI2kgBA49DVlDWrQZ cJNQa5kSMvLHXxe+jgaidUTygoYrSXZIhk1cIDQr9I1ri/CnBnrKQzf9edzyL3iUHi9r gEbj+Ik4mj0BlS1P2bG40jVrQ2hD8mwpkFyzMmhKrKfHDxvsFun8Tk8J44bLTXaFcLvq nQnmkZre4vbOXonHWq9Gb81FscYl3sRGWi749Q2XewnYoQwsSBPVnVST/gAIB0U+z3t3 q2Hw== X-Gm-Message-State: AOAM532hAT0ZbVmYA4WgztDw5m7wHiFFmmI2OEE394X5nD5cn1k4xkCs Bbj5C9GDTHteARHx/Lid0oiaOrIKRVZGkA== X-Google-Smtp-Source: ABdhPJwxsPZI4DQ0ej0eNRNFnDqflPbGj3UeR4Og/J45Z3ag90vCWus9xNfBFhGSKD9I45pphUbyXg== X-Received: by 2002:a0c:b64f:: with SMTP id q15mr1764323qvf.27.1599758518889; Thu, 10 Sep 2020 10:21:58 -0700 (PDT) Received: from localhost.localdomain ([2804:14c:81:83eb::1001]) by smtp.gmail.com with ESMTPSA id h18sm7037437qkl.12.2020.09.10.10.21.56 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 10 Sep 2020 10:21:58 -0700 (PDT) From: Matheus Tavares To: git@vger.kernel.org Cc: gitster@pobox.com, stolee@gmail.com, newren@gmail.com, jonathantanmy@google.com, jrnieder@gmail.com, sunshine@sunshineco.com Subject: [PATCH v6 6/9] config: make do_git_config_sequence receive a 'struct repository' Date: Thu, 10 Sep 2020 14:21:25 -0300 Message-Id: X-Mailer: git-send-email 2.28.0 In-Reply-To: References: MIME-Version: 1.0 Sender: git-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Jonathan Nieder The following patch will fix a bug in do_git_config_sequence, which makes it ignore worktree-specific configurations on submodules when the_repository represents the superproject. To do so, the function will need access to the 'struct repository' instance of the submodule. But it currently only receives the 'git_dir' and 'commondir' paths through 'struct config_options'. So change the struct to hold a repository pointer instead of the two strings, and adjust its users. Signed-off-by: Jonathan Nieder Signed-off-by: Matheus Tavares --- Hi, Jonathan. I just made a small change in this patch, in read_early_repo(): when running some test cases in t0001, I noticed that `the_early_repo.settings.initialized` was 0 even though the repo was populated. So I added a flag to track the repo state for the later cleanup. builtin/config.c | 6 ++---- config.c | 35 +++++++++++++++++++++-------------- config.h | 4 ++-- 3 files changed, 25 insertions(+), 20 deletions(-) diff --git a/builtin/config.c b/builtin/config.c index 5e39f61885..ca4caedf33 100644 --- a/builtin/config.c +++ b/builtin/config.c @@ -699,10 +699,8 @@ int cmd_config(int argc, const char **argv, const char *prefix) config_options.respect_includes = !given_config_source.file; else config_options.respect_includes = respect_includes_opt; - if (!nongit) { - config_options.commondir = get_git_common_dir(); - config_options.git_dir = get_git_dir(); - } + if (!nongit) + config_options.repo = the_repository; if (end_nul) { term = '\0'; diff --git a/config.c b/config.c index 2bdff4457b..97f3022c92 100644 --- a/config.c +++ b/config.c @@ -222,8 +222,8 @@ static int include_by_gitdir(const struct config_options *opts, const char *git_dir; int already_tried_absolute = 0; - if (opts->git_dir) - git_dir = opts->git_dir; + if (opts->repo && opts->repo->gitdir) + git_dir = opts->repo->gitdir; else goto done; @@ -1720,10 +1720,10 @@ static int do_git_config_sequence(const struct config_options *opts, char *repo_config; enum config_scope prev_parsing_scope = current_parsing_scope; - if (opts->commondir) - repo_config = mkpathdup("%s/config", opts->commondir); - else if (opts->git_dir) - BUG("git_dir without commondir"); + if (opts->repo && opts->repo->commondir) + repo_config = mkpathdup("%s/config", opts->repo->commondir); + else if (opts->repo && opts->repo->gitdir) + BUG("gitdir without commondir"); else repo_config = NULL; @@ -1824,27 +1824,35 @@ void read_early_config(config_fn_t cb, void *data) struct config_options opts = {0}; struct strbuf commondir = STRBUF_INIT; struct strbuf gitdir = STRBUF_INIT; + struct repository the_early_repo = {0}; + int early_repo_initialized = 0; opts.respect_includes = 1; if (have_git_dir()) { - opts.commondir = get_git_common_dir(); - opts.git_dir = get_git_dir(); + opts.repo = the_repository; /* * When setup_git_directory() was not yet asked to discover the * GIT_DIR, we ask discover_git_directory() to figure out whether there * is any repository config we should use (but unlike - * setup_git_directory_gently(), no global state is changed, most + * setup_git_directory_gently(), no global state is changed; most * notably, the current working directory is still the same after the * call). + * + * NEEDSWORK: There is some duplicate work between + * discover_git_directory and repo_init. Update to use a variant of + * repo_init that does its own repository discovery once available. */ - } else if (!discover_git_directory(&commondir, &gitdir)) { - opts.commondir = commondir.buf; - opts.git_dir = gitdir.buf; + } else if (!discover_git_directory(&commondir, &gitdir) && + !repo_init(&the_early_repo, gitdir.buf, NULL)) { + opts.repo = &the_early_repo; + early_repo_initialized = 1; } config_with_options(cb, data, NULL, &opts); + if (early_repo_initialized) + repo_clear(&the_early_repo); strbuf_release(&commondir); strbuf_release(&gitdir); } @@ -2097,8 +2105,7 @@ static void repo_read_config(struct repository *repo) struct config_options opts = { 0 }; opts.respect_includes = 1; - opts.commondir = repo->commondir; - opts.git_dir = repo->gitdir; + opts.repo = repo; if (!repo->config) repo->config = xcalloc(1, sizeof(struct config_set)); diff --git a/config.h b/config.h index 91cdfbfb41..e56293fb29 100644 --- a/config.h +++ b/config.h @@ -21,6 +21,7 @@ */ struct object_id; +struct repository; /* git_config_parse_key() returns these negated: */ #define CONFIG_INVALID_KEY 1 @@ -87,8 +88,7 @@ struct config_options { unsigned int ignore_worktree : 1; unsigned int ignore_cmdline : 1; unsigned int system_gently : 1; - const char *commondir; - const char *git_dir; + struct repository *repo; config_parser_event_fn_t event_fn; void *event_fn_data; enum config_error_action { From patchwork Thu Sep 10 17:21:26 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matheus Tavares X-Patchwork-Id: 11768259 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 72B9413B1 for ; Thu, 10 Sep 2020 17:23:33 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 4335F208E4 for ; Thu, 10 Sep 2020 17:23:33 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=usp-br.20150623.gappssmtp.com header.i=@usp-br.20150623.gappssmtp.com header.b="ti2ZVogD" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726901AbgIJRXZ (ORCPT ); Thu, 10 Sep 2020 13:23:25 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:55046 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726443AbgIJRWQ (ORCPT ); Thu, 10 Sep 2020 13:22:16 -0400 Received: from mail-qt1-x82b.google.com (mail-qt1-x82b.google.com [IPv6:2607:f8b0:4864:20::82b]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6EA24C06179A for ; Thu, 10 Sep 2020 10:22:03 -0700 (PDT) Received: by mail-qt1-x82b.google.com with SMTP id z2so5427213qtv.12 for ; Thu, 10 Sep 2020 10:22:03 -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=LOCt51zmKkQrR3v2gSQ+dAA0ex5Syp9OrbTF/GUegME=; b=ti2ZVogD5ucNE9HR9wTlg6zW5U8J9BpCl+Qgi52Gw6DxG1kJ0TXW3KTvb3jJ9bYRJM I3278izUjBEAH4ESSWg/UQQ+xBbf+3xO8it/w50hYPONZL2E5ryPnm2wqy9a4/hDmgX7 pOTvhltVsydMEBGVfpB/OTBUC8F5YSa5ZvjxDbydvUoIihawnnQYCNVN+lQ2PGX3UlWB nGyIcbZDHdMxcaa/LQqa7R/GT6MGFjAV+qeiT/BC/4foju762BMh1rE04AX4oAAU+kDh E4RVoaRhmKnewb2qathAw2LZIY0C1r9vs3pDDi3L68OazS2/umLPGkmnd1CGREo6Qm7X tRNg== 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=LOCt51zmKkQrR3v2gSQ+dAA0ex5Syp9OrbTF/GUegME=; b=uewCcq/uyIYQuvD/jCUeHL79HqenKKcRjP+6KvWCv2I7Rx8GaoTUDRoq4pFhpN4Pk6 KhoPGAHYwxVRlqMFuP4AHTrWWqXY76O/WpSYHGgbu+GOcZICroEQYRENcZDSp3YBbTke XeRJiJmsoqbDnio2Tt6eK39qN4RwQh9hr3aXM9R5CVApZqp47YvPhsYastUn495cN7NA 9VwLXvBzOJYdiFXAib/OFx9gW9/6b1vLH/Y86vFY86V6nrcjz3vdgHeRXWEkT3CmYUCX 2fb8TPNOkQzbz9YBAU1N5OzgzNv8elYpCcEDkeJjZrWiDwsNomJGNaV7fKV/sn54UOC+ ItHg== X-Gm-Message-State: AOAM532T7j17DFbzWuiiF4saSZRT0D772snEnaokAm5VH6xifiCxKgHl /cpJAwRyZz1Dxt3UyTZsy65QI/O0uRRAfQ== X-Google-Smtp-Source: ABdhPJwmCDMZFw8yphIHj76VYlq5D0nwBUX0WymKg10UJ1biR+F6GRV5+X3WjF4HHEoeRiIS4OUEpg== X-Received: by 2002:ac8:310c:: with SMTP id g12mr8970527qtb.281.1599758522030; Thu, 10 Sep 2020 10:22:02 -0700 (PDT) Received: from localhost.localdomain ([2804:14c:81:83eb::1001]) by smtp.gmail.com with ESMTPSA id h18sm7037437qkl.12.2020.09.10.10.21.59 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 10 Sep 2020 10:22:01 -0700 (PDT) From: Matheus Tavares To: git@vger.kernel.org Cc: gitster@pobox.com, stolee@gmail.com, newren@gmail.com, jonathantanmy@google.com, jrnieder@gmail.com, sunshine@sunshineco.com Subject: [PATCH v6 7/9] config: correctly read worktree configs in submodules Date: Thu, 10 Sep 2020 14:21:26 -0300 Message-Id: <3a28b8e608c727d0e184fadf34ba4113933517c5.1599758167.git.matheus.bernardino@usp.br> X-Mailer: git-send-email 2.28.0 In-Reply-To: References: MIME-Version: 1.0 Sender: git-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org The config machinery is not able to read worktree configs from a submodule in a process where the_repository represents the superproject and extensions.worktreeConfig is not set there. Furthermore, when extensions.worktreeConfig is set on the superproject, querying for a worktree config in a submodule will, instead, return the value set at the superproject. The relevant code is in do_git_config_sequence(). Although it is designed to act on an arbitrary repository, specified in the passed-in `struct config_options`, it accidentally depends on the_repository in two places: - it reads the global variable `repository_format_worktree_config`, which is set based on the content of the_repository, to determine whether extensions.worktreeConfig is set. - it uses the git_pathdup() helper to find the config.worktree file, instead of making a path using the passed-in repository. Sever these dependencies and add a regression test. Also, to avoid future misuses of `repository_format_worktree_config` like this one, remove this global variable and store the config value on `struct repository` itself. Signed-off-by: Matheus Tavares --- builtin/config.c | 2 +- cache.h | 1 - config.c | 12 +++++--- environment.c | 1 - repository.c | 1 + repository.h | 1 + setup.c | 4 +-- t/helper/test-config.c | 62 ++++++++++++++++++++++++++++++++------ t/t2404-worktree-config.sh | 16 ++++++++++ 9 files changed, 81 insertions(+), 19 deletions(-) diff --git a/builtin/config.c b/builtin/config.c index ca4caedf33..586faad359 100644 --- a/builtin/config.c +++ b/builtin/config.c @@ -673,7 +673,7 @@ int cmd_config(int argc, const char **argv, const char *prefix) given_config_source.scope = CONFIG_SCOPE_LOCAL; } else if (use_worktree_config) { struct worktree **worktrees = get_worktrees(); - if (repository_format_worktree_config) + if (!nongit && the_repository->worktree_config_extension) given_config_source.file = git_pathdup("config.worktree"); else if (worktrees[0] && worktrees[1]) die(_("--worktree cannot be used with multiple " diff --git a/cache.h b/cache.h index 4cad61ffa4..4cdce7b68f 100644 --- a/cache.h +++ b/cache.h @@ -1029,7 +1029,6 @@ extern int grafts_replace_parents; #define GIT_REPO_VERSION 0 #define GIT_REPO_VERSION_READ 1 extern int repository_format_precious_objects; -extern int repository_format_worktree_config; /* * You _have_ to initialize a `struct repository_format` using diff --git a/config.c b/config.c index 97f3022c92..38c177d1e5 100644 --- a/config.c +++ b/config.c @@ -1747,11 +1747,13 @@ static int do_git_config_sequence(const struct config_options *opts, ret += git_config_from_file(fn, repo_config, data); current_parsing_scope = CONFIG_SCOPE_WORKTREE; - if (!opts->ignore_worktree && repository_format_worktree_config) { - char *path = git_pathdup("config.worktree"); - if (!access_or_die(path, R_OK, 0)) - ret += git_config_from_file(fn, path, data); - free(path); + if (!opts->ignore_worktree && opts->repo && opts->repo->gitdir && + opts->repo->worktree_config_extension) { + struct strbuf path = STRBUF_INIT; + strbuf_repo_git_path(&path, opts->repo, "config.worktree"); + if (!access_or_die(path.buf, R_OK, 0)) + ret += git_config_from_file(fn, path.buf, data); + strbuf_release(&path); } current_parsing_scope = CONFIG_SCOPE_COMMAND; diff --git a/environment.c b/environment.c index bb518c61cd..5bfb8cf9c2 100644 --- a/environment.c +++ b/environment.c @@ -32,7 +32,6 @@ int warn_ambiguous_refs = 1; int warn_on_object_refname_ambiguity = 1; int ref_paranoia = -1; int repository_format_precious_objects; -int repository_format_worktree_config; const char *git_commit_encoding; const char *git_log_output_encoding; char *apply_default_whitespace; diff --git a/repository.c b/repository.c index a4174ddb06..8d18d9d3f2 100644 --- a/repository.c +++ b/repository.c @@ -170,6 +170,7 @@ int repo_init(struct repository *repo, goto error; repo_set_hash_algo(repo, format.hash_algo); + repo->worktree_config_extension = format.worktree_config; if (worktree) repo_set_worktree(repo, worktree); diff --git a/repository.h b/repository.h index 3c1f7d54bd..3d060bc3e6 100644 --- a/repository.h +++ b/repository.h @@ -136,6 +136,7 @@ struct repository { /* Indicate if a repository has a different 'commondir' from 'gitdir' */ unsigned different_commondir:1; + unsigned worktree_config_extension:1; }; extern struct repository *the_repository; diff --git a/setup.c b/setup.c index c04cd25a30..73cd42dbbe 100644 --- a/setup.c +++ b/setup.c @@ -567,11 +567,11 @@ static int check_repository_format_gently(const char *gitdir, struct repository_ repository_format_precious_objects = candidate->precious_objects; set_repository_format_partial_clone(candidate->partial_clone); - repository_format_worktree_config = candidate->worktree_config; + the_repository->worktree_config_extension = candidate->worktree_config; string_list_clear(&candidate->unknown_extensions, 0); string_list_clear(&candidate->v1_only_extensions, 0); - if (repository_format_worktree_config) { + if (the_repository->worktree_config_extension) { /* * pick up core.bare and core.worktree from per-worktree * config if present diff --git a/t/helper/test-config.c b/t/helper/test-config.c index 06c61d91e1..87488aab6b 100644 --- a/t/helper/test-config.c +++ b/t/helper/test-config.c @@ -2,12 +2,20 @@ #include "cache.h" #include "config.h" #include "string-list.h" +#include "submodule-config.h" +#include "parse-options.h" /* * This program exposes the C API of the configuration mechanism * as a set of simple commands in order to facilitate testing. * - * Reads stdin and prints result of command to stdout: + * Usage: test-tool config [--submodule=] [] + * + * If --submodule= is given, will operate on the submodule at the + * given . This option is not valid for the commands: read_early_config, + * configset_get_value and configset_get_value_multi. + * + * Possible cmds are: * * get_value -> prints the value with highest priority for the entered key * @@ -72,14 +80,34 @@ static int early_config_cb(const char *var, const char *value, void *vdata) #define TC_VALUE_NOT_FOUND 1 #define TC_CONFIG_FILE_ERROR 2 +static const char *test_config_usage[] = { + "test-tool config [--submodule=] []", + NULL +}; + int cmd__config(int argc, const char **argv) { int i, val, ret = 0; const char *v; const struct string_list *strptr; struct config_set cs; + struct repository subrepo, *repo = the_repository; + const char *subrepo_path = NULL; + + struct option options[] = { + OPT_STRING(0, "submodule", &subrepo_path, "path", + "run on the submodule at "), + OPT_END() + }; + + argc = parse_options(argc, argv, NULL, options, test_config_usage, + PARSE_OPT_KEEP_ARGV0 | PARSE_OPT_STOP_AT_NON_OPTION); + if (argc < 2) + usage_with_options(test_config_usage, options); if (argc == 3 && !strcmp(argv[1], "read_early_config")) { + if (subrepo_path) + die("cannot use --submodule with read_early_config"); read_early_config(early_config_cb, (void *)argv[2]); return 0; } @@ -88,11 +116,18 @@ int cmd__config(int argc, const char **argv) git_configset_init(&cs); - if (argc < 2) - die("Please, provide a command name on the command-line"); + if (subrepo_path) { + const struct submodule *sub; + + sub = submodule_from_path(the_repository, &null_oid, subrepo_path); + if (!sub || repo_submodule_init(&subrepo, the_repository, sub)) + die("invalid argument to --submodule: '%s'", subrepo_path); + + repo = &subrepo; + } if (argc == 3 && !strcmp(argv[1], "get_value")) { - if (!git_config_get_value(argv[2], &v)) { + if (!repo_config_get_value(repo, argv[2], &v)) { if (!v) printf("(NULL)\n"); else @@ -102,7 +137,7 @@ int cmd__config(int argc, const char **argv) ret = TC_VALUE_NOT_FOUND; } } else if (argc == 3 && !strcmp(argv[1], "get_value_multi")) { - strptr = git_config_get_value_multi(argv[2]); + strptr = repo_config_get_value_multi(repo, argv[2]); if (strptr) { for (i = 0; i < strptr->nr; i++) { v = strptr->items[i].string; @@ -116,27 +151,31 @@ int cmd__config(int argc, const char **argv) ret = TC_VALUE_NOT_FOUND; } } else if (argc == 3 && !strcmp(argv[1], "get_int")) { - if (!git_config_get_int(argv[2], &val)) { + if (!repo_config_get_int(repo, argv[2], &val)) { printf("%d\n", val); } else { printf("Value not found for \"%s\"\n", argv[2]); ret = TC_VALUE_NOT_FOUND; } } else if (argc == 3 && !strcmp(argv[1], "get_bool")) { - if (!git_config_get_bool(argv[2], &val)) { + if (!repo_config_get_bool(repo, argv[2], &val)) { printf("%d\n", val); } else { + printf("Value not found for \"%s\"\n", argv[2]); ret = TC_VALUE_NOT_FOUND; } } else if (argc == 3 && !strcmp(argv[1], "get_string")) { - if (!git_config_get_string_tmp(argv[2], &v)) { + if (!repo_config_get_string_tmp(repo, argv[2], &v)) { printf("%s\n", v); } else { printf("Value not found for \"%s\"\n", argv[2]); ret = TC_VALUE_NOT_FOUND; } } else if (argc >= 3 && !strcmp(argv[1], "configset_get_value")) { + if (subrepo_path) + die("cannot use --submodule with configset_get_value"); + for (i = 3; i < argc; i++) { int err; if ((err = git_configset_add_file(&cs, argv[i]))) { @@ -155,6 +194,9 @@ int cmd__config(int argc, const char **argv) ret = TC_VALUE_NOT_FOUND; } } else if (argc >= 3 && !strcmp(argv[1], "configset_get_value_multi")) { + if (subrepo_path) + die("cannot use --submodule with configset_get_value_multi"); + for (i = 3; i < argc; i++) { int err; if ((err = git_configset_add_file(&cs, argv[i]))) { @@ -177,12 +219,14 @@ int cmd__config(int argc, const char **argv) ret = TC_VALUE_NOT_FOUND; } } else if (!strcmp(argv[1], "iterate")) { - git_config(iterate_cb, NULL); + repo_config(repo, iterate_cb, NULL); } else { die("%s: Please check the syntax and the function name", argv[0]); } out: git_configset_clear(&cs); + if (repo != the_repository) + repo_clear(repo); return ret; } diff --git a/t/t2404-worktree-config.sh b/t/t2404-worktree-config.sh index 9536d10919..1e32c93735 100755 --- a/t/t2404-worktree-config.sh +++ b/t/t2404-worktree-config.sh @@ -78,4 +78,20 @@ test_expect_success 'config.worktree no longer read without extension' ' test_cmp_config -C wt2 shared this.is ' +test_expect_success 'correctly read config.worktree from submodules' ' + test_unconfig extensions.worktreeConfig && + git init sub && + ( + cd sub && + test_commit A && + git config extensions.worktreeConfig true && + git config --worktree wtconfig.sub test-value + ) && + git submodule add ./sub && + git commit -m "add sub" && + echo test-value >expect && + test-tool config --submodule=sub get_value wtconfig.sub >actual && + test_cmp expect actual +' + test_done From patchwork Thu Sep 10 17:21:27 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matheus Tavares X-Patchwork-Id: 11768263 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id C688213B1 for ; Thu, 10 Sep 2020 17:24:00 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 97922208E4 for ; Thu, 10 Sep 2020 17:24:00 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=usp-br.20150623.gappssmtp.com header.i=@usp-br.20150623.gappssmtp.com header.b="ufffcayM" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726920AbgIJRXt (ORCPT ); Thu, 10 Sep 2020 13:23:49 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:55048 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726850AbgIJRWQ (ORCPT ); Thu, 10 Sep 2020 13:22:16 -0400 Received: from mail-qt1-x842.google.com (mail-qt1-x842.google.com [IPv6:2607:f8b0:4864:20::842]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9CF42C061573 for ; Thu, 10 Sep 2020 10:22:06 -0700 (PDT) Received: by mail-qt1-x842.google.com with SMTP id n10so5484446qtv.3 for ; Thu, 10 Sep 2020 10:22:06 -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=UF6C88903hKDDHik13yeH62wpFrYGOwCxVe0dPt1sJE=; b=ufffcayMrfUKlvFzgKAWlUA+D8iSIV4nv4SUHKftgWWw20mjfB9lkQ8azpwqV3OxFA QVHAAKebcsau3jC0wiyaQ4qVcBhfXmb+Ltu5QE2wMeQp5Y6YEQ22t5F2fg0GkhnHI409 32zbwF4+I48Ku416utNxH9XN/yXuaSVC/76w/V+bXx7HNFJTk9/+WSc+wi1RAvqB51Bd SCKWHn/aDHM6IYLInGMBi1OpLVUGnTA8jpq/6G2ZY7+gdTQ87AVUw52WwrFCLYUz28Dp Qp2PT4aeFMxjwGp/AJ8zLOHB5yd4rvphIOAxwCWj6sb3+0qY1OCK8EFcofo0rh8mRm2d 9N2w== 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=UF6C88903hKDDHik13yeH62wpFrYGOwCxVe0dPt1sJE=; b=XfnlZXIU0JZiessg1KfadOxeMNL1s9x7f19LIiW7l7mE1uOiN6XZ6SuYBvgjl4wLVA 1ti67tmE0BrSouCTYFYlojwypMr+KOcOEkDLrHbytfOuvlIL2Q5Rw0hcTCpeZv7bXXSC 8rdFA09VYzwpQPhQwMtI8DddXcC7U9Zj/7I6TWpbUc+FbA1ljyHvfrGxyiXQZcPTygFR lvYK09AgNC+k4PSaKDN23Ck8/oAyl3C9tQfVfh4pk5/ty3sS/UK9ZGYMTnU6EV9Kb3sw Nuv753k/N0B/BnC6/kbUBosD39JISrQhL7yO7u62pZVGgn/12cMRCfE1ijQCa66taFzr aXag== X-Gm-Message-State: AOAM532swTz2188ElXzn6FrgOPapgE0AfHX0LpCK7BKVT22IlKRnz/rz nO5lG3URvaJ/CWIIfe8UknZHLOfYO/FSIQ== X-Google-Smtp-Source: ABdhPJzQIw5SguU9IgDLa2ApFyazE6UjcQNwEBkO6qDCqsYG8dis91653uLDIzLf/tbiEjuIKuKurQ== X-Received: by 2002:ac8:4f4e:: with SMTP id i14mr8285667qtw.213.1599758525131; Thu, 10 Sep 2020 10:22:05 -0700 (PDT) Received: from localhost.localdomain ([2804:14c:81:83eb::1001]) by smtp.gmail.com with ESMTPSA id h18sm7037437qkl.12.2020.09.10.10.22.02 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 10 Sep 2020 10:22:04 -0700 (PDT) From: Matheus Tavares To: git@vger.kernel.org Cc: gitster@pobox.com, stolee@gmail.com, newren@gmail.com, jonathantanmy@google.com, jrnieder@gmail.com, sunshine@sunshineco.com Subject: [PATCH v6 8/9] grep: honor sparse checkout patterns Date: Thu, 10 Sep 2020 14:21:27 -0300 Message-Id: <2fc889c9c264fc10d878f31bd89cc44e79982516.1599758167.git.matheus.bernardino@usp.br> X-Mailer: git-send-email 2.28.0 In-Reply-To: References: MIME-Version: 1.0 Sender: git-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org One of the main uses for a sparse checkout is to allow users to focus on the subset of files in a repository in which they are interested. But git-grep currently ignores the sparsity patterns and reports all matches found outside this subset, which kind of goes in the opposite direction. There are some use cases for ignoring the sparsity patterns and the next commit will add an option to obtain this behavior, but here we start by making grep honor the sparsity boundaries in every case where this is relevant: - git grep in worktree - git grep --cached - git grep $REVISION For the worktree and cached cases, we iterate over paths without the SKIP_WORKTREE bit set, and limit our searches to these paths. For the $REVISION case, we limit the paths we search to those that match the sparsity patterns. (We do not check the SKIP_WORKTREE bit for the $REVISION case, because $REVISION may contain paths that do not exist in HEAD and thus for which we have no SKIP_WORKTREE bit to consult. The sparsity patterns tell us how the SKIP_WORKTREE bit would be set if we were to check out $REVISION, so we consult those. Also, we don't use the sparsity patterns with the worktree or cached cases, both because we have a bit we can check directly and more efficiently, and because unmerged entries from a merge or a rebase could cause more files to temporarily be present than the sparsity patterns would normally select.) Note that there is a special case here: `git grep $TREE`. In this case, we cannot know whether $TREE corresponds to the root of the repository or some sub-tree, and thus there is no way for us to know which sparsity patterns, if any, apply. So the $TREE case will not use sparsity patterns or any SKIP_WORKTREE bits and will instead always search all files within the $TREE. Signed-off-by: Matheus Tavares --- builtin/grep.c | 125 ++++++++++++++++++-- t/t7011-skip-worktree-reading.sh | 9 -- t/t7817-grep-sparse-checkout.sh | 195 +++++++++++++++++++++++++++++++ 3 files changed, 312 insertions(+), 17 deletions(-) create mode 100755 t/t7817-grep-sparse-checkout.sh diff --git a/builtin/grep.c b/builtin/grep.c index f58979bc3f..a32815de0a 100644 --- a/builtin/grep.c +++ b/builtin/grep.c @@ -410,7 +410,7 @@ static int grep_cache(struct grep_opt *opt, const struct pathspec *pathspec, int cached); static int grep_tree(struct grep_opt *opt, const struct pathspec *pathspec, struct tree_desc *tree, struct strbuf *base, int tn_len, - int check_attr); + int is_root_tree); static int grep_submodule(struct grep_opt *opt, const struct pathspec *pathspec, @@ -508,6 +508,10 @@ static int grep_cache(struct grep_opt *opt, for (nr = 0; nr < repo->index->cache_nr; nr++) { const struct cache_entry *ce = repo->index->cache[nr]; + + if (ce_skip_worktree(ce)) + continue; + strbuf_setlen(&name, name_base_len); strbuf_addstr(&name, ce->name); @@ -520,8 +524,7 @@ static int grep_cache(struct grep_opt *opt, * cache entry are identical, even if worktree file has * been modified, so use cache version instead */ - if (cached || (ce->ce_flags & CE_VALID) || - ce_skip_worktree(ce)) { + if (cached || (ce->ce_flags & CE_VALID)) { if (ce_stage(ce) || ce_intent_to_add(ce)) continue; hit |= grep_oid(opt, &ce->oid, name.buf, @@ -552,9 +555,76 @@ static int grep_cache(struct grep_opt *opt, return hit; } -static int grep_tree(struct grep_opt *opt, const struct pathspec *pathspec, - struct tree_desc *tree, struct strbuf *base, int tn_len, - int check_attr) +static struct pattern_list *get_sparsity_patterns(struct repository *repo) +{ + struct pattern_list *patterns; + char *sparse_file; + int sparse_config, cone_config; + + if (repo_config_get_bool(repo, "core.sparsecheckout", &sparse_config) || + !sparse_config) { + return NULL; + } + + sparse_file = repo_git_path(repo, "info/sparse-checkout"); + patterns = xcalloc(1, sizeof(*patterns)); + + if (repo_config_get_bool(repo, "core.sparsecheckoutcone", &cone_config)) + cone_config = 0; + patterns->use_cone_patterns = cone_config; + + if (add_patterns_from_file_to_list(sparse_file, "", 0, patterns, NULL)) { + if (file_exists(sparse_file)) { + warning(_("failed to load sparse-checkout file: '%s'"), + sparse_file); + } + free(sparse_file); + free(patterns); + return NULL; + } + + free(sparse_file); + return patterns; +} + +static int path_in_sparse_checkout(struct strbuf *path, int prefix_len, + unsigned int entry_mode, + struct index_state *istate, + struct pattern_list *sparsity, + enum pattern_match_result parent_match, + enum pattern_match_result *match) +{ + int dtype = DT_UNKNOWN; + int is_dir = S_ISDIR(entry_mode); + + if (parent_match == MATCHED_RECURSIVE) { + *match = parent_match; + return 1; + } + + if (is_dir && !is_dir_sep(path->buf[path->len - 1])) + strbuf_addch(path, '/'); + + *match = path_matches_pattern_list(path->buf, path->len, + path->buf + prefix_len, &dtype, + sparsity, istate); + if (*match == UNDECIDED) + *match = parent_match; + + if (is_dir) + strbuf_trim_trailing_dir_sep(path); + + if (*match == NOT_MATCHED && + (!is_dir || (is_dir && sparsity->use_cone_patterns))) + return 0; + + return 1; +} + +static int do_grep_tree(struct grep_opt *opt, const struct pathspec *pathspec, + struct tree_desc *tree, struct strbuf *base, int tn_len, + int check_attr, struct pattern_list *sparsity, + enum pattern_match_result default_sparsity_match) { struct repository *repo = opt->repo; int hit = 0; @@ -570,6 +640,7 @@ static int grep_tree(struct grep_opt *opt, const struct pathspec *pathspec, while (tree_entry(tree, &entry)) { int te_len = tree_entry_len(&entry); + enum pattern_match_result sparsity_match = 0; if (match != all_entries_interesting) { strbuf_addstr(&name, base->buf + tn_len); @@ -586,6 +657,19 @@ static int grep_tree(struct grep_opt *opt, const struct pathspec *pathspec, strbuf_add(base, entry.path, te_len); + if (sparsity) { + struct strbuf path = STRBUF_INIT; + strbuf_addstr(&path, base->buf + tn_len); + + if (!path_in_sparse_checkout(&path, old_baselen - tn_len, + entry.mode, repo->index, + sparsity, default_sparsity_match, + &sparsity_match)) { + strbuf_setlen(base, old_baselen); + continue; + } + } + if (S_ISREG(entry.mode)) { hit |= grep_oid(opt, &entry.oid, base->buf, tn_len, check_attr ? base->buf + tn_len : NULL); @@ -602,8 +686,8 @@ static int grep_tree(struct grep_opt *opt, const struct pathspec *pathspec, strbuf_addch(base, '/'); init_tree_desc(&sub, data, size); - hit |= grep_tree(opt, pathspec, &sub, base, tn_len, - check_attr); + hit |= do_grep_tree(opt, pathspec, &sub, base, tn_len, + check_attr, sparsity, sparsity_match); free(data); } else if (recurse_submodules && S_ISGITLINK(entry.mode)) { hit |= grep_submodule(opt, pathspec, &entry.oid, @@ -621,6 +705,31 @@ static int grep_tree(struct grep_opt *opt, const struct pathspec *pathspec, return hit; } +/* + * Note: sparsity patterns and paths' attributes will only be considered if + * is_root_tree has true value. (Otherwise, we cannot properly perform pattern + * matching on paths.) + */ +static int grep_tree(struct grep_opt *opt, const struct pathspec *pathspec, + struct tree_desc *tree, struct strbuf *base, int tn_len, + int is_root_tree) +{ + struct pattern_list *patterns = NULL; + int ret; + + if (is_root_tree) + patterns = get_sparsity_patterns(opt->repo); + + ret = do_grep_tree(opt, pathspec, tree, base, tn_len, is_root_tree, + patterns, 0); + + if (patterns) { + clear_pattern_list(patterns); + free(patterns); + } + return ret; +} + static int grep_object(struct grep_opt *opt, const struct pathspec *pathspec, struct object *obj, const char *name, const char *path) { diff --git a/t/t7011-skip-worktree-reading.sh b/t/t7011-skip-worktree-reading.sh index 37525cae3a..26852586ac 100755 --- a/t/t7011-skip-worktree-reading.sh +++ b/t/t7011-skip-worktree-reading.sh @@ -109,15 +109,6 @@ test_expect_success 'ls-files --modified' ' test -z "$(git ls-files -m)" ' -test_expect_success 'grep with skip-worktree file' ' - git update-index --no-skip-worktree 1 && - echo test > 1 && - git update-index 1 && - git update-index --skip-worktree 1 && - rm 1 && - test "$(git grep --no-ext-grep test)" = "1:test" -' - echo ":000000 100644 $ZERO_OID $EMPTY_BLOB A 1" > expected test_expect_success 'diff-index does not examine skip-worktree absent entries' ' setup_absent && diff --git a/t/t7817-grep-sparse-checkout.sh b/t/t7817-grep-sparse-checkout.sh new file mode 100755 index 0000000000..b3109e3479 --- /dev/null +++ b/t/t7817-grep-sparse-checkout.sh @@ -0,0 +1,195 @@ +#!/bin/sh + +test_description='grep in sparse checkout + +This test creates a repo with the following structure: + +. +|-- a +|-- b +|-- dir +| `-- c +|-- sub +| |-- A +| | `-- a +| `-- B +| `-- b +`-- sub2 + `-- a + +Where the outer repository has non-cone mode sparsity patterns, sub is a +submodule with cone mode sparsity patterns and sub2 is a submodule that is +excluded by the superproject sparsity patterns. The resulting sparse checkout +should leave the following structure in the working tree: + +. +|-- a +|-- sub +| `-- B +| `-- b +`-- sub2 + `-- a + +But note that sub2 should have the SKIP_WORKTREE bit set. +' + +. ./test-lib.sh + +test_expect_success 'setup' ' + echo "text" >a && + echo "text" >b && + mkdir dir && + echo "text" >dir/c && + + git init sub && + ( + cd sub && + mkdir A B && + echo "text" >A/a && + echo "text" >B/b && + git add A B && + git commit -m sub && + git sparse-checkout init --cone && + git sparse-checkout set B + ) && + + git init sub2 && + ( + cd sub2 && + echo "text" >a && + git add a && + git commit -m sub2 + ) && + + git submodule add ./sub && + git submodule add ./sub2 && + git add a b dir && + git commit -m super && + git sparse-checkout init --no-cone && + git sparse-checkout set "/*" "!b" "!/*/" "sub" && + + git tag -am tag-to-commit tag-to-commit HEAD && + tree=$(git rev-parse HEAD^{tree}) && + git tag -am tag-to-tree tag-to-tree $tree && + + test_path_is_missing b && + test_path_is_missing dir && + test_path_is_missing sub/A && + test_path_is_file a && + test_path_is_file sub/B/b && + test_path_is_file sub2/a +' + +# The test below checks a special case: the sparsity patterns exclude '/b' +# and sparse checkout is enabled, but the path exists in the working tree (e.g. +# manually created after `git sparse-checkout init`). In this case, grep should +# skip it. +test_expect_success 'grep in working tree should honor sparse checkout' ' + cat >expect <<-EOF && + a:text + EOF + echo "new-text" >b && + test_when_finished "rm b" && + git grep "text" >actual && + test_cmp expect actual +' + +test_expect_success 'grep unmerged file despite not matching sparsity patterns' ' + cat >expect <<-EOF && + b:modified-b-in-branchX + b:modified-b-in-branchY + EOF + test_when_finished "test_might_fail git merge --abort && \ + git checkout master" && + + git sparse-checkout disable && + git checkout -b branchY master && + test_commit modified-b-in-branchY b && + git checkout -b branchX master && + test_commit modified-b-in-branchX b && + + git sparse-checkout init && + test_path_is_missing b && + test_must_fail git merge branchY && + git grep "modified-b" >actual && + test_cmp expect actual +' + +test_expect_success 'grep --cached should honor sparse checkout' ' + cat >expect <<-EOF && + a:text + EOF + git grep --cached "text" >actual && + test_cmp expect actual +' + +test_expect_success 'grep should honor sparse checkout' ' + commit=$(git rev-parse HEAD) && + cat >expect_commit <<-EOF && + $commit:a:text + EOF + cat >expect_tag-to-commit <<-EOF && + tag-to-commit:a:text + EOF + git grep "text" $commit >actual_commit && + test_cmp expect_commit actual_commit && + git grep "text" tag-to-commit >actual_tag-to-commit && + test_cmp expect_tag-to-commit actual_tag-to-commit +' + +test_expect_success 'grep should ignore sparsity patterns' ' + commit=$(git rev-parse HEAD) && + tree=$(git rev-parse HEAD^{tree}) && + cat >expect_tree <<-EOF && + $tree:a:text + $tree:b:text + $tree:dir/c:text + EOF + cat >expect_tag-to-tree <<-EOF && + tag-to-tree:a:text + tag-to-tree:b:text + tag-to-tree:dir/c:text + EOF + git grep "text" $tree >actual_tree && + test_cmp expect_tree actual_tree && + git grep "text" tag-to-tree >actual_tag-to-tree && + test_cmp expect_tag-to-tree actual_tag-to-tree +' + +# Note that sub2/ is present in the worktree but it is excluded by the sparsity +# patterns, so grep should not recurse into it. +test_expect_success 'grep --recurse-submodules should honor sparse checkout in submodule' ' + cat >expect <<-EOF && + a:text + sub/B/b:text + EOF + git grep --recurse-submodules "text" >actual && + test_cmp expect actual +' + +test_expect_success 'grep --recurse-submodules --cached should honor sparse checkout in submodule' ' + cat >expect <<-EOF && + a:text + sub/B/b:text + EOF + git grep --recurse-submodules --cached "text" >actual && + test_cmp expect actual +' + +test_expect_success 'grep --recurse-submodules should honor sparse checkout in submodule' ' + commit=$(git rev-parse HEAD) && + cat >expect_commit <<-EOF && + $commit:a:text + $commit:sub/B/b:text + EOF + cat >expect_tag-to-commit <<-EOF && + tag-to-commit:a:text + tag-to-commit:sub/B/b:text + EOF + git grep --recurse-submodules "text" $commit >actual_commit && + test_cmp expect_commit actual_commit && + git grep --recurse-submodules "text" tag-to-commit >actual_tag-to-commit && + test_cmp expect_tag-to-commit actual_tag-to-commit +' + +test_done From patchwork Thu Sep 10 17:21:28 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matheus Tavares X-Patchwork-Id: 11768265 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id DE52B92C for ; Thu, 10 Sep 2020 17:24:08 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id AEE7E208E4 for ; Thu, 10 Sep 2020 17:24:08 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=usp-br.20150623.gappssmtp.com header.i=@usp-br.20150623.gappssmtp.com header.b="CXo2Q21I" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1725820AbgIJRYD (ORCPT ); Thu, 10 Sep 2020 13:24:03 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:55060 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726384AbgIJRWV (ORCPT ); Thu, 10 Sep 2020 13:22:21 -0400 Received: from mail-qt1-x842.google.com (mail-qt1-x842.google.com [IPv6:2607:f8b0:4864:20::842]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8EBBFC06179B for ; Thu, 10 Sep 2020 10:22:09 -0700 (PDT) Received: by mail-qt1-x842.google.com with SMTP id z2so5427466qtv.12 for ; Thu, 10 Sep 2020 10:22:09 -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=wql2jSbmB/wKgLMAMdl4Eiy44fK9XQwDEfPhW74A0uA=; b=CXo2Q21I9CBIqfHtp4uX4HM/RNHCUlPE/NrMLApeL9PrV+JTnhNBQc5CdGhHG3Fwqn wjEEaXlPhey05kadu5FY05AhsTUxc+iItWOHxE3jNqrFUhdgX070m+3cDPzgohxBlgeo +aXTIDWpkfmxyTYwZc8VpWakDOAUk+0dXRombAeAAgNPAOk7Fkh7P0yfmtWFf+6UDoaa lr9AePsRnBfdGp6AZmlHCW2JiOMQUJ6JD++dEr/pl1sZHjeSRYbjClSp+Rx7HC7d3W0V Uku++GsMpYWgyr44ajalrX4YWFQM3/4fUok4bHKmfj1gwnBbDTlTYRVgYTmSCF22DeWx Hzww== 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=wql2jSbmB/wKgLMAMdl4Eiy44fK9XQwDEfPhW74A0uA=; b=uh1BE1vmTTUkflK+x/+7VgdWDexBaPeEe/hQqQEqS8YM9Oxnl3zKAYutVk+PfidlAU 81kG7YnmDd727jui8XQKaSg1RcXbOaSuWQw6TDRhOi+RpBKOSzR80DaDGTU1wCfP+/ka OsocMqV979LU/bgLu5jYNTSg4VUBUSk+JcYNjn8Rc0u3R0LsxKtFiFWsvQhkxZ03lAOy X+wnZmwh/dc2uts4AAPy+jDpRB4Lq6o3STY9447UHMgBF3DUZNpeJ0o2ZfuQwkqUedHx YnrZIdfXmDp0eStx9il1+ZpMdgqVUhLEDWbqMIuIyga4gD74Iq5yKZyZCH/jMNpyZC55 3Ahg== X-Gm-Message-State: AOAM533+n2DBOlpY1eoThvfz55q6pkXsCNWn7bmXfMrZ4CG1goc29kZj IrYstjaYbsUMcjfDVIbyfJR9w0IkQKQ0bA== X-Google-Smtp-Source: ABdhPJwZO7XyaFAZAFJWm9IsXaQ3RntQG/c9ppEoIvcKj7YHNHo/QwBW5lDo8/LUOzDA3TRVlrg1Lg== X-Received: by 2002:ac8:4059:: with SMTP id j25mr8944474qtl.155.1599758528031; Thu, 10 Sep 2020 10:22:08 -0700 (PDT) Received: from localhost.localdomain ([2804:14c:81:83eb::1001]) by smtp.gmail.com with ESMTPSA id h18sm7037437qkl.12.2020.09.10.10.22.05 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 10 Sep 2020 10:22:07 -0700 (PDT) From: Matheus Tavares To: git@vger.kernel.org Cc: gitster@pobox.com, stolee@gmail.com, newren@gmail.com, jonathantanmy@google.com, jrnieder@gmail.com, sunshine@sunshineco.com Subject: [PATCH v6 9/9] config: add setting to ignore sparsity patterns in some cmds Date: Thu, 10 Sep 2020 14:21:28 -0300 Message-Id: <92bc5351cf5fdbf7435ba4d99530d6ce02f957c4.1599758167.git.matheus.bernardino@usp.br> X-Mailer: git-send-email 2.28.0 In-Reply-To: References: MIME-Version: 1.0 Sender: git-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org When sparse checkout is enabled, some users expect the output of certain commands (such as grep, diff, and log) to be also restricted within the sparsity patterns. This would allow them to effectively work only on the subset of files in which they are interested; and allow some commands to possibly perform better, by not considering uninteresting paths. For this reason, we taught grep to honor the sparsity patterns, in the previous patch. But, on the other hand, allowing grep and the other commands mentioned to optionally ignore the patterns also make for some interesting use cases. E.g. using grep to search for a function documentation that resides outside the sparse checkout. In any case, there is no current way for users to configure the behavior they want for these commands. Aiming to provide this flexibility, let's introduce the sparse.restrictCmds setting (and the analogous --[no]-restrict-to-sparse-paths global option). The default value is true. For now, grep is the only one affected by this setting, but the goal is to have support for more commands, in the future. Helped-by: Elijah Newren Signed-off-by: Matheus Tavares --- Documentation/config.txt | 2 + Documentation/config/grep.txt | 8 ++ Documentation/config/sparse.txt | 20 ++++ Documentation/git.txt | 4 + Makefile | 1 + builtin/grep.c | 13 ++- contrib/completion/git-completion.bash | 2 + git.c | 5 + sparse-checkout.c | 18 ++++ sparse-checkout.h | 11 +++ t/t7817-grep-sparse-checkout.sh | 132 ++++++++++++++++++++++++- t/t9902-completion.sh | 4 +- 12 files changed, 214 insertions(+), 6 deletions(-) create mode 100644 Documentation/config/sparse.txt create mode 100644 sparse-checkout.c create mode 100644 sparse-checkout.h diff --git a/Documentation/config.txt b/Documentation/config.txt index 3042d80978..3b6e0901b8 100644 --- a/Documentation/config.txt +++ b/Documentation/config.txt @@ -438,6 +438,8 @@ include::config/sequencer.txt[] include::config/showbranch.txt[] +include::config/sparse.txt[] + include::config/splitindex.txt[] include::config/ssh.txt[] diff --git a/Documentation/config/grep.txt b/Documentation/config/grep.txt index dd51db38e1..a3275ab4b7 100644 --- a/Documentation/config/grep.txt +++ b/Documentation/config/grep.txt @@ -28,3 +28,11 @@ grep.fullName:: grep.fallbackToNoIndex:: If set to true, fall back to git grep --no-index if git grep is executed outside of a git repository. Defaults to false. + +ifdef::git-grep[] +sparse.restrictCmds:: + See base definition in linkgit:git-config[1]. grep honors + sparse.restrictCmds by limiting searches to the sparsity paths in three + cases: when searching the working tree, when searching the index with + --cached, and when searching a specified commit. +endif::git-grep[] diff --git a/Documentation/config/sparse.txt b/Documentation/config/sparse.txt new file mode 100644 index 0000000000..494761526e --- /dev/null +++ b/Documentation/config/sparse.txt @@ -0,0 +1,20 @@ +sparse.restrictCmds:: + Only meaningful in conjunction with core.sparseCheckout. This option + extends sparse checkouts (which limit which paths are written to the + working tree), so that output and operations are also limited to the + sparsity paths where possible and implemented. The purpose of this + option is to (1) focus output for the user on the portion of the + repository that is of interest to them, and (2) enable potentially + dramatic performance improvements, especially in conjunction with + partial clones. ++ +When this option is true (default), some git commands may limit their behavior +to the paths specified by the sparsity patterns, or to the intersection of +those paths and any (like `*.c`) that the user might also specify on the +command line. When false, the affected commands will work on full trees, +ignoring the sparsity patterns. For now, only git-grep honors this setting. ++ +Note: commands which export, integrity check, or create history will always +operate on full trees (e.g. fast-export, format-patch, fsck, commit, etc.), +unaffected by any sparsity patterns. Also, writing commands such as +sparse-checkout and read-tree will not be affected by this configuration. diff --git a/Documentation/git.txt b/Documentation/git.txt index 2fc92586b5..d857509573 100644 --- a/Documentation/git.txt +++ b/Documentation/git.txt @@ -180,6 +180,10 @@ If you just want to run git as if it was started in `` then use Do not perform optional operations that require locks. This is equivalent to setting the `GIT_OPTIONAL_LOCKS` to `0`. +--[no-]restrict-to-sparse-paths:: + Overrides the sparse.restrictCmds configuration (see + linkgit:git-config[1]) for this execution. + --list-cmds=group[,group...]:: List commands by group. This is an internal/experimental option and may change or be removed in the future. Supported diff --git a/Makefile b/Makefile index 65f8cfb236..778c9e499e 100644 --- a/Makefile +++ b/Makefile @@ -982,6 +982,7 @@ LIB_OBJS += sha1-name.o LIB_OBJS += shallow.o LIB_OBJS += sideband.o LIB_OBJS += sigchain.o +LIB_OBJS += sparse-checkout.o LIB_OBJS += split-index.o LIB_OBJS += stable-qsort.o LIB_OBJS += strbuf.o diff --git a/builtin/grep.c b/builtin/grep.c index a32815de0a..3fa364e91c 100644 --- a/builtin/grep.c +++ b/builtin/grep.c @@ -25,6 +25,7 @@ #include "submodule-config.h" #include "object-store.h" #include "packfile.h" +#include "sparse-checkout.h" static char const * const grep_usage[] = { N_("git grep [] [-e] [...] [[--] ...]"), @@ -498,6 +499,7 @@ static int grep_cache(struct grep_opt *opt, int nr; struct strbuf name = STRBUF_INIT; int name_base_len = 0; + int sparse_paths_only = restrict_to_sparse_paths(repo); if (repo->submodule_prefix) { name_base_len = strlen(repo->submodule_prefix); strbuf_addstr(&name, repo->submodule_prefix); @@ -509,7 +511,7 @@ static int grep_cache(struct grep_opt *opt, for (nr = 0; nr < repo->index->cache_nr; nr++) { const struct cache_entry *ce = repo->index->cache[nr]; - if (ce_skip_worktree(ce)) + if (sparse_paths_only && ce_skip_worktree(ce)) continue; strbuf_setlen(&name, name_base_len); @@ -715,9 +717,10 @@ static int grep_tree(struct grep_opt *opt, const struct pathspec *pathspec, int is_root_tree) { struct pattern_list *patterns = NULL; + int sparse_paths_only = restrict_to_sparse_paths(opt->repo); int ret; - if (is_root_tree) + if (is_root_tree && sparse_paths_only) patterns = get_sparsity_patterns(opt->repo); ret = do_grep_tree(opt, pathspec, tree, base, tn_len, is_root_tree, @@ -1258,6 +1261,12 @@ int cmd_grep(int argc, const char **argv, const char *prefix) if (!use_index || untracked) { int use_exclude = (opt_exclude < 0) ? use_index : !!opt_exclude; + + if (opt_restrict_to_sparse_paths >= 0) { + die(_("--[no-]restrict-to-sparse-paths is incompatible" + " with --no-index and --untracked")); + } + hit = grep_directory(&opt, &pathspec, use_exclude, use_index); } else if (0 <= opt_exclude) { die(_("--[no-]exclude-standard cannot be used for tracked contents")); diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash index 9147fba3d5..de12766a70 100644 --- a/contrib/completion/git-completion.bash +++ b/contrib/completion/git-completion.bash @@ -3402,6 +3402,8 @@ __git_main () --namespace= --no-replace-objects --help + --restrict-to-sparse-paths + --no-restrict-to-sparse-paths " ;; *) diff --git a/git.c b/git.c index 8bd1d7551d..81206b424c 100644 --- a/git.c +++ b/git.c @@ -5,6 +5,7 @@ #include "run-command.h" #include "alias.h" #include "shallow.h" +#include "sparse-checkout.h" #define RUN_SETUP (1<<0) #define RUN_SETUP_GENTLY (1<<1) @@ -311,6 +312,10 @@ static int handle_options(const char ***argv, int *argc, int *envchanged) } else { exit(list_cmds(cmd)); } + } else if (!strcmp(cmd, "--restrict-to-sparse-paths")) { + opt_restrict_to_sparse_paths = 1; + } else if (!strcmp(cmd, "--no-restrict-to-sparse-paths")) { + opt_restrict_to_sparse_paths = 0; } else { fprintf(stderr, _("unknown option: %s\n"), cmd); usage(git_usage_string); diff --git a/sparse-checkout.c b/sparse-checkout.c new file mode 100644 index 0000000000..96c5ed5446 --- /dev/null +++ b/sparse-checkout.c @@ -0,0 +1,18 @@ +#include "cache.h" +#include "config.h" +#include "sparse-checkout.h" + +int opt_restrict_to_sparse_paths = -1; + +int restrict_to_sparse_paths(struct repository *repo) +{ + int ret; + + if (opt_restrict_to_sparse_paths >= 0) + return opt_restrict_to_sparse_paths; + + if (repo_config_get_bool(repo, "sparse.restrictcmds", &ret)) + ret = 1; + + return ret; +} diff --git a/sparse-checkout.h b/sparse-checkout.h new file mode 100644 index 0000000000..a4805e443a --- /dev/null +++ b/sparse-checkout.h @@ -0,0 +1,11 @@ +#ifndef SPARSE_CHECKOUT_H +#define SPARSE_CHECKOUT_H + +struct repository; + +extern int opt_restrict_to_sparse_paths; + +/* Whether or not cmds should restrict behavior on sparse paths, in this repo */ +int restrict_to_sparse_paths(struct repository *repo); + +#endif /* SPARSE_CHECKOUT_H */ diff --git a/t/t7817-grep-sparse-checkout.sh b/t/t7817-grep-sparse-checkout.sh index b3109e3479..f93a4f71d1 100755 --- a/t/t7817-grep-sparse-checkout.sh +++ b/t/t7817-grep-sparse-checkout.sh @@ -80,10 +80,10 @@ test_expect_success 'setup' ' test_path_is_file sub2/a ' -# The test below checks a special case: the sparsity patterns exclude '/b' +# The two tests below check a special case: the sparsity patterns exclude '/b' # and sparse checkout is enabled, but the path exists in the working tree (e.g. # manually created after `git sparse-checkout init`). In this case, grep should -# skip it. +# skip the file by default, but not with --no-restrict-to-sparse-paths. test_expect_success 'grep in working tree should honor sparse checkout' ' cat >expect <<-EOF && a:text @@ -93,6 +93,16 @@ test_expect_success 'grep in working tree should honor sparse checkout' ' git grep "text" >actual && test_cmp expect actual ' +test_expect_success 'grep w/ --no-restrict-to-sparse-paths for sparsely excluded but present paths' ' + cat >expect <<-EOF && + a:text + b:new-text + EOF + echo "new-text" >b && + test_when_finished "rm b" && + git --no-restrict-to-sparse-paths grep "text" >actual && + test_cmp expect actual +' test_expect_success 'grep unmerged file despite not matching sparsity patterns' ' cat >expect <<-EOF && @@ -157,7 +167,7 @@ test_expect_success 'grep should ignore sparsity patterns' ' ' # Note that sub2/ is present in the worktree but it is excluded by the sparsity -# patterns, so grep should not recurse into it. +# patterns, so grep should only recurse into it with --no-restrict-to-sparse-paths. test_expect_success 'grep --recurse-submodules should honor sparse checkout in submodule' ' cat >expect <<-EOF && a:text @@ -166,6 +176,15 @@ test_expect_success 'grep --recurse-submodules should honor sparse checkout in s git grep --recurse-submodules "text" >actual && test_cmp expect actual ' +test_expect_success 'grep --recurse-submodules should search in excluded submodules w/ --no-restrict-to-sparse-paths' ' + cat >expect <<-EOF && + a:text + sub/B/b:text + sub2/a:text + EOF + git --no-restrict-to-sparse-paths grep --recurse-submodules "text" >actual && + test_cmp expect actual +' test_expect_success 'grep --recurse-submodules --cached should honor sparse checkout in submodule' ' cat >expect <<-EOF && @@ -192,4 +211,111 @@ test_expect_success 'grep --recurse-submodules should honor sparse test_cmp expect_tag-to-commit actual_tag-to-commit ' +for cmd in 'git --no-restrict-to-sparse-paths grep' \ + 'git -c sparse.restrictCmds=false grep' \ + 'git -c sparse.restrictCmds=true --no-restrict-to-sparse-paths grep' +do + + test_expect_success "$cmd --cached should ignore sparsity patterns" ' + cat >expect <<-EOF && + a:text + b:text + dir/c:text + EOF + $cmd --cached "text" >actual && + test_cmp expect actual + ' + + test_expect_success "$cmd should ignore sparsity patterns" ' + commit=$(git rev-parse HEAD) && + cat >expect_commit <<-EOF && + $commit:a:text + $commit:b:text + $commit:dir/c:text + EOF + cat >expect_tag-to-commit <<-EOF && + tag-to-commit:a:text + tag-to-commit:b:text + tag-to-commit:dir/c:text + EOF + $cmd "text" $commit >actual_commit && + test_cmp expect_commit actual_commit && + $cmd "text" tag-to-commit >actual_tag-to-commit && + test_cmp expect_tag-to-commit actual_tag-to-commit + ' +done + +test_expect_success 'grep --recurse-submodules --cached w/ --no-restrict-to-sparse-paths' ' + cat >expect <<-EOF && + a:text + b:text + dir/c:text + sub/A/a:text + sub/B/b:text + sub2/a:text + EOF + git --no-restrict-to-sparse-paths grep --recurse-submodules --cached \ + "text" >actual && + test_cmp expect actual +' + +test_expect_success 'grep --recurse-submodules w/ --no-restrict-to-sparse-paths' ' + commit=$(git rev-parse HEAD) && + cat >expect_commit <<-EOF && + $commit:a:text + $commit:b:text + $commit:dir/c:text + $commit:sub/A/a:text + $commit:sub/B/b:text + $commit:sub2/a:text + EOF + cat >expect_tag-to-commit <<-EOF && + tag-to-commit:a:text + tag-to-commit:b:text + tag-to-commit:dir/c:text + tag-to-commit:sub/A/a:text + tag-to-commit:sub/B/b:text + tag-to-commit:sub2/a:text + EOF + git --no-restrict-to-sparse-paths grep --recurse-submodules "text" \ + $commit >actual_commit && + test_cmp expect_commit actual_commit && + git --no-restrict-to-sparse-paths grep --recurse-submodules "text" \ + tag-to-commit >actual_tag-to-commit && + test_cmp expect_tag-to-commit actual_tag-to-commit +' + +test_expect_success 'should respect the sparse.restrictCmds values from submodules' ' + cat >expect <<-EOF && + a:text + sub/A/a:text + sub/B/b:text + EOF + test_config -C sub sparse.restrictCmds false && + git grep --cached --recurse-submodules "text" >actual && + test_cmp expect actual +' + +test_expect_success 'should propagate --[no]-restrict-to-sparse-paths to submodules' ' + cat >expect <<-EOF && + a:text + b:text + dir/c:text + sub/A/a:text + sub/B/b:text + sub2/a:text + EOF + test_config -C sub sparse.restrictCmds true && + git --no-restrict-to-sparse-paths grep --cached --recurse-submodules "text" >actual && + test_cmp expect actual +' + +for opt in '--untracked' '--no-index' +do + test_expect_success "--[no]-restrict-to-sparse-paths and $opt are incompatible" " + test_must_fail git --restrict-to-sparse-paths grep $opt . 2>actual && + test_i18ngrep 'restrict-to-sparse-paths is incompatible with' actual + " +done + test_done diff --git a/t/t9902-completion.sh b/t/t9902-completion.sh index 8425b9a531..a8c2ac9d70 100755 --- a/t/t9902-completion.sh +++ b/t/t9902-completion.sh @@ -1928,6 +1928,8 @@ test_expect_success 'double dash "git" itself' ' --namespace= --no-replace-objects Z --help Z + --restrict-to-sparse-paths Z + --no-restrict-to-sparse-paths Z EOF ' @@ -1970,7 +1972,7 @@ test_expect_success 'general options' ' test_completion "git --nam" "--namespace=" && test_completion "git --bar" "--bare " && test_completion "git --inf" "--info-path " && - test_completion "git --no-r" "--no-replace-objects " + test_completion "git --no-rep" "--no-replace-objects " ' test_expect_success 'general options plus command' '