From patchwork Mon Jun 17 09:03:47 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Miguel_=C3=81ngel_Pastor_Olivar?= X-Patchwork-Id: 13700345 Received: from mail-lf1-f53.google.com (mail-lf1-f53.google.com [209.85.167.53]) (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 D5CC2374D9 for ; Mon, 17 Jun 2024 09:03:52 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.167.53 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1718615034; cv=none; b=fv93U+0k6hs27Ry5pGcvI7arE2iOmSMMccbfGW8nypbl3xhkQK1yXr80My6Lu4QDcnSKcngdvBke1E9vV32JVj9m9/9LFLn4u/PxdN0lC5LoyDfwh7yu1uKRDipwhT2gk06+hcuNc0SY0rqlBvT1jm3igKzuaMThEYfPzF8sRO0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1718615034; c=relaxed/simple; bh=ehbenQxsdavUEI9yIW4vkNOH5l/s+m7737KhE5jqgAw=; h=Message-Id:In-Reply-To:References:From:Date:Subject:MIME-Version: Content-Type:To:Cc; b=N/w+01N/j/27ldUA1dVZbSLVmPOizui1vwW0vwO7hcKOYzFQ3MmaTMatpSVZTu7Bp7wQho4nApAuISh9TFzxGb1bdAXeCZzCE/4T4SMQwxELpYAJRYuxzdsEzwv//CmlEVxuljGYYOBNnVnCmVV4utnd9r4vW2Mcxylb+h5zUuw= 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=g0OBHorA; arc=none smtp.client-ip=209.85.167.53 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="g0OBHorA" Received: by mail-lf1-f53.google.com with SMTP id 2adb3069b0e04-52c94cf4c9bso4959238e87.2 for ; Mon, 17 Jun 2024 02:03:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1718615030; x=1719219830; darn=vger.kernel.org; h=cc:to:fcc:content-transfer-encoding:mime-version:subject:date:from :references:in-reply-to:message-id:from:to:cc:subject:date :message-id:reply-to; bh=hIvtaGI/youAs6lDvm5FvvrUzP/n2N0dEWVsonkbeQU=; b=g0OBHorADiaHFpAeXta6gBI3Ed4gyxzHVTNH0HQXnTAFdIWcVbpsnm0RqOWkH4EMrQ K+yDngHVthE3rMXkpDHq4a9AkqMACQmsGmWorc8kQmnE2G1bVTAdC9AOQXqfnPobLhdX Tw4ZHoZXkb5GxZc7eU018CU3F/qBYcJ2EaHT2VVPDEwRMX2rPzAH4IN8gh57oJfpFm2U Gjtmysykl966Whl4reWOtmdHdDCOKWnYElRFXK1JC9FPDyjGMZk4cRWIaOTDePdl7gVs dEnzXwFXhDavZWsuRmeCik3e7q7QnSd/9pFjWCc4BTEhnvBYdnIgvA6MuvpuJLM6QgzY a/mg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1718615030; x=1719219830; h=cc:to:fcc:content-transfer-encoding:mime-version:subject:date:from :references:in-reply-to:message-id:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=hIvtaGI/youAs6lDvm5FvvrUzP/n2N0dEWVsonkbeQU=; b=dFh/PsqTX82y/mL6Llwt2fdCrCDJ+E1L2Exdh9jBONysrV8mOUoFq3V5YIsAwrwKCP v6lYm2uXAVuTYEquXS4dsa0Dhc23PBPp0aSudpRXxI0JtQx+vry338wvWxln9tv9RpDo V1voXCghGuUsx3a9Zk+gnQ0W1yeyBEe7EZEF0zyOpZvCkmZRnp7otJdgcDUhltJJNqhT AE1t0MKtYRf1Tw+1LFFXEJxLn90zpCUYP1wnwveDRoUrjv6hqlUP5oid3fZQNMSBLbP3 knUus+424Ftu8gXjU0v/J4/pK/Nnq+wflZifdOcDCi6tbl3QX8905pzK4s4/wMkSFJC2 zY7g== X-Gm-Message-State: AOJu0YxQ0IW15esUQ/NAh3CQhcQ61fTk/FemWzTbOzWTbhDfH58bKd/Y JCg/kj6QccKOYb1+/AYN3hXcfb4WFZ2AJ6RHdn1UmS3hShzokBjH6dehOQ== X-Google-Smtp-Source: AGHT+IEgmXtI5ovcmjSsJoE4s5EOIhDfShOoPv/rzgqYViwLZYr+NzZXzbsUAxXpCOW6npN698bzHg== X-Received: by 2002:ac2:5a44:0:b0:52b:bc4c:5c35 with SMTP id 2adb3069b0e04-52ca6e6e7fcmr7409640e87.39.1718615030289; Mon, 17 Jun 2024 02:03:50 -0700 (PDT) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-360751037absm11331908f8f.91.2024.06.17.02.03.49 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 17 Jun 2024 02:03:49 -0700 (PDT) Message-Id: In-Reply-To: References: Date: Mon, 17 Jun 2024 09:03:47 +0000 Subject: [PATCH 1/2] cat-file: configurable number of symlink resolutions Precedence: bulk X-Mailing-List: git@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Fcc: Sent To: git@vger.kernel.org Cc: Miguel =?utf-8?b?w4FuZ2Vs?= Pastor Olivar , =?utf-8?q?Miguel_=C3=81ngel_Pastor_Olivar?= From: =?utf-8?q?Miguel_=C3=81ngel_Pastor_Olivar?= From: =?UTF-8?q?Miguel=20=C3=81ngel=20Pastor=20Olivar?= Sometimes, it can be useful to limit the number of symlink resolutions performed while looking for a tree entry. The goal is to provide the ability to resolve up to a particular depth, instead of reaching the end of the link chain. The current code already provides a limit to the maximum number of resolutions that can be performed (GET_TREE_ENTRY_FOLLOW_SYMLINKS_MAX_LINKS). This patch introduces a new config setting to make the previous property configurable. No logical changes are introduced in this patch Signed-off-by: Miguel Ángel Pastor Olivar --- Documentation/config/core.txt | 5 +++++ config.c | 5 +++++ environment.c | 1 + environment.h | 1 + t/t1006-cat-file.sh | 17 +++++++++++++++++ tree-walk.c | 7 ++++++- 6 files changed, 35 insertions(+), 1 deletion(-) diff --git a/Documentation/config/core.txt b/Documentation/config/core.txt index 93d65e1dfd2..ca2d1eede52 100644 --- a/Documentation/config/core.txt +++ b/Documentation/config/core.txt @@ -757,3 +757,8 @@ core.maxTreeDepth:: tree (e.g., "a/b/cde/f" has a depth of 4). This is a fail-safe to allow Git to abort cleanly, and should not generally need to be adjusted. The default is 4096. + +core.maxSymlinkDepth:: + The maximum number of symlinks Git is willing to resolve while + looking for a tree entry. + The default is GET_TREE_ENTRY_FOLLOW_SYMLINKS_MAX_LINKS. \ No newline at end of file diff --git a/config.c b/config.c index abce05b7744..d69e9a3ae6b 100644 --- a/config.c +++ b/config.c @@ -1682,6 +1682,11 @@ static int git_default_core_config(const char *var, const char *value, return 0; } + if (!strcmp(var, "core.maxsymlinkdepth")) { + max_symlink_depth = git_config_int(var, value, ctx->kvi); + return 0; + } + /* Add other config variables here and to Documentation/config.txt. */ return platform_core_config(var, value, ctx, cb); } diff --git a/environment.c b/environment.c index 701d5151354..6d7a5001eb1 100644 --- a/environment.c +++ b/environment.c @@ -95,6 +95,7 @@ int max_allowed_tree_depth = #else 2048; #endif +int max_symlink_depth = -1; #ifndef PROTECT_HFS_DEFAULT #define PROTECT_HFS_DEFAULT 0 diff --git a/environment.h b/environment.h index e9f01d4d11c..ea39c2887b1 100644 --- a/environment.h +++ b/environment.h @@ -141,6 +141,7 @@ extern size_t delta_base_cache_limit; extern unsigned long big_file_threshold; extern unsigned long pack_size_limit_cfg; extern int max_allowed_tree_depth; +extern int max_symlink_depth; /* * Accessors for the core.sharedrepository config which lazy-load the value diff --git a/t/t1006-cat-file.sh b/t/t1006-cat-file.sh index e12b2219721..fd7ab1d1eff 100755 --- a/t/t1006-cat-file.sh +++ b/t/t1006-cat-file.sh @@ -878,6 +878,9 @@ test_expect_success 'cat-file -t and -s on corrupt loose object' ' test_expect_success 'prep for symlink tests' ' echo_without_newline "$hello_content" >morx && test_ln_s_add morx same-dir-link && + test_ln_s_add same-dir-link link-to-symlink-1 && + test_ln_s_add link-to-symlink-1 link-to-symlink-2 && + test_ln_s_add link-to-symlink-2 link-to-symlink-3 && test_ln_s_add dir link-to-dir && test_ln_s_add ../fleem out-of-repo-link && test_ln_s_add .. out-of-repo-link-dir && @@ -1096,6 +1099,20 @@ test_expect_success 'git cat-file --batch --follow-symlink returns correct sha a test_cmp expect actual ' +test_expect_success 'git cat-file --batch --follow-symlink stop resolving symlinks' ' + printf "loop 22\nHEAD:link-to-symlink-3\n">expect && + printf 'HEAD:link-to-symlink-3' | git -c core.maxsymlinkdepth=1 cat-file --batch="%(objectname) %(objecttype) %(objectsize)" --follow-symlinks > actual && + test_cmp expect actual && + printf 'HEAD:link-to-symlink-3' | git -c core.maxsymlinkdepth=2 cat-file --batch="%(objectname) %(objecttype) %(objectsize)" --follow-symlinks > actual && + test_cmp expect actual && + printf 'HEAD:link-to-symlink-3' | git -c core.maxsymlinkdepth=3 cat-file --batch="%(objectname) %(objecttype) %(objectsize)" --follow-symlinks > actual && + test_cmp expect actual && + oid=$(git rev-parse HEAD:morx) && + printf "${oid} blob 11\nHello World\n" >expect && + printf 'HEAD:link-to-symlink-3' | git -c core.maxsymlinkdepth=4 cat-file --batch="%(objectname) %(objecttype) %(objectsize)" --follow-symlinks > actual && + test_cmp expect actual +' + test_expect_success 'cat-file --batch-all-objects shows all objects' ' # make new repos so we know the full set of objects; we will # also make sure that there are some packed and some loose diff --git a/tree-walk.c b/tree-walk.c index 6565d9ad993..3ec2302309e 100644 --- a/tree-walk.c +++ b/tree-walk.c @@ -664,7 +664,12 @@ enum get_oid_result get_tree_entry_follow_symlinks(struct repository *r, struct object_id current_tree_oid; struct strbuf namebuf = STRBUF_INIT; struct tree_desc t; - int follows_remaining = GET_TREE_ENTRY_FOLLOW_SYMLINKS_MAX_LINKS; + int follows_remaining = + max_symlink_depth > -1 && + max_symlink_depth <= + GET_TREE_ENTRY_FOLLOW_SYMLINKS_MAX_LINKS ? + max_symlink_depth : + GET_TREE_ENTRY_FOLLOW_SYMLINKS_MAX_LINKS; init_tree_desc(&t, NULL, NULL, 0UL); strbuf_addstr(&namebuf, name); From patchwork Mon Jun 17 09:03:48 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Miguel_=C3=81ngel_Pastor_Olivar?= X-Patchwork-Id: 13700346 Received: from mail-wm1-f44.google.com (mail-wm1-f44.google.com [209.85.128.44]) (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 9F3B618F2CE for ; Mon, 17 Jun 2024 09:03:53 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.44 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1718615035; cv=none; b=pS+pC82DaxU4YuUA9eRq7LPFlqC5PLcVLzG2H+ST14y8578LCxU/BObKgfejoc5mbNcg/w0RLBg6jEqVUK5/gMMsd1a8zQ1SJ8nJWCKzECB0VEDo1iInKCAgNyxIJ7wUGkzOBuu2gwkUIXB9PIDUJ2KxoBLKcCcHRJiJboghphE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1718615035; c=relaxed/simple; bh=Qgd78TN6am1o79+7mwACkb4xv/A7R8gnG/Hlm4v186Y=; h=Message-Id:In-Reply-To:References:From:Date:Subject:MIME-Version: Content-Type:To:Cc; b=H6dGRqy0+zDH/jLvoT7V90XoBcOB9iAeyVDLbSMZPnslmX+l/1Aq1bUUyFGni2WWQ5CwX1ajFTlS6RHZopvE8nxeJYQEjiLvMzoCYWuQBjn+UWwRWGNPJk+ObJiEtCo2O6sPhWIAmSZn2btPfgdSGBDG9MQR2H279PluTGeVk8o= 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=UU5peD72; arc=none smtp.client-ip=209.85.128.44 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="UU5peD72" Received: by mail-wm1-f44.google.com with SMTP id 5b1f17b1804b1-4217c7eb6b4so36250595e9.2 for ; Mon, 17 Jun 2024 02:03:53 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1718615031; x=1719219831; darn=vger.kernel.org; h=cc:to:fcc:content-transfer-encoding:mime-version:subject:date:from :references:in-reply-to:message-id:from:to:cc:subject:date :message-id:reply-to; bh=kuZFZqPODb4Up1nJ6cQCuica5gYsxVUc3Mo6xQqIUf8=; b=UU5peD72aRs9989vt+y2yhR+/5pJmvBQup48XtbxcG/A1iSaC4fbGXorr83ADo6waW KE1rXyyMYgRskIBPcmN+rBsyUxWZDx3wpROuiwL7X0ckCv+elyGGnGPUXMpePMOxa4we lctp0+GjX/6MKjbdvQySn6MO+qHpwHpCeBGlXxAVwOs2/B+MfYtMPVmcezIFqpXRsvSx NWbfFDmw6V+yi2zhQiQN5Hm2SUl2m1zpKZCcEunx9xk896T5tQmPIiy8Kq/Bv4qOMP3M B3zFJJ75bJeZQXmzDDULdqQMg5JL8lfnO3cicVcW7bfgee0vgjuszjqMBvzmPEP2PCrJ kJCg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1718615031; x=1719219831; h=cc:to:fcc:content-transfer-encoding:mime-version:subject:date:from :references:in-reply-to:message-id:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=kuZFZqPODb4Up1nJ6cQCuica5gYsxVUc3Mo6xQqIUf8=; b=dcRqnUzqZ+DiKqDZ+HOIEtkh5EkH6XJNebLG1CWFyIoGRm5ZMGGOinje9NIVzrGZvM 8WfcetNPFqM8T81kKsTqermvyb2SZXHsOSuy2xJgFYmdiKdmMEkuDgM/AQKHikLrgclp js5YCai96v++8eRhuZ0bl2rHQymCsqsMo4llLE1vopF0Iv0s+svqXmKjpUGjYAZLxNdd W+ju9c5ZLSir/4iM2SqN5QnGLz/h3Tkb/rNBT6zsk+bblWY4LptkvVVSRIQ68TWQOzK1 x3+e/YW9P+aFLj5dQFuYYC+OXpA1eDGY3cCYxIvJGyEz4pSmVSM2qMiJcTrmw5rf2mue xehw== X-Gm-Message-State: AOJu0YyGceGSHrsatYkoTwoIpos1LZg1YBWI5Lrd24lzjvpzIs7AFVn6 PdE/Wmw2PMaMUAAvVB4JNYHn2L+oW1scdA3hXqBgKMfY9Bmon0owTyGFPQ== X-Google-Smtp-Source: AGHT+IHTWgcKefLFjDeUMohoSqDvrHAsYeuTqDCqbUiwVBcaGq++MEXJkaIGiqCgouUsel7aU+RtfA== X-Received: by 2002:a05:600c:4ca9:b0:422:52c3:7fe0 with SMTP id 5b1f17b1804b1-4230482c1e9mr77903155e9.22.1718615031052; Mon, 17 Jun 2024 02:03:51 -0700 (PDT) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-422f5f33be5sm155663135e9.2.2024.06.17.02.03.50 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 17 Jun 2024 02:03:50 -0700 (PDT) Message-Id: <5de72c45e767c4d704503c8cd5c8e6dce4ea04d6.1718615028.git.gitgitgadget@gmail.com> In-Reply-To: References: Date: Mon, 17 Jun 2024 09:03:48 +0000 Subject: [PATCH 2/2] cat-file: configurable "best effort mode" for symlink resolution Precedence: bulk X-Mailing-List: git@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Fcc: Sent To: git@vger.kernel.org Cc: Miguel =?utf-8?b?w4FuZ2Vs?= Pastor Olivar , =?utf-8?q?Miguel_=C3=81ngel_Pastor_Olivar?= From: =?utf-8?q?Miguel_=C3=81ngel_Pastor_Olivar?= From: =?UTF-8?q?Miguel=20=C3=81ngel=20Pastor=20Olivar?= This patch introduces a new "best effort mode" where the object found at resolution step N is returned. If we've reached the end of the chain, the returned object will be the file at the end of the chain, however, if, after n resolutions we haven't reached the end of the chain, the returned object will represent a symlink The goal is to extend the symlink resolution process and provide the ability to return the object found at the designated depth instead of returning an error. The current code already provides a limit to the maximum number of resolutions that can be performed and something similar to this is returned back to the caller: loop SP LF LF With the new config setting we are looking to return the actual information of the object where the resolution stopped. Something similar to: blob \ndata\n Signed-off-by: Miguel Ángel Pastor Olivar --- Documentation/config/core.txt | 16 +++++++++++++++- config.c | 13 +++++++++++++ environment.c | 2 ++ environment.h | 7 +++++++ t/t1006-cat-file.sh | 29 +++++++++++++++++++++++++++++ tree-walk.c | 11 +++++++++++ 6 files changed, 77 insertions(+), 1 deletion(-) diff --git a/Documentation/config/core.txt b/Documentation/config/core.txt index ca2d1eede52..706f316c89e 100644 --- a/Documentation/config/core.txt +++ b/Documentation/config/core.txt @@ -761,4 +761,18 @@ core.maxTreeDepth:: core.maxSymlinkDepth:: The maximum number of symlinks Git is willing to resolve while looking for a tree entry. - The default is GET_TREE_ENTRY_FOLLOW_SYMLINKS_MAX_LINKS. \ No newline at end of file + The default is GET_TREE_ENTRY_FOLLOW_SYMLINKS_MAX_LINKS. + +core.symlinkResolutionMode:: + The result returned by the symlink resolution process when + core.maxSymlinkDepth is reached. When set to "error" + ` + loop SP LF + LF + ` is returned. + If `best-effort` is set, the resolution process will return + something like: + ` + blob 120000\nname\n + ` + The default is "error". \ No newline at end of file diff --git a/config.c b/config.c index d69e9a3ae6b..fa753565e68 100644 --- a/config.c +++ b/config.c @@ -1687,6 +1687,19 @@ static int git_default_core_config(const char *var, const char *value, return 0; } + if (!strcmp(var, "core.symlinkresolutionmode")) { + if (!value) + symlink_resolution_mode = SYMLINK_RESOLUTION_MODE_ERROR; + if (!strcmp(value, "error")) + symlink_resolution_mode = SYMLINK_RESOLUTION_MODE_ERROR; + else if (!strcmp(value, "best-effort")) + symlink_resolution_mode = + SYMLINK_RESOLUTION_MODE_BEST_EFFORT; + else + warning(_("ignoring unknown core.symlinkresolutionmode value '%s'"), + value); + } + /* Add other config variables here and to Documentation/config.txt. */ return platform_core_config(var, value, ctx, cb); } diff --git a/environment.c b/environment.c index 6d7a5001eb1..a497331f2bc 100644 --- a/environment.c +++ b/environment.c @@ -96,6 +96,8 @@ int max_allowed_tree_depth = 2048; #endif int max_symlink_depth = -1; +enum symlink_resolution_mode symlink_resolution_mode = + SYMLINK_RESOLUTION_MODE_ERROR; #ifndef PROTECT_HFS_DEFAULT #define PROTECT_HFS_DEFAULT 0 diff --git a/environment.h b/environment.h index ea39c2887b1..5a6eebb061b 100644 --- a/environment.h +++ b/environment.h @@ -143,6 +143,13 @@ extern unsigned long pack_size_limit_cfg; extern int max_allowed_tree_depth; extern int max_symlink_depth; +enum symlink_resolution_mode { + SYMLINK_RESOLUTION_MODE_ERROR = 0, + SYMLINK_RESOLUTION_MODE_BEST_EFFORT +}; + +extern enum symlink_resolution_mode symlink_resolution_mode; + /* * Accessors for the core.sharedrepository config which lazy-load the value * from the config (if not already set). The "reset" function can be diff --git a/t/t1006-cat-file.sh b/t/t1006-cat-file.sh index fd7ab1d1eff..c1d807a0d7f 100755 --- a/t/t1006-cat-file.sh +++ b/t/t1006-cat-file.sh @@ -1113,6 +1113,35 @@ test_expect_success 'git cat-file --batch --follow-symlink stop resolving symlin test_cmp expect actual ' +test_expect_success 'git cat-file --batch --follow-symlink stop resolving symlink at designated depth with error mode config' ' + printf "loop 22\nHEAD:link-to-symlink-3\n">expect && + printf 'HEAD:link-to-symlink-3' | git -c core.maxsymlinkdepth=1 -c core.symlinkresolutionmode=error cat-file --batch="%(objectname) %(objecttype) %(objectsize)" --follow-symlinks > actual && + test_cmp expect actual && + printf 'HEAD:link-to-symlink-3' | git -c core.maxsymlinkdepth=2 -c core.symlinkresolutionmode=error cat-file --batch="%(objectname) %(objecttype) %(objectsize)" --follow-symlinks > actual && + test_cmp expect actual && + printf 'HEAD:link-to-symlink-3' | git -c core.maxsymlinkdepth=3 -c core.symlinkresolutionmode=error cat-file --batch="%(objectname) %(objecttype) %(objectsize)" --follow-symlinks > actual && + test_cmp expect actual && + oid=$(git rev-parse HEAD:morx) && + printf "${oid} blob 11\nHello World\n" >expect && + printf 'HEAD:link-to-symlink-3' | git -c core.maxsymlinkdepth=4 cat-file --batch="%(objectname) %(objecttype) %(objectsize)" --follow-symlinks > actual && + test_cmp expect actual +' + +test_expect_success 'git cat-file --batch --follow-symlink return object info at designated depth' ' + oid=$(git rev-parse HEAD:link-to-symlink-1) && + printf "${oid} blob 13\nsame-dir-link\n" >expect && + printf 'HEAD:link-to-symlink-1' | git -c core.maxsymlinkdepth=1 -c core.symlinkresolutionmode=best-effort cat-file --batch="%(objectname) %(objecttype) %(objectsize)" --follow-symlinks >actual && + test_cmp expect actual && + oid=$(git rev-parse HEAD:same-dir-link) && + printf "${oid} blob 4\nmorx\n" > expect && + printf 'HEAD:link-to-symlink-1' | git -c core.maxsymlinkdepth=2 -c core.symlinkresolutionmode=best-effort cat-file --batch="%(objectname) %(objecttype) %(objectsize)" --follow-symlinks >actual && + test_cmp expect actual && + oid=$(git rev-parse HEAD:morx) && + printf "${oid} blob 11\nHello World\n" > expect && + printf 'HEAD:link-to-symlink-1' | git -c core.maxsymlinkdepth=3 -c core.symlinkresolutionmode=best-effort cat-file --batch="%(objectname) %(objecttype) %(objectsize)" --follow-symlinks >actual && + test_cmp expect actual +' + test_expect_success 'cat-file --batch-all-objects shows all objects' ' # make new repos so we know the full set of objects; we will # also make sure that there are some packed and some loose diff --git a/tree-walk.c b/tree-walk.c index 3ec2302309e..ee861fd6351 100644 --- a/tree-walk.c +++ b/tree-walk.c @@ -821,6 +821,17 @@ enum get_oid_result get_tree_entry_follow_symlinks(struct repository *r, contents_start = contents; parent = &parents[parents_nr - 1]; + + if (follows_remaining == 0 && + symlink_resolution_mode == + SYMLINK_RESOLUTION_MODE_BEST_EFFORT) { + strbuf_addstr(result_path, contents); + oidcpy(result, ¤t_tree_oid); + free(contents); + retval = FOUND; + goto done; + } + init_tree_desc(&t, &parent->oid, parent->tree, parent->size); strbuf_splice(&namebuf, 0, len, contents_start, link_len);