From patchwork Sun Sep 29 07:15:18 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: shejialuo X-Patchwork-Id: 13814848 Received: from mail-pl1-f178.google.com (mail-pl1-f178.google.com [209.85.214.178]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C134F17C68 for ; Sun, 29 Sep 2024 07:15:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.178 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727594122; cv=none; b=EUHpljdbYLpNbY4/A/jA/ERBjh5+eXUutbup9sG2XZlPaPWk5sC1cL5kE8eGrKx3qHBbw9tMAb46sExGlJZg8Q6FYQHp52hFMWxyA2+bIvKaGOXiyz+51fkegISKsxap+IDzoLrKW4fISeya2iO/Cu9WnrU0MBCD4KpoO368nYk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727594122; c=relaxed/simple; bh=7hEPM+686e2LwLzUsNKEW/7eC4H9tgaIcZjbUuF9yJs=; h=Date:From:To:Cc:Subject:Message-ID:References:MIME-Version: Content-Type:Content-Disposition:In-Reply-To; b=T01aEl+f/6yRAiGDd7oYd4bvzCGKv9J1H90pSt7QxLPyt8NVWlTuUEszgMGYnI0hNxywFgjCG/Ua9yqyCO1Sfc/0tgDL8p8c+0yqdYRLERJsROkmzRl3LnoWRQDtIyRk4v/MGozn9TBBr2xLOrOVUjb81RVI0y3hI5P8lTM2+MU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=D7N/FI5j; arc=none smtp.client-ip=209.85.214.178 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="D7N/FI5j" Received: by mail-pl1-f178.google.com with SMTP id d9443c01a7336-2059112f0a7so31603515ad.3 for ; Sun, 29 Sep 2024 00:15:20 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1727594119; x=1728198919; darn=vger.kernel.org; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:from:to:cc:subject:date:message-id:reply-to; bh=PaW/L1N+pf/tIvL6LVphvkNKwP4K+NALqN0af0AZ1E8=; b=D7N/FI5jJ45eg1pgzfLWgKyYyT2cwRclnxdMYgILzvMhTyu8MyzZVS9tDNapfSctcj 3vkEkB4NXG4f0ydpBAwqGt3lHJPub3NuemynHZEIAPW3hlng7b8c/Z1ZGrlkAkRpyadf a36fT8C9u4pAeri7k1916qro0K4VKVbbF0V+Sf6gsj0Boq6GRsq7ZTSnzniPM/uupMbm LvnqahjjIpy9DSVGhZVshEPfUlN085gCfBzUYZgBgKNkFsvid74ql6/CLmpaQ+8X3K8J /EQTlxTTQwouXFZQQS68hJgmrwa1vUXD0z+GPFf4CHMpPDNy+x4LFQo6w+AQVV4HmsZy de6Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1727594119; x=1728198919; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=PaW/L1N+pf/tIvL6LVphvkNKwP4K+NALqN0af0AZ1E8=; b=OvL2sed+OTVyIKGhr8QUIFmegoSB38lmg1OrqavwBEccSZQ1FUCXiO4c9g9omkcO+x gy0Iqd2Ghtdyh9L5CzJN1SdRScDFoJ8RkqhbQtqKiExMv/4Jdb9MMe27sRcpA9xyPYRX xEmj0OnfuSzsc30MnFssIa6xOijP/yIsIHtdkNhHnOO+FkP42FH20epTIsud7KyfP+zq CHgie+JZYk54YpmjJGA/pCEQIGws8KWevTMZR79J1Pfa9Zn5opaZENZiv7PgtTr8U+VE eRVH8+oTEXTez9DjeMdcp7uSFgyFRfP3c4SWY3xm8dCzgN3cp6XCSfFSBzb/0ju9AJLK BsqA== X-Gm-Message-State: AOJu0YwsRmMn8uqJgxKJQggjN+hATHNAo9V/KIEQLzHtnfr/p1b4LDBz sj5H9us2WPrNwoo7XhWribHp2SvZ/LQCZ3riuMR0ulw+JtW1LWxtzG103g== X-Google-Smtp-Source: AGHT+IFJ+hbo3O8zrYJVjd8XJd9ceSwOQdaZOuxDI0Xfu71rWcKPy4gzaEjBIHgcmZVmvvdI4wLbOQ== X-Received: by 2002:a17:902:f54b:b0:206:8c18:a538 with SMTP id d9443c01a7336-20b3776af26mr126102845ad.32.1727594119445; Sun, 29 Sep 2024 00:15:19 -0700 (PDT) Received: from localhost ([2605:52c0:1:4cf:6c5a:92ff:fe25:ceff]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-20b37e63ab7sm35739665ad.290.2024.09.29.00.15.18 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 29 Sep 2024 00:15:18 -0700 (PDT) Date: Sun, 29 Sep 2024 15:15:18 +0800 From: shejialuo To: git@vger.kernel.org Cc: Patrick Steinhardt , Karthik Nayak , Junio C Hamano Subject: [PATCH v5 1/9] ref: initialize "fsck_ref_report" with zero Message-ID: References: Precedence: bulk X-Mailing-List: git@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: In "fsck.c::fsck_refs_error_function", we need to tell whether "oid" and "referent" is NULL. So, we need to always initialize these parameters to NULL instead of letting them point to anywhere when creating a new "fsck_ref_report" structure. The original code explicitly initializes the "path" member in the "struct fsck_ref_report" to NULL (which implicitly 0-initializes other members in the struct). It is more customary to use "{ 0 }" to express that we are 0-initializing everything. In order to align with the the codebase, initialize "fsck_ref_report" with zero. Mentored-by: Patrick Steinhardt Mentored-by: Karthik Nayak Signed-off-by: shejialuo --- refs/files-backend.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/refs/files-backend.c b/refs/files-backend.c index 0824c0b8a9..03d2503276 100644 --- a/refs/files-backend.c +++ b/refs/files-backend.c @@ -3520,7 +3520,7 @@ static int files_fsck_refs_name(struct ref_store *ref_store UNUSED, goto cleanup; if (check_refname_format(iter->basename, REFNAME_ALLOW_ONELEVEL)) { - struct fsck_ref_report report = { .path = NULL }; + struct fsck_ref_report report = { 0 }; strbuf_addf(&sb, "%s/%s", refs_check_dir, iter->relative_path); report.path = sb.buf; From patchwork Sun Sep 29 07:15:26 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: shejialuo X-Patchwork-Id: 13814849 Received: from mail-pj1-f41.google.com (mail-pj1-f41.google.com [209.85.216.41]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7692213C67A for ; Sun, 29 Sep 2024 07:15:29 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.216.41 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727594131; cv=none; b=rtHaTUUM+qmMqpsWdjjqXMkvCh0LCJYs3DTmPYqSW/dww7QJ/MNvEB6C6KNWvo7GdjMRzCr+owtjzgacXKZbtSmOpW9eZ7Y8m4DPRd4wGrtla7q5/8XjO2zc7neM9+iNLEUPoNddeSEKLU3H/uDQjM3imA0j/LBackSRvuPlTHs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727594131; c=relaxed/simple; bh=yJy575HqzJiYdTToT6U3V5n6TQzj+0GlDVx1EUccbXU=; h=Date:From:To:Cc:Subject:Message-ID:References:MIME-Version: Content-Type:Content-Disposition:In-Reply-To; b=OwgV0btQtj0ldhFyUT73Ac2zQhbnbE585ciVb+Z/dnQgX5UsI7i/3OQsG2JagbuXWjHIWU9HkUtdF5kF7VtpeArMMkiiSVLxT4rceqtO9uAyR8F0Fg/9f+IYgqoWte6ApoIT+NdCLArhHBNvssphGHGe28vMOIzJCq3zyrWnWjA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=KsMBeLeu; arc=none smtp.client-ip=209.85.216.41 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="KsMBeLeu" Received: by mail-pj1-f41.google.com with SMTP id 98e67ed59e1d1-2e0be1afa85so1990283a91.1 for ; Sun, 29 Sep 2024 00:15:29 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1727594128; x=1728198928; darn=vger.kernel.org; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:from:to:cc:subject:date:message-id:reply-to; bh=Qs3co9Xh5bx28I4SQMHLxDzB2eXrlvaIlCbD7vydN8U=; b=KsMBeLeuMhoBNrcO5q3ajDXwRpb/smSQO/2aXLX/tpvdw1Pv++LsfxnCEOpmE3Gmzm C/Ls7Vnn20A6wsaA/+X1BhShJUR94iWx1mCitagwVwXISjWg9p1B+wW89hLAim5BQ+hC UpvniZbF4dqDLoxRLU/Nb+wFoCePoBHPC1hXNNYwPpaLMo4QvEzfbfI7jX4SA5vm6w4m E7MR/uomx1R574/DPnwdwyr7I17ooBxFYhieeMxnnL+VwhzY44QNS5218OKaFRHKNwtA LY2rSdH5YBw65LmdTBTerHxA+4x7oGDLiFUduVQoM/II3nNbbaYxv2SPwIHPU7DfwY9Y Bd0g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1727594128; x=1728198928; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=Qs3co9Xh5bx28I4SQMHLxDzB2eXrlvaIlCbD7vydN8U=; b=L4GevJWCAmOjXpdltY0M35OuusE9iucbfSEc6bJSbegdiwNI8skaBZetBDDqbjNPM1 I6S5w2fPIM5qREPNkpHVblJ4czu/CvoNMVebLIcslnx0Eufoshnbm+v+5g6QE7/nMIXQ Rf2oH3Ky7FOOFUJm3zfdCfmmjNfSzrRMyZO0xi7jVFteDC4HljRMMvL4ogf+/IwC0vDh f4vZdrcOa6ieWeteyki3i4sNFKIthSSRbFUU9BbuVjS0jjfABk/mitnXgBZy2zjT7tIG Hifmquj/8TJwlVQGaRW40aVLgQ256HMIi4RkcBxGO1/7gAg5IMigWq2mSNFtc9Wjtk/r AWWA== X-Gm-Message-State: AOJu0YyE9fCsYvWl8AhZxKzzj/RusfajRFTovfZNJ7gRUO2S/Ja2zxYO fHEJ5ylCdLBxrsRwlITvhKfnOm+v5/gvYjLuLvbHN6sJ5pQCMhyfz+YkgA== X-Google-Smtp-Source: AGHT+IGcPrIo+cdctA/TzkTqanY3Zd23cClAD5Vqqdow2+M6yT2L3dPTuV6ROefod+eQFaAT7dgPSA== X-Received: by 2002:a17:90a:bd8d:b0:2d8:f7e2:f03 with SMTP id 98e67ed59e1d1-2e0b8e9282cmr10714261a91.32.1727594128178; Sun, 29 Sep 2024 00:15:28 -0700 (PDT) Received: from localhost ([2605:52c0:1:4cf:6c5a:92ff:fe25:ceff]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-2e0b6c7729fsm5307319a91.22.2024.09.29.00.15.27 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 29 Sep 2024 00:15:27 -0700 (PDT) Date: Sun, 29 Sep 2024 15:15:26 +0800 From: shejialuo To: git@vger.kernel.org Cc: Patrick Steinhardt , Karthik Nayak , Junio C Hamano Subject: [PATCH v5 2/9] builtin/refs: support multiple worktrees check for refs. Message-ID: References: Precedence: bulk X-Mailing-List: git@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: We have already set up the infrastructure to check the consistency for refs, but we do not support multiple worktrees. As we decide to add more checks for ref content, we need to set up support for multiple worktrees. Use "get_worktrees" and "get_worktree_ref_store" to check refs under the worktrees. Because we should only check once for "packed-refs", let's call the fsck function for packed-backend when in the main worktree. In order to know which directory we check, we should default print this information instead of specifying "--verbose". It's not suitable to print these information to the stderr. So, change to stdout. Mentored-by: Patrick Steinhardt Mentored-by: Karthik Nayak Signed-off-by: shejialuo --- builtin/refs.c | 11 ++++++-- refs/files-backend.c | 18 ++++++++---- t/t0602-reffiles-fsck.sh | 59 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 81 insertions(+), 7 deletions(-) diff --git a/builtin/refs.c b/builtin/refs.c index 24978a7b7b..3c492ea922 100644 --- a/builtin/refs.c +++ b/builtin/refs.c @@ -5,6 +5,7 @@ #include "parse-options.h" #include "refs.h" #include "strbuf.h" +#include "worktree.h" #define REFS_MIGRATE_USAGE \ N_("git refs migrate --ref-format= [--dry-run]") @@ -66,6 +67,7 @@ static int cmd_refs_migrate(int argc, const char **argv, const char *prefix) static int cmd_refs_verify(int argc, const char **argv, const char *prefix) { struct fsck_options fsck_refs_options = FSCK_REFS_OPTIONS_DEFAULT; + struct worktree **worktrees, **p; const char * const verify_usage[] = { REFS_VERIFY_USAGE, NULL, @@ -75,7 +77,7 @@ static int cmd_refs_verify(int argc, const char **argv, const char *prefix) OPT_BOOL(0, "strict", &fsck_refs_options.strict, N_("enable strict checking")), OPT_END(), }; - int ret; + int ret = 0; argc = parse_options(argc, argv, prefix, options, verify_usage, 0); if (argc) @@ -84,9 +86,14 @@ static int cmd_refs_verify(int argc, const char **argv, const char *prefix) git_config(git_fsck_config, &fsck_refs_options); prepare_repo_settings(the_repository); - ret = refs_fsck(get_main_ref_store(the_repository), &fsck_refs_options); + worktrees = get_worktrees(); + for (p = worktrees; *p; p++) { + struct worktree *wt = *p; + ret += refs_fsck(get_worktree_ref_store(wt), &fsck_refs_options); + } fsck_options_clear(&fsck_refs_options); + free_worktrees(worktrees); return ret; } diff --git a/refs/files-backend.c b/refs/files-backend.c index 03d2503276..57318b4c4e 100644 --- a/refs/files-backend.c +++ b/refs/files-backend.c @@ -3558,7 +3558,7 @@ static int files_fsck_refs_dir(struct ref_store *ref_store, } else if (S_ISREG(iter->st.st_mode) || S_ISLNK(iter->st.st_mode)) { if (o->verbose) - fprintf_ln(stderr, "Checking %s/%s", + fprintf_ln(stdout, "Checking %s/%s", refs_check_dir, iter->relative_path); for (size_t i = 0; fsck_refs_fn[i]; i++) { if (fsck_refs_fn[i](ref_store, o, refs_check_dir, iter)) @@ -3589,8 +3589,8 @@ static int files_fsck_refs(struct ref_store *ref_store, NULL, }; - if (o->verbose) - fprintf_ln(stderr, _("Checking references consistency")); + fprintf_ln(stdout, _("Checking references consistency in %s"), + ref_store->gitdir); return files_fsck_refs_dir(ref_store, o, "refs", fsck_refs_fn); } @@ -3600,8 +3600,16 @@ static int files_fsck(struct ref_store *ref_store, struct files_ref_store *refs = files_downcast(ref_store, REF_STORE_READ, "fsck"); - return files_fsck_refs(ref_store, o) | - refs->packed_ref_store->be->fsck(refs->packed_ref_store, o); + int ret = files_fsck_refs(ref_store, o); + + /* + * packed-refs should only be checked once because it is shared + * between all worktrees. + */ + if (!strcmp(ref_store->gitdir, ref_store->repo->gitdir)) + ret += refs->packed_ref_store->be->fsck(refs->packed_ref_store, o); + + return ret; } struct ref_storage_be refs_be_files = { diff --git a/t/t0602-reffiles-fsck.sh b/t/t0602-reffiles-fsck.sh index 71a4d1a5ae..4c6cd6f7d0 100755 --- a/t/t0602-reffiles-fsck.sh +++ b/t/t0602-reffiles-fsck.sh @@ -89,4 +89,63 @@ test_expect_success 'ref name check should be adapted into fsck messages' ' test_must_be_empty err ' +test_expect_success 'ref name check should work for multiple worktrees' ' + test_when_finished "rm -rf repo" && + git init repo && + + cd repo && + test_commit initial && + git checkout -b branch-1 && + test_commit second && + git checkout -b branch-2 && + test_commit third && + git checkout -b branch-3 && + git worktree add ./worktree-1 branch-1 && + git worktree add ./worktree-2 branch-2 && + worktree1_refdir_prefix=.git/worktrees/worktree-1/refs/worktree && + worktree2_refdir_prefix=.git/worktrees/worktree-2/refs/worktree && + + ( + cd worktree-1 && + git update-ref refs/worktree/branch-4 refs/heads/branch-3 + ) && + ( + cd worktree-2 && + git update-ref refs/worktree/branch-4 refs/heads/branch-3 + ) && + + cp $worktree1_refdir_prefix/branch-4 $worktree1_refdir_prefix/.branch-2 && + cp $worktree2_refdir_prefix/branch-4 $worktree2_refdir_prefix/@ && + + test_must_fail git refs verify 2>err && + cat >expect <<-EOF && + error: refs/worktree/.branch-2: badRefName: invalid refname format + error: refs/worktree/@: badRefName: invalid refname format + EOF + sort err >sorted_err && + test_cmp expect sorted_err && + + ( + cd worktree-1 && + test_must_fail git refs verify 2>err && + cat >expect <<-EOF && + error: refs/worktree/.branch-2: badRefName: invalid refname format + error: refs/worktree/@: badRefName: invalid refname format + EOF + sort err >sorted_err && + test_cmp expect sorted_err + ) && + + ( + cd worktree-2 && + test_must_fail git refs verify 2>err && + cat >expect <<-EOF && + error: refs/worktree/.branch-2: badRefName: invalid refname format + error: refs/worktree/@: badRefName: invalid refname format + EOF + sort err >sorted_err && + test_cmp expect sorted_err + ) +' + test_done From patchwork Sun Sep 29 07:15:46 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: shejialuo X-Patchwork-Id: 13814850 Received: from mail-pl1-f176.google.com (mail-pl1-f176.google.com [209.85.214.176]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9849C13635F for ; Sun, 29 Sep 2024 07:15:48 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.176 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727594150; cv=none; b=CtKpbLXKuwrqKoyc6PVt+sXXAD0XZZpixClbLk50z/Jrrb6Wc6L2onqyHoxT0+m0DXB5sGYp6kO8q9kmuWGnO9pl7/moAyj3LDp6llNarlF6vGsR+2GfigjbWI0Yj3Nnj+c8HrVUvNuC1OaeyNY/fhCXbh4AEmj64NabrnPGtz8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727594150; c=relaxed/simple; bh=GqXZTTFiEm2fuNnDo8NDciaVdx10GU4ZyW8ITJKdci0=; h=Date:From:To:Cc:Subject:Message-ID:References:MIME-Version: Content-Type:Content-Disposition:In-Reply-To; b=n8GtBD4XL078v+EV2auBzRkh/HSRb8zoAex8oN8YAD7a6bNQ3mRLt1oAx62oUTdaZNX05veqSPIUAPE0nCITuVxaoL/byR8eKgJ95MwMNE3d4vrJEQC8wEdoYWTbqcPQYVlyXQLD9PrymDPzon5BieVxmftd0oqtU3hLxuj/jLQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=TXgr15+Z; arc=none smtp.client-ip=209.85.214.176 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="TXgr15+Z" Received: by mail-pl1-f176.google.com with SMTP id d9443c01a7336-2054feabfc3so32320265ad.1 for ; Sun, 29 Sep 2024 00:15:48 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1727594147; x=1728198947; darn=vger.kernel.org; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:from:to:cc:subject:date:message-id:reply-to; bh=hj5F+gEtyBRxz310G1FbgvC+oRcD5qK5T27Qn9rMPGI=; b=TXgr15+ZLSxc9rY/exwkxYTXbKw9DpcgnXFmmJ20EwncnVYhbwvlXJ+eXCLSF76n6D SIYQEtGK1amGc7S1PaK/YouGmSQuZbtyO0FhHidK6/oiXTHdSKIZsrDzIbyZep/VuiXn Samob8xq6Ibe6kyE8R4j88Ih97O7jfXmXLaX/3wm5jJl9voWpWFS6uTFB/PXZd+pQ2JE DXipFm0Tzn3u/vwzBpvgpG2xUkwaiH0EmyjCBDTgPTlx7fo1YJRIeMx1kH8syV8/+PoN zJfRgkWB1LMr4WQL4vJETHSWedsCJRHjFVL3mGp/nD2E6vwukrDL+t/J9uQABgrEJ43w KbOQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1727594147; x=1728198947; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=hj5F+gEtyBRxz310G1FbgvC+oRcD5qK5T27Qn9rMPGI=; b=Hfqu4BGactE7GQSeIYjB6qHObsFQ3QGIojUwvwgdvfB1XIEoBmsB7S/wW6UzU2nSHg 05ctkRQqnSHHYnn8l/yy10Zvs8H7YIESitN5fZztZMJF5TwBzJmYoTk/LGrMr3fYjSq+ oP6yK6tFAE9BmCmu1hUIwaHOLRzut9X2XjmsOeUxbli9NyENvWLqbJmpyNns6WhhMDbl MRqjsopiGYp2uLmF7Y+IRQSBl8ih6PbJ0BoxseVyiS89B3/jK9lUOvWpSHEensAzTwIT TDLGEJ2hFJWzhmbYtofjnJL7aVnpVpyZSMxXa/q2FmP/Klisysk7YncxudszJ4tI8FA/ Z8Rg== X-Gm-Message-State: AOJu0YwwdfMa/LMFRiuZsQWy1c4/r/a2FagtlwTJisf6vTHqUpVm7WN2 NgJEVIlRYqGcBBg6rD2nk6Ozdp1ZfOlDflk+QYEZQRB/j7AYyJheeRE98w== X-Google-Smtp-Source: AGHT+IGTsUENLnnxoP4Q10wSZoxK78yyzBh7EI3v2sWqyqpOQAwgP8z2bccvdMhjyiE5Zd3SE9G1Eg== X-Received: by 2002:a17:903:32cc:b0:20b:7e0d:8f with SMTP id d9443c01a7336-20b7e0d032bmr4830935ad.3.1727594147405; Sun, 29 Sep 2024 00:15:47 -0700 (PDT) Received: from localhost ([2605:52c0:1:4cf:6c5a:92ff:fe25:ceff]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-20b37e0ef3asm35656435ad.121.2024.09.29.00.15.46 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 29 Sep 2024 00:15:46 -0700 (PDT) Date: Sun, 29 Sep 2024 15:15:46 +0800 From: shejialuo To: git@vger.kernel.org Cc: Patrick Steinhardt , Karthik Nayak , Junio C Hamano Subject: [PATCH v5 3/9] ref: port git-fsck(1) regular refs check for files backend Message-ID: References: Precedence: bulk X-Mailing-List: git@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: "git-fsck(1)" has some consistency checks for regular refs. As we want to align the checks "git refs verify" performs with them (and eventually call the unified code that checks refs from both), port the logic "git-fsck" has to "git refs verify". "git-fsck(1)" will report an error when the ref content is invalid. Following this, add a similar check to "git refs verify". Then add a new fsck error message "badRefContent(ERROR)" to represent that a ref has an invalid content. Mentored-by: Patrick Steinhardt Mentored-by: Karthik Nayak Signed-off-by: shejialuo --- Documentation/fsck-msgids.txt | 3 ++ fsck.h | 1 + refs/files-backend.c | 45 ++++++++++++++++++++++++ t/t0602-reffiles-fsck.sh | 66 +++++++++++++++++++++++++++++++++++ 4 files changed, 115 insertions(+) diff --git a/Documentation/fsck-msgids.txt b/Documentation/fsck-msgids.txt index 68a2801f15..22c385ea22 100644 --- a/Documentation/fsck-msgids.txt +++ b/Documentation/fsck-msgids.txt @@ -19,6 +19,9 @@ `badParentSha1`:: (ERROR) A commit object has a bad parent sha1. +`badRefContent`:: + (ERROR) A ref has bad content. + `badRefFiletype`:: (ERROR) A ref has a bad file type. diff --git a/fsck.h b/fsck.h index 500b4c04d2..0d99a87911 100644 --- a/fsck.h +++ b/fsck.h @@ -31,6 +31,7 @@ enum fsck_msg_type { FUNC(BAD_NAME, ERROR) \ FUNC(BAD_OBJECT_SHA1, ERROR) \ FUNC(BAD_PARENT_SHA1, ERROR) \ + FUNC(BAD_REF_CONTENT, ERROR) \ FUNC(BAD_REF_FILETYPE, ERROR) \ FUNC(BAD_REF_NAME, ERROR) \ FUNC(BAD_TIMEZONE, ERROR) \ diff --git a/refs/files-backend.c b/refs/files-backend.c index 57318b4c4e..35b3fa983e 100644 --- a/refs/files-backend.c +++ b/refs/files-backend.c @@ -3504,6 +3504,50 @@ typedef int (*files_fsck_refs_fn)(struct ref_store *ref_store, const char *refs_check_dir, struct dir_iterator *iter); +static int files_fsck_refs_content(struct ref_store *ref_store, + struct fsck_options *o, + const char *refs_check_dir, + struct dir_iterator *iter) +{ + struct strbuf ref_content = STRBUF_INIT; + struct strbuf referent = STRBUF_INIT; + struct strbuf refname = STRBUF_INIT; + struct fsck_ref_report report = { 0 }; + unsigned int type = 0; + int failure_errno = 0; + struct object_id oid; + int ret = 0; + + strbuf_addf(&refname, "%s/%s", refs_check_dir, iter->relative_path); + report.path = refname.buf; + + if (S_ISLNK(iter->st.st_mode)) + goto cleanup; + + if (strbuf_read_file(&ref_content, iter->path.buf, 0) < 0) { + ret = fsck_report_ref(o, &report, + FSCK_MSG_BAD_REF_CONTENT, + "cannot read ref file"); + goto cleanup; + } + + if (parse_loose_ref_contents(ref_store->repo->hash_algo, + ref_content.buf, &oid, &referent, + &type, &failure_errno)) { + strbuf_rtrim(&ref_content); + ret = fsck_report_ref(o, &report, + FSCK_MSG_BAD_REF_CONTENT, + "%s", ref_content.buf); + goto cleanup; + } + +cleanup: + strbuf_release(&refname); + strbuf_release(&ref_content); + strbuf_release(&referent); + return ret; +} + static int files_fsck_refs_name(struct ref_store *ref_store UNUSED, struct fsck_options *o, const char *refs_check_dir, @@ -3586,6 +3630,7 @@ static int files_fsck_refs(struct ref_store *ref_store, { files_fsck_refs_fn fsck_refs_fn[]= { files_fsck_refs_name, + files_fsck_refs_content, NULL, }; diff --git a/t/t0602-reffiles-fsck.sh b/t/t0602-reffiles-fsck.sh index 4c6cd6f7d0..628f9bcc46 100755 --- a/t/t0602-reffiles-fsck.sh +++ b/t/t0602-reffiles-fsck.sh @@ -148,4 +148,70 @@ test_expect_success 'ref name check should work for multiple worktrees' ' ) ' +test_expect_success 'regular ref content should be checked (individual)' ' + test_when_finished "rm -rf repo" && + git init repo && + branch_dir_prefix=.git/refs/heads && + tag_dir_prefix=.git/refs/tags && + cd repo && + test_commit default && + mkdir -p "$branch_dir_prefix/a/b" && + + git refs verify 2>err && + test_must_be_empty err && + + bad_content=$(git rev-parse main)x && + printf "%s" $bad_content >$tag_dir_prefix/tag-bad-1 && + test_must_fail git refs verify 2>err && + cat >expect <<-EOF && + error: refs/tags/tag-bad-1: badRefContent: $bad_content + EOF + rm $tag_dir_prefix/tag-bad-1 && + test_cmp expect err && + + bad_content=xfsazqfxcadas && + printf "%s" $bad_content >$tag_dir_prefix/tag-bad-2 && + test_must_fail git refs verify 2>err && + cat >expect <<-EOF && + error: refs/tags/tag-bad-2: badRefContent: $bad_content + EOF + rm $tag_dir_prefix/tag-bad-2 && + test_cmp expect err && + + bad_content=Xfsazqfxcadas && + printf "%s" $bad_content >$branch_dir_prefix/a/b/branch-bad && + test_must_fail git refs verify 2>err && + cat >expect <<-EOF && + error: refs/heads/a/b/branch-bad: badRefContent: $bad_content + EOF + rm $branch_dir_prefix/a/b/branch-bad && + test_cmp expect err +' + +test_expect_success 'regular ref content should be checked (aggregate)' ' + test_when_finished "rm -rf repo" && + git init repo && + branch_dir_prefix=.git/refs/heads && + tag_dir_prefix=.git/refs/tags && + cd repo && + test_commit default && + mkdir -p "$branch_dir_prefix/a/b" && + + bad_content_1=$(git rev-parse main)x && + bad_content_2=xfsazqfxcadas && + bad_content_3=Xfsazqfxcadas && + printf "%s" $bad_content_1 >$tag_dir_prefix/tag-bad-1 && + printf "%s" $bad_content_2 >$tag_dir_prefix/tag-bad-2 && + printf "%s" $bad_content_3 >$branch_dir_prefix/a/b/branch-bad && + + test_must_fail git refs verify 2>err && + cat >expect <<-EOF && + error: refs/heads/a/b/branch-bad: badRefContent: $bad_content_3 + error: refs/tags/tag-bad-1: badRefContent: $bad_content_1 + error: refs/tags/tag-bad-2: badRefContent: $bad_content_2 + EOF + sort err >sorted_err && + test_cmp expect sorted_err +' + test_done From patchwork Sun Sep 29 07:16:00 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: shejialuo X-Patchwork-Id: 13814851 Received: from mail-pf1-f175.google.com (mail-pf1-f175.google.com [209.85.210.175]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 033A541A80 for ; Sun, 29 Sep 2024 07:16:02 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.175 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727594164; cv=none; b=pimkXoE03nc3h37z9mMtmPnhQUnIEj+wQon1nimIZmEI8bl3vAzvllz4P8Qj3c0q5F43evTHYRji02RT5XTfrH+v+bWxY8ayfvf4EySpl6oKtpb4h9H5ALftEgMr8MjHDLjAX9EITgaNen69JOFyn122FT9fF1bIPrspJDczq0I= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727594164; c=relaxed/simple; bh=pko4bPXNmFe+yLYPQMZREJoBps7+UMT5xQtXIyfFfXw=; h=Date:From:To:Cc:Subject:Message-ID:References:MIME-Version: Content-Type:Content-Disposition:In-Reply-To; b=fEB+wo0EIj58d0mlI58J4YCxWp7FV0O4b/CMORH+R/4syoknBPmSwLUWKq77PNJiKiSrkIeSZ+eNxZr7PPV7ArH0Rb5e5SO403iOhUW+BxYfwGVf7qk+p15H0YApP5OaHBIrchP9xj8UIpmp7/oIPAzqKMlT7+LxjiHXqfli6Ms= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=jRMTANyN; arc=none smtp.client-ip=209.85.210.175 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="jRMTANyN" Received: by mail-pf1-f175.google.com with SMTP id d2e1a72fcca58-71b8d10e9b3so1470790b3a.3 for ; Sun, 29 Sep 2024 00:16:02 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1727594161; x=1728198961; darn=vger.kernel.org; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:from:to:cc:subject:date:message-id:reply-to; bh=wJNgxMD8w83MEp8FDGh673OZgYRvyJABz0VkV6JNJ0s=; b=jRMTANyN31m6VSaRqMmU61hwajjoShDiKBkxCjB3P8/cJNoU5i9/NPGDUnszYgfcME AZ2AjK0rstic0OYfuJ/0+dYlaghMKeXSifSpggKZo6JlFWoODNPL9BrWy8Q6bkSXYioR c2qZxcuG0PbzkRG73RY9ealKoaYxPF4Jk0CiEnAodxefbbvIXX/ir2Q+brEvbekHg+li L06VuAd9AcEKJ9v0Hma8JJPtFpGSJVH3V/AiYd6Vq/ALuYJzRx2xR1f99gStSO1l3yaP twNVA/AHn9jPNXzTthC5ZBBi29LCCJFRqtiM7y4gbHyjWhXhloAuYw5hG8qVtipE6c9y v2ig== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1727594161; x=1728198961; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=wJNgxMD8w83MEp8FDGh673OZgYRvyJABz0VkV6JNJ0s=; b=aIe5rL4KLNQW3BBkvlVQhr3SADcupqsx1+MmHoIyshu+Ev4wsn7RXcx0DCKXny/EP3 U+dTvHPyK1Dp0FausELVlzwB3v26KUDAvt3uC0siRCileBGP5JkVksrC87FprQt84Cz+ tWG7RVucZ2udNDSSJ5diB4Crfe3iWTkb0bRs2HmUwfCfLJM4UG2GJDIgGC0qE4yy7N9b zudbcO3eTUBH+by262dOQ3OjIDdnERyr+J2R8OLxtrnI5Pjew4sgqF1D2DpcJOrsRYLW iL5DPHSuW+PP8rdA26HGGwhwKWSjJUgoDWjk9p6jApVy8WnA3WmOt2vsLu+iv6jFLb27 zTIg== X-Gm-Message-State: AOJu0YwcEiLzMEjTR+J7nFdI5yN0YW/sBMvSqdtc8i9/4j39Wfhsp//Z oOedUvqY29DiRhqaG6rTO7IHO0phaIS72ZFhjox84VrCEUJuBGjSYIr3PQ== X-Google-Smtp-Source: AGHT+IG1bey+ohM8oU0S1bn7ld5xDH7JuuWN6up85ljn46YfiyXTLn8qpa6UiHMwzm0zmTUC76HEKQ== X-Received: by 2002:a05:6a20:d80d:b0:1cf:3245:5227 with SMTP id adf61e73a8af0-1d4fa80fd44mr12061813637.46.1727594161284; Sun, 29 Sep 2024 00:16:01 -0700 (PDT) Received: from localhost ([2605:52c0:1:4cf:6c5a:92ff:fe25:ceff]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-71b264b7dd6sm4156970b3a.46.2024.09.29.00.16.00 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 29 Sep 2024 00:16:00 -0700 (PDT) Date: Sun, 29 Sep 2024 15:16:00 +0800 From: shejialuo To: git@vger.kernel.org Cc: Patrick Steinhardt , Karthik Nayak , Junio C Hamano Subject: [PATCH v5 4/9] ref: add more strict checks for regular refs Message-ID: References: Precedence: bulk X-Mailing-List: git@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: We have already used "parse_loose_ref_contents" function to check whether the ref content is valid in files backend. However, by using "parse_loose_ref_contents", we allow the ref's content to end with garbage or without a newline. Even though we never create such loose refs ourselves, we have accepted such loose refs. So, it is entirely possible that some third-party tools may rely on such loose refs being valid. We should not report an error fsck message at current. We should notify the users about such "curiously formatted" loose refs so that adequate care is taken before we decide to tighten the rules in the future. And it's not suitable either to report a warn fsck message to the user. We don't yet want the "--strict" flag that controls this bit to end up generating errors for such weirdly-formatted reference contents, as we first want to assess whether this retroactive tightening will cause issues for any tools out there. It may cause compatibility issues which may break the repository. So we add the "unofficialFormattedRef(INFO)" fsck message to represent the situation where the ref format is not officially created by us and notify the users it may become an error in the future. It might appear that we can't provide the user with any warnings by using FSCK_INFO. However, in "fsck.c::fsck_vreport", we will convert FSCK_INFO to FSCK_WARN and we can still warn the user about these situations when using "git refs verify" without introducing compatibility issues. Mentored-by: Patrick Steinhardt Mentored-by: Karthik Nayak Signed-off-by: shejialuo --- Documentation/fsck-msgids.txt | 8 +++++ fsck.h | 1 + refs.c | 2 +- refs/files-backend.c | 26 +++++++++++++-- refs/refs-internal.h | 2 +- t/t0602-reffiles-fsck.sh | 59 +++++++++++++++++++++++++++++++++++ 6 files changed, 93 insertions(+), 5 deletions(-) diff --git a/Documentation/fsck-msgids.txt b/Documentation/fsck-msgids.txt index 22c385ea22..e310b5bce9 100644 --- a/Documentation/fsck-msgids.txt +++ b/Documentation/fsck-msgids.txt @@ -179,6 +179,14 @@ `unknownType`:: (ERROR) Found an unknown object type. +`unofficialFormattedRef`:: + (INFO) The content of a loose ref file is not in the official + format such as not having a LF at the end or having trailing + garbage. As valid implementations of Git never created such a + loose ref file, it may become an error in the future. Report + to the git@vger.kernel.org mailing list if you see this error, + as we need to know what tools created such a file. + `unterminatedHeader`:: (FATAL) Missing end-of-line in the object header. diff --git a/fsck.h b/fsck.h index 0d99a87911..7420add5c0 100644 --- a/fsck.h +++ b/fsck.h @@ -85,6 +85,7 @@ enum fsck_msg_type { FUNC(MAILMAP_SYMLINK, INFO) \ FUNC(BAD_TAG_NAME, INFO) \ FUNC(MISSING_TAGGER_ENTRY, INFO) \ + FUNC(UNOFFICIAL_FORMATTED_REF, INFO) \ /* ignored (elevated when requested) */ \ FUNC(EXTRA_HEADER_ENTRY, IGNORE) diff --git a/refs.c b/refs.c index 5f729ed412..6ba1bb1aa1 100644 --- a/refs.c +++ b/refs.c @@ -1788,7 +1788,7 @@ static int refs_read_special_head(struct ref_store *ref_store, } result = parse_loose_ref_contents(ref_store->repo->hash_algo, content.buf, - oid, referent, type, failure_errno); + oid, referent, type, NULL, failure_errno); done: strbuf_release(&full_path); diff --git a/refs/files-backend.c b/refs/files-backend.c index 35b3fa983e..b2a790c884 100644 --- a/refs/files-backend.c +++ b/refs/files-backend.c @@ -568,7 +568,7 @@ static int read_ref_internal(struct ref_store *ref_store, const char *refname, buf = sb_contents.buf; ret = parse_loose_ref_contents(ref_store->repo->hash_algo, buf, - oid, referent, type, &myerr); + oid, referent, type, NULL, &myerr); out: if (ret && !myerr) @@ -605,7 +605,7 @@ static int files_read_symbolic_ref(struct ref_store *ref_store, const char *refn int parse_loose_ref_contents(const struct git_hash_algo *algop, const char *buf, struct object_id *oid, struct strbuf *referent, unsigned int *type, - int *failure_errno) + const char **trailing, int *failure_errno) { const char *p; if (skip_prefix(buf, "ref:", &buf)) { @@ -627,6 +627,10 @@ int parse_loose_ref_contents(const struct git_hash_algo *algop, *failure_errno = EINVAL; return -1; } + + if (trailing) + *trailing = p; + return 0; } @@ -3513,6 +3517,7 @@ static int files_fsck_refs_content(struct ref_store *ref_store, struct strbuf referent = STRBUF_INIT; struct strbuf refname = STRBUF_INIT; struct fsck_ref_report report = { 0 }; + const char *trailing = NULL; unsigned int type = 0; int failure_errno = 0; struct object_id oid; @@ -3533,7 +3538,7 @@ static int files_fsck_refs_content(struct ref_store *ref_store, if (parse_loose_ref_contents(ref_store->repo->hash_algo, ref_content.buf, &oid, &referent, - &type, &failure_errno)) { + &type, &trailing, &failure_errno)) { strbuf_rtrim(&ref_content); ret = fsck_report_ref(o, &report, FSCK_MSG_BAD_REF_CONTENT, @@ -3541,6 +3546,21 @@ static int files_fsck_refs_content(struct ref_store *ref_store, goto cleanup; } + if (!(type & REF_ISSYMREF)) { + if (!*trailing) { + ret = fsck_report_ref(o, &report, + FSCK_MSG_UNOFFICIAL_FORMATTED_REF, + "misses LF at the end"); + goto cleanup; + } + if (*trailing != '\n' || *(trailing + 1)) { + ret = fsck_report_ref(o, &report, + FSCK_MSG_UNOFFICIAL_FORMATTED_REF, + "has trailing garbage: '%s'", trailing); + goto cleanup; + } + } + cleanup: strbuf_release(&refname); strbuf_release(&ref_content); diff --git a/refs/refs-internal.h b/refs/refs-internal.h index 2313c830d8..73b05f971b 100644 --- a/refs/refs-internal.h +++ b/refs/refs-internal.h @@ -715,7 +715,7 @@ struct ref_store { int parse_loose_ref_contents(const struct git_hash_algo *algop, const char *buf, struct object_id *oid, struct strbuf *referent, unsigned int *type, - int *failure_errno); + const char **trailing, int *failure_errno); /* * Fill in the generic part of refs and add it to our collection of diff --git a/t/t0602-reffiles-fsck.sh b/t/t0602-reffiles-fsck.sh index 628f9bcc46..2f5c4a1926 100755 --- a/t/t0602-reffiles-fsck.sh +++ b/t/t0602-reffiles-fsck.sh @@ -185,6 +185,61 @@ test_expect_success 'regular ref content should be checked (individual)' ' error: refs/heads/a/b/branch-bad: badRefContent: $bad_content EOF rm $branch_dir_prefix/a/b/branch-bad && + test_cmp expect err && + + printf "%s" "$(git rev-parse main)" >$branch_dir_prefix/branch-no-newline && + git refs verify 2>err && + cat >expect <<-EOF && + warning: refs/heads/branch-no-newline: unofficialFormattedRef: misses LF at the end + EOF + rm $branch_dir_prefix/branch-no-newline && + test_cmp expect err && + + printf "%s garbage" "$(git rev-parse main)" >$branch_dir_prefix/branch-garbage && + git refs verify 2>err && + cat >expect <<-EOF && + warning: refs/heads/branch-garbage: unofficialFormattedRef: has trailing garbage: '\'' garbage'\'' + EOF + rm $branch_dir_prefix/branch-garbage && + test_cmp expect err && + + printf "%s\n\n\n" "$(git rev-parse main)" >$tag_dir_prefix/tag-garbage-1 && + git refs verify 2>err && + cat >expect <<-EOF && + warning: refs/tags/tag-garbage-1: unofficialFormattedRef: has trailing garbage: '\'' + + + '\'' + EOF + rm $tag_dir_prefix/tag-garbage-1 && + test_cmp expect err && + + printf "%s\n\n\n garbage" "$(git rev-parse main)" >$tag_dir_prefix/tag-garbage-2 && + git refs verify 2>err && + cat >expect <<-EOF && + warning: refs/tags/tag-garbage-2: unofficialFormattedRef: has trailing garbage: '\'' + + + garbage'\'' + EOF + rm $tag_dir_prefix/tag-garbage-2 && + test_cmp expect err && + + printf "%s garbage\na" "$(git rev-parse main)" >$tag_dir_prefix/tag-garbage-3 && + git refs verify 2>err && + cat >expect <<-EOF && + warning: refs/tags/tag-garbage-3: unofficialFormattedRef: has trailing garbage: '\'' garbage + a'\'' + EOF + rm $tag_dir_prefix/tag-garbage-3 && + test_cmp expect err && + + printf "%s garbage" "$(git rev-parse main)" >$tag_dir_prefix/tag-garbage-4 && + test_must_fail git -c fsck.unofficialFormattedRef=error refs verify 2>err && + cat >expect <<-EOF && + error: refs/tags/tag-garbage-4: unofficialFormattedRef: has trailing garbage: '\'' garbage'\'' + EOF + rm $tag_dir_prefix/tag-garbage-4 && test_cmp expect err ' @@ -203,12 +258,16 @@ test_expect_success 'regular ref content should be checked (aggregate)' ' printf "%s" $bad_content_1 >$tag_dir_prefix/tag-bad-1 && printf "%s" $bad_content_2 >$tag_dir_prefix/tag-bad-2 && printf "%s" $bad_content_3 >$branch_dir_prefix/a/b/branch-bad && + printf "%s" "$(git rev-parse main)" >$branch_dir_prefix/branch-no-newline && + printf "%s garbage" "$(git rev-parse main)" >$branch_dir_prefix/branch-garbage && test_must_fail git refs verify 2>err && cat >expect <<-EOF && error: refs/heads/a/b/branch-bad: badRefContent: $bad_content_3 error: refs/tags/tag-bad-1: badRefContent: $bad_content_1 error: refs/tags/tag-bad-2: badRefContent: $bad_content_2 + warning: refs/heads/branch-garbage: unofficialFormattedRef: has trailing garbage: '\'' garbage'\'' + warning: refs/heads/branch-no-newline: unofficialFormattedRef: misses LF at the end EOF sort err >sorted_err && test_cmp expect sorted_err From patchwork Sun Sep 29 07:16:13 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: shejialuo X-Patchwork-Id: 13814852 Received: from mail-pj1-f41.google.com (mail-pj1-f41.google.com [209.85.216.41]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 1C35841A80 for ; Sun, 29 Sep 2024 07:16:15 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.216.41 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727594177; cv=none; b=g8uT4JODF9SvPbxhHhiD8HBmz3osInXhbZHLUkWD7inGWVnvEmmtg29fh2l2+dgoi2s2xEfcSq+25F+caZyr3+IfHA/yD/ENAXyysflFod2UD+HGn4O8bjh4JNYV03IgHG+nAW+jQynlTMmDNnA/4+iR57UDAfYTjgG0YLo/QYI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727594177; c=relaxed/simple; bh=0c8uPffODKlmSH08Ta2EBndqFdcW+Ckmn+xz0HffdDw=; h=Date:From:To:Cc:Subject:Message-ID:References:MIME-Version: Content-Type:Content-Disposition:In-Reply-To; b=pz0Lv0N/kCGXoGI++TmZt9u2BvR2BRkNMCUV94PHsyKLl4DnhVkHGE06BB3W8znjxeoEFG5/G2dKNXTmHmmEL4BtkJ/i+i0ocomiRP8jh7Qx3uuBUCtf4NUGrELVphZVpEmzjVqBrv4l2sS1XYRyg+KV2wwOYT2y/s/ZPQH96yY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=W1SO5RHH; arc=none smtp.client-ip=209.85.216.41 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="W1SO5RHH" Received: by mail-pj1-f41.google.com with SMTP id 98e67ed59e1d1-2e0a74ce880so2642229a91.2 for ; Sun, 29 Sep 2024 00:16:15 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1727594174; x=1728198974; darn=vger.kernel.org; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:from:to:cc:subject:date:message-id:reply-to; bh=UJF8VeQL2HjnDfKySzYq6faytJz2JwQhTx1KTxguLek=; b=W1SO5RHHJGUpQOCyxSVrIAL8E3RIMLiTgVQVCjYiig+LnlgkBAv5R89kgqLzIOzHq7 yOCsEstyIEejxVFiev9J53HXk6qb9b2n3dT9UPdn9jS/2KQWXnKuH1acQc0RYr/5F5sK vnTRFo31Z6FLuyKzD3ZfsWMnLwi1VZX0heP2Sfcb1sQVafV3qi5duFxq+/ie4PDWTsmQ 2/JGAHFmoW/seAaj3pvaqwv4/++KZMBsvGNzpYmRxyATz3sYHk+ygC4ytPXWUZOKeaxW VvAbUvx1vJzioZaypt2zuWpx1/5Cnr1ihglYBgdQy+czQJVwpPQKbGMhx1TeaAnNeym2 2Ylg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1727594174; x=1728198974; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=UJF8VeQL2HjnDfKySzYq6faytJz2JwQhTx1KTxguLek=; b=oqNVuoSxboiXBYhj5fV971exkUPzGxAVKs/CLSyyo7+d8xgG2hl6+gRDN9nrDF3ZEt TfWqwKSIHAckLQQidaEMJwOxR5ZzLnl9y3PDGAmuiNTLeTW2te76K8XguGVSi0WlnQMj EUQrVx2bAePOkjw+v2x1ts5jufgQFqFwt6tv+C4VBs6k3yp+Jj2RXH0CAP7yXCGBR2Tv P2NcpqjZuSwAdsghqt4GNox3e1vkzni/1yojKpCPuLopR+DtNjH/ku6SfbFfK+rDjRuf /jcSYsgileF7+Sq2iBhwtTVqZAfGQTUuYFiXU+hh0C0WO0XKR7Tt7BXK850RngAKIUu4 /MRw== X-Gm-Message-State: AOJu0Yyqn1b0COHOrYTEei4MNleduDY3nXyJLxKVu+2hJo5FGgybSws9 oqkRsjEcab6qx7ZZvERRO/4GBilNlA/Rs3bEIq6yrtucLuTT6H2RClmg4g== X-Google-Smtp-Source: AGHT+IHS5+l0qBAuEl7hpn0agWcjmq4gHrQP9jSAeU0DqqHu2c7cyV8A9SygK+dGoEUV7zJDLLvqxw== X-Received: by 2002:a17:90a:f991:b0:2cf:fe5d:ea12 with SMTP id 98e67ed59e1d1-2e0b8d5b0fdmr10343167a91.24.1727594174429; Sun, 29 Sep 2024 00:16:14 -0700 (PDT) Received: from localhost ([2605:52c0:1:4cf:6c5a:92ff:fe25:ceff]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-2e0b6c73ec3sm5289966a91.17.2024.09.29.00.16.13 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 29 Sep 2024 00:16:13 -0700 (PDT) Date: Sun, 29 Sep 2024 15:16:13 +0800 From: shejialuo To: git@vger.kernel.org Cc: Patrick Steinhardt , Karthik Nayak , Junio C Hamano Subject: [PATCH v5 5/9] ref: add basic symref content check for files backend Message-ID: References: Precedence: bulk X-Mailing-List: git@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: We have code that checks regular ref contents, but we do not yet check the contents of symbolic refs. By using "parse_loose_ref_content" for symbolic refs, we will get the information of the "referent". We do not need to check the "referent" by opening the file. This is because if "referent" exists in the file system, we will eventually check its correctness by inspecting every file in the "refs" directory. If the "referent" does not exist in the filesystem, this is OK as it is seen as the dangling symref. So we just need to check the "referent" string content. A regular could be accepted as a textual symref if it begins with "ref:", followed by zero or more whitespaces, followed by the full refname, followed only by whitespace characters. However, we always write a single SP after "ref:" and a single LF after the refname. It may seem that we should report a fsck error message when the "referent" does not apply above rules and we should not be so aggressive because third-party reimplementations of Git may have taken advantage of the looser syntax. Put it more specific, we accept the following "referent": 1. "ref: refs/heads/master " 2. "ref: refs/heads/master \n \n" 3. "ref: refs/heads/master\n\n" When introducing the regular ref content checks, we created a new fsck message "unofficialFormattedRef" which exactly represents above situation. So we will reuse this fsck message to write checks to info the user about these situations. But we do not allow any other trailing garbage. The followings are bad symref contents which will be reported as fsck error by "git-fsck(1)". 1. "ref: refs/heads/master garbage\n" 2. "ref: refs/heads/master \n\n\n garbage " And we introduce a new "badReferent(ERROR)" fsck message to report above errors by using "ref.c::check_refname_format". But we cannot just pass the "referent" to this function because the "referent" might contain some whitespaces which will cause "check_refname_format" failing. In order to add checks, we will do the following things: 1. Record the untrimmed length "orig_len" and untrimmed last byte "orig_last_byte". 2. Use "strbuf_rtrim" to trim the whitespaces or newlines to make sure "check_refname_format" won't be failed by them. 3. Use "orig_len" and "orig_last_byte" to check whether the "referent" misses '\n' at the end or it has trailing whitespaces or newlines. Mentored-by: Patrick Steinhardt Mentored-by: Karthik Nayak Signed-off-by: shejialuo --- Documentation/fsck-msgids.txt | 3 ++ fsck.h | 1 + refs/files-backend.c | 40 +++++++++++++++ t/t0602-reffiles-fsck.sh | 97 +++++++++++++++++++++++++++++++++++ 4 files changed, 141 insertions(+) diff --git a/Documentation/fsck-msgids.txt b/Documentation/fsck-msgids.txt index e310b5bce9..e0e4519334 100644 --- a/Documentation/fsck-msgids.txt +++ b/Documentation/fsck-msgids.txt @@ -28,6 +28,9 @@ `badRefName`:: (ERROR) A ref has an invalid format. +`badReferent`:: + (ERROR) The referent of a ref is invalid. + `badTagName`:: (INFO) A tag has an invalid format. diff --git a/fsck.h b/fsck.h index 7420add5c0..979d75cb53 100644 --- a/fsck.h +++ b/fsck.h @@ -34,6 +34,7 @@ enum fsck_msg_type { FUNC(BAD_REF_CONTENT, ERROR) \ FUNC(BAD_REF_FILETYPE, ERROR) \ FUNC(BAD_REF_NAME, ERROR) \ + FUNC(BAD_REFERENT, ERROR) \ FUNC(BAD_TIMEZONE, ERROR) \ FUNC(BAD_TREE, ERROR) \ FUNC(BAD_TREE_SHA1, ERROR) \ diff --git a/refs/files-backend.c b/refs/files-backend.c index b2a790c884..57ac466b64 100644 --- a/refs/files-backend.c +++ b/refs/files-backend.c @@ -3508,6 +3508,43 @@ typedef int (*files_fsck_refs_fn)(struct ref_store *ref_store, const char *refs_check_dir, struct dir_iterator *iter); +static int files_fsck_symref_target(struct fsck_options *o, + struct fsck_ref_report *report, + struct strbuf *referent) +{ + char orig_last_byte; + size_t orig_len; + int ret = 0; + + orig_len = referent->len; + orig_last_byte = referent->buf[orig_len - 1]; + strbuf_rtrim(referent); + + if (check_refname_format(referent->buf, 0)) { + ret = fsck_report_ref(o, report, + FSCK_MSG_BAD_REFERENT, + "points to invalid refname '%s'", referent->buf); + goto out; + } + + + if (referent->len == orig_len || + (referent->len < orig_len && orig_last_byte != '\n')) { + ret = fsck_report_ref(o, report, + FSCK_MSG_UNOFFICIAL_FORMATTED_REF, + "misses LF at the end"); + } + + if (referent->len != orig_len && referent->len != orig_len - 1) { + ret = fsck_report_ref(o, report, + FSCK_MSG_UNOFFICIAL_FORMATTED_REF, + "has trailing whitespaces or newlines"); + } + +out: + return ret; +} + static int files_fsck_refs_content(struct ref_store *ref_store, struct fsck_options *o, const char *refs_check_dir, @@ -3559,6 +3596,9 @@ static int files_fsck_refs_content(struct ref_store *ref_store, "has trailing garbage: '%s'", trailing); goto cleanup; } + } else { + ret = files_fsck_symref_target(o, &report, &referent); + goto cleanup; } cleanup: diff --git a/t/t0602-reffiles-fsck.sh b/t/t0602-reffiles-fsck.sh index 2f5c4a1926..718f6abb71 100755 --- a/t/t0602-reffiles-fsck.sh +++ b/t/t0602-reffiles-fsck.sh @@ -273,4 +273,101 @@ test_expect_success 'regular ref content should be checked (aggregate)' ' test_cmp expect sorted_err ' +test_expect_success 'textual symref content should be checked (individual)' ' + test_when_finished "rm -rf repo" && + git init repo && + branch_dir_prefix=.git/refs/heads && + tag_dir_prefix=.git/refs/tags && + cd repo && + test_commit default && + mkdir -p "$branch_dir_prefix/a/b" && + + printf "ref: refs/heads/branch\n" >$branch_dir_prefix/branch-good && + git refs verify 2>err && + rm $branch_dir_prefix/branch-good && + test_must_be_empty err && + + printf "ref: refs/heads/branch" >$branch_dir_prefix/branch-no-newline-1 && + git refs verify 2>err && + cat >expect <<-EOF && + warning: refs/heads/branch-no-newline-1: unofficialFormattedRef: misses LF at the end + EOF + rm $branch_dir_prefix/branch-no-newline-1 && + test_cmp expect err && + + printf "ref: refs/heads/branch " >$branch_dir_prefix/a/b/branch-trailing-1 && + git refs verify 2>err && + cat >expect <<-EOF && + warning: refs/heads/a/b/branch-trailing-1: unofficialFormattedRef: misses LF at the end + warning: refs/heads/a/b/branch-trailing-1: unofficialFormattedRef: has trailing whitespaces or newlines + EOF + rm $branch_dir_prefix/a/b/branch-trailing-1 && + test_cmp expect err && + + printf "ref: refs/heads/branch\n\n" >$branch_dir_prefix/a/b/branch-trailing-2 && + git refs verify 2>err && + cat >expect <<-EOF && + warning: refs/heads/a/b/branch-trailing-2: unofficialFormattedRef: has trailing whitespaces or newlines + EOF + rm $branch_dir_prefix/a/b/branch-trailing-2 && + test_cmp expect err && + + printf "ref: refs/heads/branch \n" >$branch_dir_prefix/a/b/branch-trailing-3 && + git refs verify 2>err && + cat >expect <<-EOF && + warning: refs/heads/a/b/branch-trailing-3: unofficialFormattedRef: has trailing whitespaces or newlines + EOF + rm $branch_dir_prefix/a/b/branch-trailing-3 && + test_cmp expect err && + + printf "ref: refs/heads/branch \n " >$branch_dir_prefix/a/b/branch-complicated && + git refs verify 2>err && + cat >expect <<-EOF && + warning: refs/heads/a/b/branch-complicated: unofficialFormattedRef: misses LF at the end + warning: refs/heads/a/b/branch-complicated: unofficialFormattedRef: has trailing whitespaces or newlines + EOF + rm $branch_dir_prefix/a/b/branch-complicated && + test_cmp expect err && + + printf "ref: refs/heads/.branch\n" >$branch_dir_prefix/branch-bad-1 && + test_must_fail git refs verify 2>err && + cat >expect <<-EOF && + error: refs/heads/branch-bad-1: badReferent: points to invalid refname '\''refs/heads/.branch'\'' + EOF + rm $branch_dir_prefix/branch-bad-1 && + test_cmp expect err +' + +test_expect_success 'textual symref content should be checked (aggregate)' ' + test_when_finished "rm -rf repo" && + git init repo && + branch_dir_prefix=.git/refs/heads && + tag_dir_prefix=.git/refs/tags && + cd repo && + test_commit default && + mkdir -p "$branch_dir_prefix/a/b" && + + printf "ref: refs/heads/branch\n" >$branch_dir_prefix/branch-good && + printf "ref: refs/heads/branch" >$branch_dir_prefix/branch-no-newline-1 && + printf "ref: refs/heads/branch " >$branch_dir_prefix/a/b/branch-trailing-1 && + printf "ref: refs/heads/branch\n\n" >$branch_dir_prefix/a/b/branch-trailing-2 && + printf "ref: refs/heads/branch \n" >$branch_dir_prefix/a/b/branch-trailing-3 && + printf "ref: refs/heads/branch \n " >$branch_dir_prefix/a/b/branch-complicated && + printf "ref: refs/heads/.branch\n" >$branch_dir_prefix/branch-bad-1 && + + test_must_fail git refs verify 2>err && + cat >expect <<-EOF && + error: refs/heads/branch-bad-1: badReferent: points to invalid refname '\''refs/heads/.branch'\'' + warning: refs/heads/a/b/branch-complicated: unofficialFormattedRef: has trailing whitespaces or newlines + warning: refs/heads/a/b/branch-complicated: unofficialFormattedRef: misses LF at the end + warning: refs/heads/a/b/branch-trailing-1: unofficialFormattedRef: has trailing whitespaces or newlines + warning: refs/heads/a/b/branch-trailing-1: unofficialFormattedRef: misses LF at the end + warning: refs/heads/a/b/branch-trailing-2: unofficialFormattedRef: has trailing whitespaces or newlines + warning: refs/heads/a/b/branch-trailing-3: unofficialFormattedRef: has trailing whitespaces or newlines + warning: refs/heads/branch-no-newline-1: unofficialFormattedRef: misses LF at the end + EOF + sort err >sorted_err && + test_cmp expect sorted_err +' + test_done From patchwork Sun Sep 29 07:16:21 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: shejialuo X-Patchwork-Id: 13814853 Received: from mail-pl1-f175.google.com (mail-pl1-f175.google.com [209.85.214.175]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5D27F13A88A for ; Sun, 29 Sep 2024 07:16:23 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.175 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727594184; cv=none; b=A+NhT2pW0T2ODY35FJkK5brSbQU6mqlPsjZC1AIdiqaFOgPJt/oNzx9WHYPygyf62DlAeOwTPTADanxdnKZbCUaHyRWaz/hIICkBF/t9OQhkQpnwfHl2dqjBhlQeI2/9aNpc8K53aSPllBfm6avm0JsloD8/YfTKajbUmcmVEYM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727594184; c=relaxed/simple; bh=i5WeibbUQfZTyz6ZjfOYSnDJjnxVLNav0adtmjFg7o4=; h=Date:From:To:Cc:Subject:Message-ID:References:MIME-Version: Content-Type:Content-Disposition:In-Reply-To; b=Lz7v4cV26EcPdioRQ8Iyqi2xJGYXQ/C2G54jo+1HKSxJxzKlVckGan0u/6D5imzuwdDwPejvyynJDBzmlBWu1l3UHlpGBKpU3u+A79Cqr9OsPXKW8f3hMOzdGdCwY+3jP9/7ASee82KpUsh4rKG5rLOdnQvJhVqwqDCcp2uRIYg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=BKjGb+iw; arc=none smtp.client-ip=209.85.214.175 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="BKjGb+iw" Received: by mail-pl1-f175.google.com with SMTP id d9443c01a7336-20b7259be6fso2338365ad.0 for ; Sun, 29 Sep 2024 00:16:23 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1727594182; x=1728198982; darn=vger.kernel.org; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:from:to:cc:subject:date:message-id:reply-to; bh=+4/GUTGVkhy9V/5Z584JAAPEXUSNAFGcpnh37F59zOQ=; b=BKjGb+iwQ/EKPcX/t24uJjEjSSc1Dq0dlhuZgQQ9YjK/ZqXKDLzc/qTKZrMOSXR2zq 4ka8oOf8oqP3gaZ22a2J/scjyMnB9Yq3Io4TblfyfW34Gw4ykhgMqSN57EhR+VE6IfkQ UirwoEyzzPPHVkK48pPPxjiTAMcPdFE7BIAUKiNx4Rm7nYuHqtG0aiDEtg/G7pBNyRrJ WmNMD9Xh/G7b1BfOZ0RhHbYIXkSolzoO139XeML+QASXWit2UUI4tfRAcd9OWzK4yjfC A+qNu+6ChZgpQQ7BhsiuQClh45ePn6mxpQiLFPt71IwhR27+EXcumiyyo/ieIqEUmfZb 3Vcw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1727594182; x=1728198982; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=+4/GUTGVkhy9V/5Z584JAAPEXUSNAFGcpnh37F59zOQ=; b=ja0/NYgy9XFvt8p5n50ixc6AjABcNQXeLXHsG6J2Qj+mYXx8devcHfF7nRhytYDz78 xblnOsTZGJlccgs9TIUgbK6mPR5tBAEi8MqbyzzzzQwuI5g3DGeGcwzW2NY2P0iyYb9X cBSJv78/qUg4XBei1aAt50qQxL9zwooDz9RF1ExCy+JlaIUqa84klwyvqUKE8JBX9H71 /kCBgVTGYvJDxJPlMjc4hTl8t75LbR73scNd/9SPRQ0XdXNtoEDCyM0+xUvEQ2iNnAJ2 y/W9gaKYdahLQ08XWKYiTzPoiw+rs7ocTMCVy3ZzsUjGpen2L17a1ktpTIdhLwWdyWFi uJtQ== X-Gm-Message-State: AOJu0YyCd+B8uN/5VWXrX/NAj+qjLhSbmrV5SLvo+YI6cLddn/hOaVhE rb5mnr6A1qlwkdbwNKixT18rVeKq20eCDlyGoaK6Wrt1qtYIaingZ1owng== X-Google-Smtp-Source: AGHT+IFHzcyboVI8CEolzlNZtvv1TiK/TTVSqUMCkmtSnbZ+MTVCNnj2QnzO/c97JHzm7Pw6ZyIQTg== X-Received: by 2002:a17:902:dad2:b0:207:45f1:d1fe with SMTP id d9443c01a7336-20b37c120ccmr132649965ad.61.1727594181836; Sun, 29 Sep 2024 00:16:21 -0700 (PDT) Received: from localhost ([2605:52c0:1:4cf:6c5a:92ff:fe25:ceff]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-20b37d60dfesm35914525ad.52.2024.09.29.00.16.20 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 29 Sep 2024 00:16:21 -0700 (PDT) Date: Sun, 29 Sep 2024 15:16:21 +0800 From: shejialuo To: git@vger.kernel.org Cc: Patrick Steinhardt , Karthik Nayak , Junio C Hamano Subject: [PATCH v5 6/9] ref: add escape check for the referent of symref Message-ID: References: Precedence: bulk X-Mailing-List: git@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: Ideally, we want to the users use "git symbolic-ref" to create symrefs instead of writing raw contents into the filesystem. However, "git symbolic-ref" is strict with the refname but not strict with the referent. For example, we can make the "referent" located at the "$(gitdir)/logs/aaa" and manually write the content into this where we can still successfully parse this symref by using "git rev-parse". $ git init repo && cd repo && git commit --allow-empty -mx $ git symbolic-ref refs/heads/test logs/aaa $ echo $(git rev-parse HEAD) > .git/logs/aaa $ git rev-parse test We may need to add some restrictions for "referent" parameter when using "git symbolic-ref" to create symrefs because ideally all the nonpeudo-refs should be located under the "refs" directory and we may tighten this in the future. In order to tell the user we may tighten the "escape" situation, create a new fsck message "escapeReferent" to notify the user that this may become an error in the future. Mentored-by: Patrick Steinhardt Mentored-by: Karthik Nayak Signed-off-by: shejialuo --- Documentation/fsck-msgids.txt | 8 ++++++++ fsck.h | 1 + refs/files-backend.c | 7 +++++++ t/t0602-reffiles-fsck.sh | 18 ++++++++++++++++++ 4 files changed, 34 insertions(+) diff --git a/Documentation/fsck-msgids.txt b/Documentation/fsck-msgids.txt index e0e4519334..223974057d 100644 --- a/Documentation/fsck-msgids.txt +++ b/Documentation/fsck-msgids.txt @@ -52,6 +52,14 @@ `emptyName`:: (WARN) A path contains an empty name. +`escapeReferent`:: + (INFO) The referent of a symref is outside the "ref" directory. + Although we allow create a symref pointing to the referent which + is outside the "ref" by using `git symbolic-ref`, we may tighten + the rule in the future. Report to the git@vger.kernel.org + mailing list if you see this error, as we need to know what tools + created such a file. + `extraHeaderEntry`:: (IGNORE) Extra headers found after `tagger`. diff --git a/fsck.h b/fsck.h index 979d75cb53..5ecee0fda5 100644 --- a/fsck.h +++ b/fsck.h @@ -80,6 +80,7 @@ enum fsck_msg_type { FUNC(LARGE_PATHNAME, WARN) \ /* infos (reported as warnings, but ignored by default) */ \ FUNC(BAD_FILEMODE, INFO) \ + FUNC(ESCAPE_REFERENT, INFO) \ FUNC(GITMODULES_PARSE, INFO) \ FUNC(GITIGNORE_SYMLINK, INFO) \ FUNC(GITATTRIBUTES_SYMLINK, INFO) \ diff --git a/refs/files-backend.c b/refs/files-backend.c index 57ac466b64..bd215c8d08 100644 --- a/refs/files-backend.c +++ b/refs/files-backend.c @@ -3520,6 +3520,13 @@ static int files_fsck_symref_target(struct fsck_options *o, orig_last_byte = referent->buf[orig_len - 1]; strbuf_rtrim(referent); + if (!starts_with(referent->buf, "refs/")) { + ret = fsck_report_ref(o, report, + FSCK_MSG_ESCAPE_REFERENT, + "referent '%s' is outside of refs/", + referent->buf); + } + if (check_refname_format(referent->buf, 0)) { ret = fsck_report_ref(o, report, FSCK_MSG_BAD_REFERENT, diff --git a/t/t0602-reffiles-fsck.sh b/t/t0602-reffiles-fsck.sh index 718f6abb71..585f562245 100755 --- a/t/t0602-reffiles-fsck.sh +++ b/t/t0602-reffiles-fsck.sh @@ -370,4 +370,22 @@ test_expect_success 'textual symref content should be checked (aggregate)' ' test_cmp expect sorted_err ' +test_expect_success 'textual symref should be checked whether it is escaped' ' + test_when_finished "rm -rf repo" && + git init repo && + branch_dir_prefix=.git/refs/heads && + tag_dir_prefix=.git/refs/tags && + cd repo && + test_commit default && + mkdir -p "$branch_dir_prefix/a/b" && + + printf "ref: refs-back/heads/main\n" >$branch_dir_prefix/branch-bad-1 && + git refs verify 2>err && + cat >expect <<-EOF && + warning: refs/heads/branch-bad-1: escapeReferent: referent '\''refs-back/heads/main'\'' is outside of refs/ + EOF + rm $branch_dir_prefix/branch-bad-1 && + test_cmp expect err +' + test_done From patchwork Sun Sep 29 07:17:01 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: shejialuo X-Patchwork-Id: 13814854 Received: from mail-pl1-f171.google.com (mail-pl1-f171.google.com [209.85.214.171]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A33AE2B9BB for ; Sun, 29 Sep 2024 07:17:03 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.171 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727594225; cv=none; b=d//2T8i3IP5DLy0NA1vsgUhMmxoQwZpVIOjtXXqQagJAcfBKDDkK0Rujum/PalcXbRFZtsxkFpaJeCcTUP3sgr9r+M0lQ+JSTX/8mZXA2JKW3XjEGVNJdWVPLSWIgC9pXUBujyfC5KJuhPeMoisy52bnTSIMrzH+70P+IHtBelM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727594225; c=relaxed/simple; bh=f5cCi/MWnCZNhzkbRN4ADpPfkkkFsHvOd2cEbON0c1g=; h=Date:From:To:Cc:Subject:Message-ID:References:MIME-Version: Content-Type:Content-Disposition:In-Reply-To; b=rWUKUkCRSW87lmgkAiCwbbQ815UbsSjnkRRb3QyxSVjF39RPp74riirR+S+kY/wn4aA6DiKfXpCd3IT5qruvA30jX7ZlQ/V3e4gAUgyOFzAu8raLu7lgiXt4WCGBojpNhIM2gMS2UQl4pu8Gt/cGkyjLhaUrQ6oV+NyP3LdyeLA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=SpFkN+7o; arc=none smtp.client-ip=209.85.214.171 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="SpFkN+7o" Received: by mail-pl1-f171.google.com with SMTP id d9443c01a7336-20aff65aa37so28167395ad.1 for ; Sun, 29 Sep 2024 00:17:03 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1727594222; x=1728199022; darn=vger.kernel.org; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:from:to:cc:subject:date:message-id:reply-to; bh=k4FKk7fMGVLekQs1kc9jbFG/WsuMnmm1pp+fm9kPZ8M=; b=SpFkN+7oces5FC7WtYmKITGyo/Oaysu1FYoVfhDXOkt1h5OR3LsZsAk6RnAPlMmu6H p4zHyqofO6jS6GIgDXEOh1AHgi3roz35JZPeIYomIZQMGvXmUVl53wsJUXPwFW8v2oc8 TQBfuiKVNuqucCO/r1nxxC592rrTTWOw97yKLjwrMJQKgdnCcSRiusHHhLuU8dpacw+Z tQupEqNqW0LFdfiSqu1De65nzT/8Ve90cIUbdjeVHImIPf7+GOwuWEzps0H47UNzHcT0 N7KU8egk8LZrNz04Rgt7NT02HYISGPD3nMNQ8iQWo7OX9njM4lAD61eawPVXcEzQ8JHJ TXRA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1727594222; x=1728199022; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=k4FKk7fMGVLekQs1kc9jbFG/WsuMnmm1pp+fm9kPZ8M=; b=G8zvNbvt6/mtrcfbzAFhyKyoumajG6hQ75cRCEx9oqHfVTLu5tzfm+jXJFoUgdURIh Es/pina7Xo1dcB+unwAfETdLb7E7T3YpFwFlmWJQJI5c5ySc2W/crMx2FJjbOyQxjX3s 3PZ1Hw/1yv4Lg1oTz+NtAmfC6XgFYsSVA8eBc1/hcIMimeCwqNyxwMwFNjRcWoz+IG1g WZ650A117QdpWWRt8WBML5CeI0uH2Iowd9lf9IvvP2tNbxcLqkbCnzSShhK18Tj5L53x a8DVxeo4SPX85hZAzax3vTbDwEkxp+shduIGbU8f6pa35MpzeZiHJSfu7lAOntlJCz3N UBeQ== X-Gm-Message-State: AOJu0YyDNjGnzpXRuixiQ2Q30Rt3wiZYSycIPMwqa3f0B7gfOudDfM/D s9EvSCuufgE9cZamZxGrV0vxicbUfRDhQeD3s+j44YesU6NPSelrPehZiw== X-Google-Smtp-Source: AGHT+IFNt1oeL1qUv3pdrpJLgXoUduGG0S8CB3fe37+cnhPgBT9aa48qLBlc7eL/lnPtZzoHBGIu/g== X-Received: by 2002:a17:902:e844:b0:20b:65a8:917c with SMTP id d9443c01a7336-20b65a923c0mr40236945ad.10.1727594222543; Sun, 29 Sep 2024 00:17:02 -0700 (PDT) Received: from localhost ([2605:52c0:1:4cf:6c5a:92ff:fe25:ceff]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-20b54c6d95fsm20981115ad.222.2024.09.29.00.17.01 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 29 Sep 2024 00:17:02 -0700 (PDT) Date: Sun, 29 Sep 2024 15:17:01 +0800 From: shejialuo To: git@vger.kernel.org Cc: Patrick Steinhardt , Karthik Nayak , Junio C Hamano Subject: [PATCH v5 7/9] ref: enhance escape situation for worktrees Message-ID: References: Precedence: bulk X-Mailing-List: git@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: We do allow users to use "git symbolic-ref" to create symrefs which point to one of the linked worktrees from the primary worktree or one of the linked worktrees. We should not info the user about the escape for above situation. So, enhance "files_fsck_symref_target" function to check whether the "referent" starts with the "worktrees/" to make sure that we won't warn the user when symrefs point to "referent" in the linked worktrees. Mentored-by: Patrick Steinhardt Mentored-by: Karthik Nayak Signed-off-by: shejialuo --- refs/files-backend.c | 5 +++-- t/t0602-reffiles-fsck.sh | 34 +++++++++++++++++++++++++++++++++- 2 files changed, 36 insertions(+), 3 deletions(-) diff --git a/refs/files-backend.c b/refs/files-backend.c index bd215c8d08..1182bca108 100644 --- a/refs/files-backend.c +++ b/refs/files-backend.c @@ -3520,10 +3520,11 @@ static int files_fsck_symref_target(struct fsck_options *o, orig_last_byte = referent->buf[orig_len - 1]; strbuf_rtrim(referent); - if (!starts_with(referent->buf, "refs/")) { + if (!starts_with(referent->buf, "refs/") && + !starts_with(referent->buf, "worktrees/")) { ret = fsck_report_ref(o, report, FSCK_MSG_ESCAPE_REFERENT, - "referent '%s' is outside of refs/", + "referent '%s' is outside of refs/ or worktrees/", referent->buf); } diff --git a/t/t0602-reffiles-fsck.sh b/t/t0602-reffiles-fsck.sh index 585f562245..936448f780 100755 --- a/t/t0602-reffiles-fsck.sh +++ b/t/t0602-reffiles-fsck.sh @@ -382,10 +382,42 @@ test_expect_success 'textual symref should be checked whether it is escaped' ' printf "ref: refs-back/heads/main\n" >$branch_dir_prefix/branch-bad-1 && git refs verify 2>err && cat >expect <<-EOF && - warning: refs/heads/branch-bad-1: escapeReferent: referent '\''refs-back/heads/main'\'' is outside of refs/ + warning: refs/heads/branch-bad-1: escapeReferent: referent '\''refs-back/heads/main'\'' is outside of refs/ or worktrees/ EOF rm $branch_dir_prefix/branch-bad-1 && test_cmp expect err ' +test_expect_success 'textual symref escape check should work with worktrees' ' + test_when_finished "rm -rf repo" && + git init repo && + cd repo && + test_commit default && + git branch branch-1 && + git branch branch-2 && + git branch branch-3 && + git worktree add ./worktree-1 branch-2 && + git worktree add ./worktree-2 branch-3 && + + ( + cd worktree-1 && + git branch refs/worktree/w1-branch && + git symbolic-ref refs/worktree/branch-4 refs/heads/branch-1 && + git symbolic-ref refs/worktree/branch-5 worktrees/worktree-2/refs/worktree/w2-branch + ) && + ( + cd worktree-2 && + git branch refs/worktree/w2-branch && + git symbolic-ref refs/worktree/branch-4 refs/heads/branch-1 && + git symbolic-ref refs/worktree/branch-5 worktrees/worktree-1/refs/worktree/w1-branch + ) && + + + git symbolic-ref refs/heads/branch-5 worktrees/worktree-1/refs/worktree/w1-branch && + git symbolic-ref refs/heads/branch-6 worktrees/worktree-2/refs/worktree/w2-branch && + + git refs verify 2>err && + test_must_be_empty err +' + test_done From patchwork Sun Sep 29 07:17:18 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: shejialuo X-Patchwork-Id: 13814855 Received: from mail-pl1-f174.google.com (mail-pl1-f174.google.com [209.85.214.174]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 871F841A80 for ; Sun, 29 Sep 2024 07:17:21 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.174 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727594242; cv=none; b=cOtnR4d3OuvvekzMzM3hdDGMFWPktPqtfrxwWNT2VXNI26U1j2zBp18fkH0iMPBFqaRdwo6/TpvevpENOGdhkOdVzSYkkhNqLVwuymktbr6UuEXNWTkaJaa8FQIHiVTSfPRQ4+OJ312NiOAz5mIowRTw/ZTBYlMd2QGXPsZ+5W0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727594242; c=relaxed/simple; bh=ooiR5gK4TTbqyFkShGRd5x1jM3o3sZmcWH6YybD51dc=; h=Date:From:To:Cc:Subject:Message-ID:References:MIME-Version: Content-Type:Content-Disposition:In-Reply-To; b=LpfD2TRd/8dVp8PJxV2UlOd9+fzDNfi2me5A0ccRza73mFT27evihyHG1yEtKwpgQ5oKdBswgKq2/LFQWg1z6PNAVM5NnX908zQfsQtTTmoceOLxoGH0Czy/mVsb+lfKNVGgd4d3arsUDIFNKA5F50b/CoqPN1yZtr+8L/XUVP0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=DF9eUnc7; arc=none smtp.client-ip=209.85.214.174 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="DF9eUnc7" Received: by mail-pl1-f174.google.com with SMTP id d9443c01a7336-205722ba00cso31023635ad.0 for ; Sun, 29 Sep 2024 00:17:21 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1727594240; x=1728199040; darn=vger.kernel.org; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:from:to:cc:subject:date:message-id:reply-to; bh=7z19YvUHUUyJtN2aTo7tINeCHtO/uAVDcxKH49xO8ps=; b=DF9eUnc7GRwcdGZW0IylIy6K2kuH9WN3tJ2DJkHndPH2RngFcEShDpUq+lM9gwSmCG ocbP0s5GEWlQyUdEs76Px+sqI+EeyiZSBxnN0ncHIEEbU8dsDXKIdxy2LTTnpAl+Gs2x X5iDD1292IFj0bkjdw6qE0/OFlywuGNiRvoNAxjN0A+eo7Nguq3Zu8RbuQD/LrVeXNBc amLe3VoylcGTCdJMn2zFisRfU70B9tjw8r+YGYURD7lGPYxgpotKwfsmW3Tq/LOhJSXP EqQ6CQ2szCAzKJM2TAhYV53884+pq8P0QQ7od2bSBQeKbjAX6oz4PVFXPOfpgcNO23pM Mvww== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1727594240; x=1728199040; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=7z19YvUHUUyJtN2aTo7tINeCHtO/uAVDcxKH49xO8ps=; b=I4VXkgIWxRJ3AVnJYpXAD/9yEHqZyLRwpyW1X5z4aXKTPaa47YOKDSTSIbyKWq+NmJ aDdGeTlgRkUJUqu3ua+xSQid7AGF3PDBpBtDhqMEP70eWkqwSGillLLf/8scbtMpN4XY mOXAgR9iwr1TlIX6+bSsneM/9ivHT1o39/JoIiZ4FeX8qWY150GamI1Olcf5ctWcahSZ QR8cC4KGHsMCymqVLlAfmAWWDthWAqjhEKuHccp7+cPjYHJr8jsPt96gH07sTSQrpfWU RF1c6F2jTIs0nbyZR8jg5dMJ50Sa0/nAtB+EdaWtl2pvrm9SzUZ/iFf07thUTSRvq7ev 1OSw== X-Gm-Message-State: AOJu0Yx5pRh7McseQ1jtwZnOjWDAA7r01+7WvqmR2QbeVGf5UkzJJdNb MCBoUdHfuBlkuz6tq/0Pvmzj4UAYxfrpM6IZpneK1NsKGI1IYTi7/OcgWA== X-Google-Smtp-Source: AGHT+IGpuxTAIhyOA3ev7OZVbSMd9TfSzUQLLCrYEFG1rPHBhlBquROyXzqH382KkWd22/EGmXiOZg== X-Received: by 2002:a17:902:d506:b0:20b:61c0:43ed with SMTP id d9443c01a7336-20b61c0457fmr53139375ad.30.1727594239550; Sun, 29 Sep 2024 00:17:19 -0700 (PDT) Received: from localhost ([2605:52c0:1:4cf:6c5a:92ff:fe25:ceff]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-20b37d5ef7fsm35821755ad.22.2024.09.29.00.17.18 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 29 Sep 2024 00:17:19 -0700 (PDT) Date: Sun, 29 Sep 2024 15:17:18 +0800 From: shejialuo To: git@vger.kernel.org Cc: Patrick Steinhardt , Karthik Nayak , Junio C Hamano Subject: [PATCH v5 8/9] t0602: add ref content checks for worktrees Message-ID: References: Precedence: bulk X-Mailing-List: git@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: We have already added content tests, but we don't have tests when there are worktrees in the repository. Add a new test to test all the functionalities we have added for worktrees. Mentored-by: Patrick Steinhardt Mentored-by: Karthik Nayak Signed-off-by: shejialuo --- t/t0602-reffiles-fsck.sh | 66 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/t/t0602-reffiles-fsck.sh b/t/t0602-reffiles-fsck.sh index 936448f780..97bbcd3f13 100755 --- a/t/t0602-reffiles-fsck.sh +++ b/t/t0602-reffiles-fsck.sh @@ -420,4 +420,70 @@ test_expect_success 'textual symref escape check should work with worktrees' ' test_must_be_empty err ' +test_expect_success 'all textual symref checks should work with worktrees' ' + test_when_finished "rm -rf repo" && + git init repo && + cd repo && + test_commit default && + git branch branch-1 && + git branch branch-2 && + git branch branch-3 && + git worktree add ./worktree-1 branch-2 && + git worktree add ./worktree-2 branch-3 && + worktree1_refdir_prefix=.git/worktrees/worktree-1/refs/worktree && + worktree2_refdir_prefix=.git/worktrees/worktree-2/refs/worktree && + + ( + cd worktree-1 && + git update-ref refs/worktree/branch-4 refs/heads/branch-1 + ) && + ( + cd worktree-2 && + git update-ref refs/worktree/branch-4 refs/heads/branch-1 + ) && + + bad_content_1=$(git rev-parse HEAD)x && + bad_content_2=xfsazqfxcadas && + bad_content_3=Xfsazqfxcadas && + + printf "%s" $bad_content_1 >$worktree1_refdir_prefix/bad-branch-1 && + test_must_fail git refs verify 2>err && + cat >expect <<-EOF && + error: refs/worktree/bad-branch-1: badRefContent: $bad_content_1 + EOF + rm $worktree1_refdir_prefix/bad-branch-1 && + test_cmp expect err && + + printf "%s" $bad_content_2 >$worktree2_refdir_prefix/bad-branch-2 && + test_must_fail git refs verify 2>err && + cat >expect <<-EOF && + error: refs/worktree/bad-branch-2: badRefContent: $bad_content_2 + EOF + rm $worktree2_refdir_prefix/bad-branch-2 && + test_cmp expect err && + + printf "%s" $bad_content_3 >$worktree1_refdir_prefix/bad-branch-3 && + test_must_fail git refs verify 2>err && + cat >expect <<-EOF && + error: refs/worktree/bad-branch-3: badRefContent: $bad_content_3 + EOF + rm $worktree1_refdir_prefix/bad-branch-3 && + test_cmp expect err && + + printf "%s" "$(git rev-parse HEAD)" >$worktree1_refdir_prefix/branch-no-newline && + git refs verify 2>err && + cat >expect <<-EOF && + warning: refs/worktree/branch-no-newline: unofficialFormattedRef: misses LF at the end + EOF + rm $worktree1_refdir_prefix/branch-no-newline && + test_cmp expect err && + + printf "%s garbage" "$(git rev-parse HEAD)" >$worktree2_refdir_prefix/branch-garbage && + git refs verify 2>err && + cat >expect <<-EOF && + warning: refs/worktree/branch-garbage: unofficialFormattedRef: has trailing garbage: '\'' garbage'\'' + EOF + rm $worktree2_refdir_prefix/branch-garbage +' + test_done From patchwork Sun Sep 29 07:17:36 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: shejialuo X-Patchwork-Id: 13814856 Received: from mail-pl1-f171.google.com (mail-pl1-f171.google.com [209.85.214.171]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 757692B9BB for ; Sun, 29 Sep 2024 07:17:38 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.171 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727594260; cv=none; b=Bx0gWPSCurrs/aC04WB3iqezGKwGrZkIVHeRxmjquKc1dSsypdDMnnRBQp6O0tFxmkelSEums/7hHpzvpbF5HnOdQ0Ts7duE8XiO4uh+KrFDwVA0bI1spD6isQAO6MxnWW66dSYOBAcSQv/CShlUEkiDnX6VOBsapagBwJhVpZ8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727594260; c=relaxed/simple; bh=SksFYVlGFykWr6RcyKhXT2JXUP1FQCT+NApR4NzgrRY=; h=Date:From:To:Cc:Subject:Message-ID:References:MIME-Version: Content-Type:Content-Disposition:In-Reply-To; b=qa8LnWcD9ST9npLRCSmiKnwY0q1f3CqhUFNpSeCswt7bNUIAhx50t8iaBUEpg252dGCmU9PJm32/hnHdiNEaP1BYu0A1aSEvYCiQbDUO5IrImBARC/okGza8kjfrtsLXBvi8kzcH0uZasZJjVo/q7kZEWnTwc2WxS/wbB45Bnss= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=CZz0nJhQ; arc=none smtp.client-ip=209.85.214.171 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="CZz0nJhQ" Received: by mail-pl1-f171.google.com with SMTP id d9443c01a7336-207115e3056so29037575ad.2 for ; Sun, 29 Sep 2024 00:17:38 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1727594257; x=1728199057; darn=vger.kernel.org; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:from:to:cc:subject:date:message-id:reply-to; bh=WbjzJ6W6f2dDRq6ZRP9I+cPiZ/sENA99+TsujPV7mHg=; b=CZz0nJhQxd8jNArlyIhfLFxCwf+Wwe0bjnxB30SznbHEZJ2PDmGRn4oneLEX1zUIm+ GGY0Nvo1aBA4rIhaQ6uPRFRHaoJSoZdSaItaZMHXpb6vsnpmOG9YwZt2t5GrLwsmfIgb uiOU6bQuT/Z5XfsP7ZMDe4xQhE9xkzmzuFVh6vSYo8/if/OQvanPFCMSZc9BdDQF0f7P 7hTi8p2nz0oDsJfxLLITux1+8n5eazsl09B67tqwvid4NobCqU4KoIVLjJq1qI+Sn8Z/ 0eKYCXh7qpMmsF0dkrdqEZclTXhTqIG6Hkf3u9LW0TKHNlsaibH7++kFZunmZRmz5AGg Mxnw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1727594257; x=1728199057; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=WbjzJ6W6f2dDRq6ZRP9I+cPiZ/sENA99+TsujPV7mHg=; b=KLHaYXAFjiKk5WIDKgBgW+rx7n3MJuyhSpGpsH8BKFMrx7typRhc/SNfR69iuBoPTF jzHVWNVmeHOMs37DtAwG0RR6XS5hFWiQu50RhlTVgCMKEE06RCbsjMKXRwlnDOdpBnCz ReyfAMl3XQt+IPhRXy0L7piQK5sRneX9dUIcuoxW7iSYJtK2AvqDXdOLzgmkQNrqIS1v Pphe6pkHBjEhLX5wOmZVrH+9V/1J//DAQ/MXbFpsYMM4oMGpFezQzF1wxIPhN37JETaP uoC3pvZy8pUZmPc4RLBjpta+eqHq5cfQX3YHfEO1o3Gy53AQDBuZP2WPyBekAk9Eqbs5 a9bg== X-Gm-Message-State: AOJu0Ywpk0hT5trqSidGh1XraPH78T1heRSpOfu+NqZvdTtAL0NnLvOu 3O/t5lu+kDGISeeF7+ZK6UXXn/FRB05Hb80eUqARAjtgHm4+QZTjaLOO2Q== X-Google-Smtp-Source: AGHT+IEUHCwctBjKX3StZJ3rTJVeyylZenu5Op/AuMHSiiAyfNEi5BfZaWiz9dN2/umuB5TlJKdTrw== X-Received: by 2002:a17:903:32cc:b0:20b:7e0d:91 with SMTP id d9443c01a7336-20b7e0d0336mr4097365ad.50.1727594257166; Sun, 29 Sep 2024 00:17:37 -0700 (PDT) Received: from localhost ([2605:52c0:1:4cf:6c5a:92ff:fe25:ceff]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-20b37e64045sm35747165ad.272.2024.09.29.00.17.36 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 29 Sep 2024 00:17:36 -0700 (PDT) Date: Sun, 29 Sep 2024 15:17:36 +0800 From: shejialuo To: git@vger.kernel.org Cc: Patrick Steinhardt , Karthik Nayak , Junio C Hamano Subject: [PATCH v5 9/9] ref: add symlink ref content check for files backend Message-ID: References: Precedence: bulk X-Mailing-List: git@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: We have already introduced "files_fsck_symref_target". We should reuse this function to handle the symrefs which use legacy symbolic links. We should not check the trailing garbage for symbolic refs. Add a new parameter "symbolic_link" to disable some checks which should only be executed for textual symrefs. We firstly use the "strbuf_add_real_path" to resolve the symlink and get the absolute path as the "ref_content" which the symlink ref points to. Then we can use the absolute "abs_gitdir" of the "gitdir" and then combine "ref_content" and "abs_gitdir" to extract the relative path "referent". If "ref_content" is outside of "gitdir", we just use the "ref_content" as the "referent". Thus, we can reuse "files_fsck_symref_target" function to seamlessly check the symlink refs. Because we consider deprecating writing the symbolic links. We first need to asses whether symbolic links may still be used. So, add a new fsck message "symlinkRef(INFO)" to tell the user be aware of this information. Mentored-by: Patrick Steinhardt Mentored-by: Karthik Nayak Signed-off-by: shejialuo --- Documentation/fsck-msgids.txt | 6 +++++ fsck.h | 1 + refs/files-backend.c | 43 ++++++++++++++++++++++++++++----- t/t0602-reffiles-fsck.sh | 45 +++++++++++++++++++++++++++++++++++ 4 files changed, 89 insertions(+), 6 deletions(-) diff --git a/Documentation/fsck-msgids.txt b/Documentation/fsck-msgids.txt index 223974057d..ffe9d6a2f6 100644 --- a/Documentation/fsck-msgids.txt +++ b/Documentation/fsck-msgids.txt @@ -184,6 +184,12 @@ `nullSha1`:: (WARN) Tree contains entries pointing to a null sha1. +`symlinkRef`:: + (INFO) A symbolic link is used as a symref. Report to the + git@vger.kernel.org mailing list if you see this error, as we + are assessing the feasibility of dropping the support to drop + creating symblinks as symrefs. + `treeNotSorted`:: (ERROR) A tree is not properly sorted. diff --git a/fsck.h b/fsck.h index 5ecee0fda5..f1da5c8a77 100644 --- a/fsck.h +++ b/fsck.h @@ -87,6 +87,7 @@ enum fsck_msg_type { FUNC(MAILMAP_SYMLINK, INFO) \ FUNC(BAD_TAG_NAME, INFO) \ FUNC(MISSING_TAGGER_ENTRY, INFO) \ + FUNC(SYMLINK_REF, INFO) \ FUNC(UNOFFICIAL_FORMATTED_REF, INFO) \ /* ignored (elevated when requested) */ \ FUNC(EXTRA_HEADER_ENTRY, IGNORE) diff --git a/refs/files-backend.c b/refs/files-backend.c index 1182bca108..5a5327a146 100644 --- a/refs/files-backend.c +++ b/refs/files-backend.c @@ -1,6 +1,7 @@ #define USE_THE_REPOSITORY_VARIABLE #include "../git-compat-util.h" +#include "../abspath.h" #include "../config.h" #include "../copy.h" #include "../environment.h" @@ -3510,15 +3511,18 @@ typedef int (*files_fsck_refs_fn)(struct ref_store *ref_store, static int files_fsck_symref_target(struct fsck_options *o, struct fsck_ref_report *report, - struct strbuf *referent) + struct strbuf *referent, + unsigned int symbolic_link) { char orig_last_byte; size_t orig_len; int ret = 0; - orig_len = referent->len; - orig_last_byte = referent->buf[orig_len - 1]; - strbuf_rtrim(referent); + if (!symbolic_link) { + orig_len = referent->len; + orig_last_byte = referent->buf[orig_len - 1]; + strbuf_rtrim(referent); + } if (!starts_with(referent->buf, "refs/") && !starts_with(referent->buf, "worktrees/")) { @@ -3535,6 +3539,9 @@ static int files_fsck_symref_target(struct fsck_options *o, goto out; } + if (symbolic_link) + goto out; + if (referent->len == orig_len || (referent->len < orig_len && orig_last_byte != '\n')) { @@ -3559,6 +3566,7 @@ static int files_fsck_refs_content(struct ref_store *ref_store, struct dir_iterator *iter) { struct strbuf ref_content = STRBUF_INIT; + struct strbuf abs_gitdir = STRBUF_INIT; struct strbuf referent = STRBUF_INIT; struct strbuf refname = STRBUF_INIT; struct fsck_ref_report report = { 0 }; @@ -3571,8 +3579,30 @@ static int files_fsck_refs_content(struct ref_store *ref_store, strbuf_addf(&refname, "%s/%s", refs_check_dir, iter->relative_path); report.path = refname.buf; - if (S_ISLNK(iter->st.st_mode)) + if (S_ISLNK(iter->st.st_mode)) { + const char* relative_referent_path = NULL; + + ret = fsck_report_ref(o, &report, + FSCK_MSG_SYMLINK_REF, + "use deprecated symbolic link for symref"); + + strbuf_add_absolute_path(&abs_gitdir, ref_store->gitdir); + strbuf_normalize_path(&abs_gitdir); + if (!is_dir_sep(abs_gitdir.buf[abs_gitdir.len - 1])) + strbuf_addch(&abs_gitdir, '/'); + + strbuf_add_real_path(&ref_content, iter->path.buf); + skip_prefix(ref_content.buf, abs_gitdir.buf, + &relative_referent_path); + + if (relative_referent_path) + strbuf_addstr(&referent, relative_referent_path); + else + strbuf_addbuf(&referent, &ref_content); + + ret += files_fsck_symref_target(o, &report, &referent, 1); goto cleanup; + } if (strbuf_read_file(&ref_content, iter->path.buf, 0) < 0) { ret = fsck_report_ref(o, &report, @@ -3605,7 +3635,7 @@ static int files_fsck_refs_content(struct ref_store *ref_store, goto cleanup; } } else { - ret = files_fsck_symref_target(o, &report, &referent); + ret = files_fsck_symref_target(o, &report, &referent, 0); goto cleanup; } @@ -3613,6 +3643,7 @@ static int files_fsck_refs_content(struct ref_store *ref_store, strbuf_release(&refname); strbuf_release(&ref_content); strbuf_release(&referent); + strbuf_release(&abs_gitdir); return ret; } diff --git a/t/t0602-reffiles-fsck.sh b/t/t0602-reffiles-fsck.sh index 97bbcd3f13..be4c064b3c 100755 --- a/t/t0602-reffiles-fsck.sh +++ b/t/t0602-reffiles-fsck.sh @@ -486,4 +486,49 @@ test_expect_success 'all textual symref checks should work with worktrees' ' rm $worktree2_refdir_prefix/branch-garbage ' +test_expect_success SYMLINKS 'symlink symref content should be checked (individual)' ' + test_when_finished "rm -rf repo" && + git init repo && + branch_dir_prefix=.git/refs/heads && + tag_dir_prefix=.git/refs/tags && + cd repo && + test_commit default && + mkdir -p "$branch_dir_prefix/a/b" && + + ln -sf ./main $branch_dir_prefix/branch-symbolic-good && + git refs verify 2>err && + cat >expect <<-EOF && + warning: refs/heads/branch-symbolic-good: symlinkRef: use deprecated symbolic link for symref + EOF + rm $branch_dir_prefix/branch-symbolic-good && + test_cmp expect err && + + ln -sf ../../logs/branch-escape $branch_dir_prefix/branch-symbolic && + git refs verify 2>err && + cat >expect <<-EOF && + warning: refs/heads/branch-symbolic: symlinkRef: use deprecated symbolic link for symref + warning: refs/heads/branch-symbolic: escapeReferent: referent '\''logs/branch-escape'\'' is outside of refs/ or worktrees/ + EOF + rm $branch_dir_prefix/branch-symbolic && + test_cmp expect err && + + ln -sf ./"branch space" $branch_dir_prefix/branch-symbolic-bad && + test_must_fail git refs verify 2>err && + cat >expect <<-EOF && + warning: refs/heads/branch-symbolic-bad: symlinkRef: use deprecated symbolic link for symref + error: refs/heads/branch-symbolic-bad: badReferent: points to invalid refname '\''refs/heads/branch space'\'' + EOF + rm $branch_dir_prefix/branch-symbolic-bad && + test_cmp expect err && + + ln -sf ./".tag" $tag_dir_prefix/tag-symbolic-1 && + test_must_fail git refs verify 2>err && + cat >expect <<-EOF && + warning: refs/tags/tag-symbolic-1: symlinkRef: use deprecated symbolic link for symref + error: refs/tags/tag-symbolic-1: badReferent: points to invalid refname '\''refs/tags/.tag'\'' + EOF + rm $tag_dir_prefix/tag-symbolic-1 && + test_cmp expect err +' + test_done