From patchwork Tue Dec 28 21:32:18 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Derrick Stolee X-Patchwork-Id: 12700641 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 6440FC433EF for ; Tue, 28 Dec 2021 21:32:31 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230093AbhL1Vca (ORCPT ); Tue, 28 Dec 2021 16:32:30 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37162 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229953AbhL1Vc1 (ORCPT ); Tue, 28 Dec 2021 16:32:27 -0500 Received: from mail-wr1-x42a.google.com (mail-wr1-x42a.google.com [IPv6:2a00:1450:4864:20::42a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5D6EFC06173E for ; Tue, 28 Dec 2021 13:32:27 -0800 (PST) Received: by mail-wr1-x42a.google.com with SMTP id t26so40584635wrb.4 for ; Tue, 28 Dec 2021 13:32:27 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=message-id:in-reply-to:references:from:date:subject:fcc :content-transfer-encoding:mime-version:to:cc; bh=lgCF+kpvTSY66fmxxp714TIlFEsS63dT8obB4mIHTF4=; b=RAmrbi4CfxzbKbx7zCu4MXd0pDmcH2UB194NA0En5B/ZS5+Y+4qCIuZAZaqOMXribW vBhJW3lPPe4JVTent8UiIydc4wMWcuCJr+U9PAyENsXD29a+coN1//eaJ7/cJqxTYNx9 wzvJ7GW3GXrW0WtDABckpVVoid7x9wRTSI6r6knACIy0eLBhi7f9LzaFAUQPqb5wyb8J tskkRJiXW6SN6sC7cgF5AAFWosgSjTHrXQP/nq0EEmK/uUdsHfvjcGsYdLHzQ6PVI3oJ LOmNj1jTB3jNmDJorWFq/S6/lKi5n5uwq0TBgr1zNQVB84dRdk54jKhHfCVf+7j5kW8b Cb3w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:message-id:in-reply-to:references:from:date :subject:fcc:content-transfer-encoding:mime-version:to:cc; bh=lgCF+kpvTSY66fmxxp714TIlFEsS63dT8obB4mIHTF4=; b=jxWRyH2toP7UL6sUdWx++m88NX3faDSfC6i+cP1/jSPOAESQ5q/o/GV6XRKqSGsA81 00iwm+/4GgLf6Hb9zeJjXieZHxuLA7zQ5ewO5qgzWL+EPNDNbPr731ad6FuEHYfH2lmj 4p7D1GNmj63bmeaEON6cczHR1xFtwHuDt02zpySAPe0MDYurdsT+onlK37UxnkZBPSXu 8f58fhOgeCums/0IdyDeJV+Z5zkdeb3inD3zhyfGlc3r7QzXRp/eauH/8gNbQlaSi5n2 InCpWP2O4SPbGSA1ZcoExzA/tSHmjyKjKY8J7JJjZQNlapt62bPH8RWlhwZwa4W5kh6e dOVQ== X-Gm-Message-State: AOAM531D5uVX2Mx+TlMVFqBv5Su2X5MDUhVZWSb9WlhB3lL+mYxGe9TJ 0JOMKliuW0fOIRg75BVd+Hw1bhawjgY= X-Google-Smtp-Source: ABdhPJwbQh0H7qXwNnChO6Tr2UA5o0Lnx/YdhsXUvVKjPejo/k2G5BvEjpu9FX2FCQYFq5MkcyR8kA== X-Received: by 2002:a05:6000:2c8:: with SMTP id o8mr17937017wry.84.1640727145688; Tue, 28 Dec 2021 13:32:25 -0800 (PST) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id k7sm19099543wrg.105.2021.12.28.13.32.25 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 28 Dec 2021 13:32:25 -0800 (PST) Message-Id: <749ba67d21e0dacfaadc0fabdbab5e46e3d5bfcc.1640727143.git.gitgitgadget@gmail.com> In-Reply-To: References: Date: Tue, 28 Dec 2021 21:32:18 +0000 Subject: [PATCH v3 1/6] setup: use a repository when upgrading format Fcc: Sent MIME-Version: 1.0 To: git@vger.kernel.org Cc: stolee@gmail.com, sunshine@sunshineco.com, allred.sean@gmail.com, gitster@pobox.com, Elijah Newren , Derrick Stolee , Derrick Stolee Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Derrick Stolee From: Derrick Stolee The upgrade_repository_format() helper previously was not aware of the possibility of multiple repositories. Add a 'struct repository *' parameter so it is possible to call it from a specific repository. The implementation already referred to the_repository in one place, so that is an easy replacement. The use of git_config_set() is replaced with a call to repo_config_set(). Signed-off-by: Derrick Stolee --- builtin/sparse-checkout.c | 2 +- list-objects-filter-options.c | 2 +- repository.h | 2 +- setup.c | 6 +++--- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/builtin/sparse-checkout.c b/builtin/sparse-checkout.c index 679c1070368..08f8df2648c 100644 --- a/builtin/sparse-checkout.c +++ b/builtin/sparse-checkout.c @@ -361,7 +361,7 @@ static int set_config(enum sparse_checkout_mode mode) { const char *config_path; - if (upgrade_repository_format(1) < 0) + if (upgrade_repository_format(the_repository, 1) < 0) die(_("unable to upgrade repository format to enable worktreeConfig")); if (git_config_set_gently("extensions.worktreeConfig", "true")) { error(_("failed to set extensions.worktreeConfig setting")); diff --git a/list-objects-filter-options.c b/list-objects-filter-options.c index fd8d59f653a..6e21d12045e 100644 --- a/list-objects-filter-options.c +++ b/list-objects-filter-options.c @@ -372,7 +372,7 @@ void partial_clone_register( */ return; } else { - if (upgrade_repository_format(1) < 0) + if (upgrade_repository_format(the_repository, 1) < 0) die(_("unable to upgrade repository format to support partial clone")); /* Add promisor config for the remote */ diff --git a/repository.h b/repository.h index 98f95834706..d3fc1f7689d 100644 --- a/repository.h +++ b/repository.h @@ -215,6 +215,6 @@ void prepare_repo_settings(struct repository *r); * Return 1 if upgrade repository format to target_version succeeded, * 0 if no upgrade is necessary, and -1 when upgrade is not possible. */ -int upgrade_repository_format(int target_version); +int upgrade_repository_format(struct repository *, int target_version); #endif /* REPOSITORY_H */ diff --git a/setup.c b/setup.c index 347d7181ae9..90516664ce5 100644 --- a/setup.c +++ b/setup.c @@ -595,14 +595,14 @@ static int check_repository_format_gently(const char *gitdir, struct repository_ return 0; } -int upgrade_repository_format(int target_version) +int upgrade_repository_format(struct repository *r, int target_version) { struct strbuf sb = STRBUF_INIT; struct strbuf err = STRBUF_INIT; struct strbuf repo_version = STRBUF_INIT; struct repository_format repo_fmt = REPOSITORY_FORMAT_INIT; - strbuf_git_common_path(&sb, the_repository, "config"); + strbuf_git_common_path(&sb, r, "config"); read_repository_format(&repo_fmt, sb.buf); strbuf_release(&sb); @@ -621,7 +621,7 @@ int upgrade_repository_format(int target_version) repo_fmt.unknown_extensions.items[0].string); strbuf_addf(&repo_version, "%d", target_version); - git_config_set("core.repositoryformatversion", repo_version.buf); + repo_config_set(r, "core.repositoryformatversion", repo_version.buf); strbuf_release(&repo_version); return 1; } From patchwork Tue Dec 28 21:32:19 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Derrick Stolee X-Patchwork-Id: 12700642 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 81FBAC433F5 for ; Tue, 28 Dec 2021 21:32:36 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230198AbhL1Vcg (ORCPT ); Tue, 28 Dec 2021 16:32:36 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37170 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229974AbhL1Vc2 (ORCPT ); Tue, 28 Dec 2021 16:32:28 -0500 Received: from mail-wr1-x42c.google.com (mail-wr1-x42c.google.com [IPv6:2a00:1450:4864:20::42c]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1EAFDC061574 for ; Tue, 28 Dec 2021 13:32:28 -0800 (PST) Received: by mail-wr1-x42c.google.com with SMTP id t26so40584662wrb.4 for ; Tue, 28 Dec 2021 13:32:28 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=message-id:in-reply-to:references:from:date:subject:fcc :content-transfer-encoding:mime-version:to:cc; bh=ZHHVedAp8W2JuzN7+w7ympjfdkaHVwsh7qOjVXFvtD0=; b=TEVK/qFTbx1tSC6XxNa2dDh3ledPkG7h6frTig3fw289zbh2K7AEWIls9jGAh7vZae nbKMlBwabsifa8WNprMSOCsfWhJMEpCHlPtjmfcHPVlp9m9QdXT8O6fLNXn4jMnAvgl5 XmqOtI1A0xhQ76mvCw2ZbB3aOOMjbEVrMCwgOytiDQFVy3szmFFUek4v3gVOGF5oHrKD NwubTNTTCyoXIX3lgwyMUyApIqfIek358EfVBS8bBA00Lj8+jklAel+DSB9hT4DDrLnA QO5Abr0IecRgt50ImyDBNv/GBH1/8kMKoDqECBBlK8g0QyS8IK5Tazh/ykRX6VPxdjEg fj3A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:message-id:in-reply-to:references:from:date :subject:fcc:content-transfer-encoding:mime-version:to:cc; bh=ZHHVedAp8W2JuzN7+w7ympjfdkaHVwsh7qOjVXFvtD0=; b=OsXYz0+eJZxuXiD79WJuW8//RCjLifj1qAXv/T0MMpQUriedxIxpQ3WZRsOmwk7XtB ip6KctiDxKpbDst+YmUmQnaLwNydPuqyLkwWX9OtXj2P9t4Kj92hHUIVecRwyzo7Q0/S ARGUcyCfwTNiZjrrSoZ0ZmIWywqtvXfTAO17c3qAU+IpBEaOHiKe9AXLQvvcTRuW0/Fr 2giJ/SyNnSC6ArunS2yPD0cM0pRAHMGl7pv+sWY6FqQn8AiScJFjSLnrUUExnD3pXSvK muw4KNS/JDZpvltuWFyTXaJ1hLcOvJfIjksBYFpDpkyffToHvS95PXCCEqSauawCujvW rDPw== X-Gm-Message-State: AOAM531ObJWrB7awjKzQ5pi8jPlYHrh185YO0P0x6jdUFOyfJMeVbVh7 IJmwECmKLtrfBg+HKB5WLsODIFTyA/0= X-Google-Smtp-Source: ABdhPJwP+LGDXycIt2XuUulUtv2186Nostun+cwXfHaHxIeC7vuroJiBQEzl2xsnW46AMd+FyZ8+ZQ== X-Received: by 2002:a05:6000:18af:: with SMTP id b15mr18222277wri.616.1640727146575; Tue, 28 Dec 2021 13:32:26 -0800 (PST) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id l16sm21302399wrx.117.2021.12.28.13.32.25 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 28 Dec 2021 13:32:26 -0800 (PST) Message-Id: <61b96937016acd61da66deb0d14e93f795eaca51.1640727143.git.gitgitgadget@gmail.com> In-Reply-To: References: Date: Tue, 28 Dec 2021 21:32:19 +0000 Subject: [PATCH v3 2/6] config: make some helpers repo-aware Fcc: Sent MIME-Version: 1.0 To: git@vger.kernel.org Cc: stolee@gmail.com, sunshine@sunshineco.com, allred.sean@gmail.com, gitster@pobox.com, Elijah Newren , Derrick Stolee , Derrick Stolee Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Derrick Stolee From: Derrick Stolee As we prepare to add new config helpers to write into a config.worktree, let's make some existing methods be available for writing to a config file relative to a repository. Signed-off-by: Derrick Stolee --- config.c | 29 ++++++++++++++++++++++++++--- config.h | 7 +++++++ 2 files changed, 33 insertions(+), 3 deletions(-) diff --git a/config.c b/config.c index c5873f3a706..9c9eef16018 100644 --- a/config.c +++ b/config.c @@ -2882,7 +2882,12 @@ int git_config_set_gently(const char *key, const char *value) void git_config_set(const char *key, const char *value) { - git_config_set_multivar(key, value, NULL, 0); + repo_config_set(the_repository, key, value); +} + +void repo_config_set(struct repository *r, const char *key, const char *value) +{ + repo_config_set_multivar(r, key, value, NULL, 0); trace2_cmd_set_config(key, value); } @@ -3177,14 +3182,32 @@ void git_config_set_multivar_in_file(const char *config_filename, int git_config_set_multivar_gently(const char *key, const char *value, const char *value_pattern, unsigned flags) { - return git_config_set_multivar_in_file_gently(NULL, key, value, value_pattern, + return repo_config_set_multivar_gently(the_repository, key, value, + value_pattern, flags); +} + +int repo_config_set_multivar_gently(struct repository *r, const char *key, + const char *value, + const char *value_pattern, unsigned flags) +{ + return git_config_set_multivar_in_file_gently(repo_git_path(r, "config"), + key, value, value_pattern, flags); } void git_config_set_multivar(const char *key, const char *value, const char *value_pattern, unsigned flags) { - git_config_set_multivar_in_file(NULL, key, value, value_pattern, + repo_config_set_multivar(the_repository, key, value, + value_pattern, flags); +} + +void repo_config_set_multivar(struct repository *r, const char *key, + const char *value, const char *value_pattern, + unsigned flags) +{ + git_config_set_multivar_in_file(repo_git_path(r, "config"), + key, value, value_pattern, flags); } diff --git a/config.h b/config.h index f119de01309..5531fc018e3 100644 --- a/config.h +++ b/config.h @@ -258,6 +258,11 @@ int git_config_set_gently(const char *, const char *); */ void git_config_set(const char *, const char *); +/** + * write config values to `.git/config`, takes a key/value pair as parameter. + */ +void repo_config_set(struct repository *, const char *, const char *); + int git_config_parse_key(const char *, char **, size_t *); /* @@ -281,6 +286,8 @@ int git_config_parse_key(const char *, char **, size_t *); int git_config_set_multivar_gently(const char *, const char *, const char *, unsigned); void git_config_set_multivar(const char *, const char *, const char *, unsigned); +int repo_config_set_multivar_gently(struct repository *, const char *, const char *, const char *, unsigned); +void repo_config_set_multivar(struct repository *, const char *, const char *, const char *, unsigned); int git_config_set_multivar_in_file_gently(const char *, const char *, const char *, const char *, unsigned); /** From patchwork Tue Dec 28 21:32:20 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Derrick Stolee X-Patchwork-Id: 12700643 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 2E0FAC433FE for ; Tue, 28 Dec 2021 21:32:37 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230223AbhL1Vcg (ORCPT ); Tue, 28 Dec 2021 16:32:36 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37172 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230074AbhL1Vc3 (ORCPT ); Tue, 28 Dec 2021 16:32:29 -0500 Received: from mail-wr1-x430.google.com (mail-wr1-x430.google.com [IPv6:2a00:1450:4864:20::430]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id DA6FAC06173E for ; Tue, 28 Dec 2021 13:32:28 -0800 (PST) Received: by mail-wr1-x430.google.com with SMTP id w20so31601699wra.9 for ; Tue, 28 Dec 2021 13:32:28 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=message-id:in-reply-to:references:from:date:subject:fcc :content-transfer-encoding:mime-version:to:cc; bh=8Fqdt3bzApNIyi9ioy/h/ZUnaMcda3XAOsr7OAE4fPQ=; b=OWAN5rlpZa7zOKqy77q66Mne14nYMitBHIOT3fVP2b+12jMiZ5hs2BAkoniB9SDyoK tXix9ATTMNca5GXVNtSLX06a2t1oaAG9+y3WUlPVjf9aTO7x44jvp/s0iEtW3G2HYwR4 sFBlid5hcY/cqJIxzLmptMjtQWl4lLqLQ22WqONpoTSBv9QNeDLGcdU7cGApR5EaRPjS tEK+lPsGbentFkEjQ8d8k11S+qj6NcQ3MUBdDZpMgLv57ogBZt0gYBzsF4yXPVn2nU9C Ssn+vCa3SLlWJDydSZUX9k4/syePf2PU6bO5mjnXoPRAriJAbWEgrVPM4r+eJLFoTmnY wYOA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:message-id:in-reply-to:references:from:date :subject:fcc:content-transfer-encoding:mime-version:to:cc; bh=8Fqdt3bzApNIyi9ioy/h/ZUnaMcda3XAOsr7OAE4fPQ=; b=0onzj2dGATLMiIAOF15XWeMnF8S8NNLlFkBlYVoQ963QP/kNlp8vbnGvpjOYUsxWe2 p4+Imtyixyv4Oc5OUMg1BqeDofEcGt4dAEfpbhdUAixG6NMj7uGrE9HcRiv0xFC1+xJZ RQJvsDDzv2ls8mUo/22eYsonvJ8IBIU4bi7MD5Af8ygql5dAkFkFjjw2aDl/BJvbDk3b H639FmoSw7V4rPqxXkphRTnnW22EB2HBlQ+H3OxO5NqMewK93TU4/MS/G/4LVDcda8VZ PR8PhdlOcbwOI7WtKb0xEDmsXrb6nBeZ6wY6TOpd3RGtjsOppO5VO2z1d0TOV51Yf48B Ke8g== X-Gm-Message-State: AOAM5324Kfu+VzeSH+4k1tWBZrkAlPXMTORPLkpQ7/M3SbqCgdHuYeoZ cMeomgfFjc/gz9u2PlHuvkVQ1FI9M2I= X-Google-Smtp-Source: ABdhPJzbn0GpaJ5CRnN5zyAL584nGkLcTARv5dl2OQJYOqsa13bbwXik67RtKe6qg4it/4vx/9xz8g== X-Received: by 2002:a5d:4489:: with SMTP id j9mr18291404wrq.544.1640727147155; Tue, 28 Dec 2021 13:32:27 -0800 (PST) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id 1sm11011732wrb.13.2021.12.28.13.32.26 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 28 Dec 2021 13:32:26 -0800 (PST) Message-Id: In-Reply-To: References: Date: Tue, 28 Dec 2021 21:32:20 +0000 Subject: [PATCH v3 3/6] worktree: add 'init-worktree-config' subcommand Fcc: Sent MIME-Version: 1.0 To: git@vger.kernel.org Cc: stolee@gmail.com, sunshine@sunshineco.com, allred.sean@gmail.com, gitster@pobox.com, Elijah Newren , Derrick Stolee , Derrick Stolee Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Derrick Stolee From: Derrick Stolee Some features, such as the sparse-checkout builtin, currently use the worktree config extension. It might seem simple to upgrade the repository format and add extensions.worktreeConfig, which is what happens in the sparse-checkout builtin. However, this is overly simplistic and can cause issues in some cases. We will transition away from making this upgrade automatically, but first we will make an easy way for users to upgrade their repositories correctly. Transitioning from one config file to multiple has some strange side-effects. In particular, if the base repository is bare and the worktree is not, Git knows to treat the worktree as non-bare as a special case when not using worktree config. Once worktree config is enabled, Git stops that special case since the core.bare setting could apply at the worktree config level. Similarly, the core.worktree config setting is a precursor to the 'git worktree' feature, allowing config to point to a different worktree, presumably temporarily. This is special-cased to be ignored in a worktree, but that case is dropped when worktree config is enabled. To help resolve this transition, create the 'git worktree init-worktree-config' helper. This new subcommand does the following: 1. Set core.repositoryFormatVersion to 1 in the common config file. 2. Set extensions.worktreeConfig to true in the common config file. 3. If core.bare is true in the common config file, then move that setting to the main worktree's config file. 4. Move the core.worktree config value to the main worktree's config file. If the repository is already configured to use worktree config, then none of these steps happen. This preserves any state that the user might have created on purpose. Update the documentation to mention this subcommand as the proper way to upgrade to worktree config files. To gain access to the core repository's config and config.worktree file, we reference a repository struct's 'commondir' member. If the repository was a submodule instead of a worktree, then this still applies correctly. Helped-by: Eric Sunshine Signed-off-by: Derrick Stolee --- Documentation/git-worktree.txt | 22 +++++-- builtin/worktree.c | 82 ++++++++++++++++++++++++ t/t2407-worktree-init-worktree-config.sh | 68 ++++++++++++++++++++ 3 files changed, 167 insertions(+), 5 deletions(-) create mode 100755 t/t2407-worktree-init-worktree-config.sh diff --git a/Documentation/git-worktree.txt b/Documentation/git-worktree.txt index 9e862fbcf79..0f0642ac039 100644 --- a/Documentation/git-worktree.txt +++ b/Documentation/git-worktree.txt @@ -10,6 +10,7 @@ SYNOPSIS -------- [verse] 'git worktree add' [-f] [--detach] [--checkout] [--lock [--reason ]] [-b ] [] +'git worktree init-worktree-config' 'git worktree list' [-v | --porcelain] 'git worktree lock' [--reason ] 'git worktree move' @@ -92,6 +93,14 @@ checked out in the new working tree, if it's not checked out anywhere else, otherwise the command will refuse to create the working tree (unless `--force` is used). +init-worktree-config:: + +Initialize config settings to enable worktree-specific config settings. +This will set `core.repositoryFormatversion=1` and enable +`extensions.worktreeConfig`, which might cause some third-party tools from +being able to operate on your repository. See CONFIGURATION FILE for more +details. + list:: List details of each working tree. The main working tree is listed first, @@ -290,10 +299,10 @@ already present in the config file, they will be applied to the main working trees only. In order to have configuration specific to working trees, you can turn -on the `worktreeConfig` extension, e.g.: +on the `worktreeConfig` extension, using this command: ------------ -$ git config extensions.worktreeConfig true +$ git worktree init-worktree-config ------------ In this mode, specific configuration stays in the path pointed by `git @@ -303,9 +312,12 @@ versions will refuse to access repositories with this extension. Note that in this file, the exception for `core.bare` and `core.worktree` is gone. If they exist in `$GIT_DIR/config`, you must move -them to the `config.worktree` of the main working tree. You may also -take this opportunity to review and move other configuration that you -do not want to share to all working trees: +them to the `config.worktree` of the main working tree. These keys are +moved automatically when you use the `git worktree init-worktree-config` +command. + +You may also take this opportunity to review and move other configuration +that you do not want to share to all working trees: - `core.worktree` and `core.bare` should never be shared diff --git a/builtin/worktree.c b/builtin/worktree.c index a57fcd0f3c5..937ee6fc38b 100644 --- a/builtin/worktree.c +++ b/builtin/worktree.c @@ -17,6 +17,7 @@ static const char * const worktree_usage[] = { N_("git worktree add [] []"), + N_("git worktree init-worktree-config"), N_("git worktree list []"), N_("git worktree lock [] "), N_("git worktree move "), @@ -1031,6 +1032,85 @@ static int repair(int ac, const char **av, const char *prefix) return rc; } +static int move_config_setting(const char *key, const char *value, + const char *from_file, const char *to_file) +{ + if (git_config_set_in_file_gently(to_file, key, value)) + return error(_("unable to set %s in '%s'"), key, to_file); + if (git_config_set_in_file_gently(from_file, key, NULL)) + return error(_("unable to unset %s in '%s'"), key, from_file); + return 0; +} + +static int init_worktree_config(int ac, const char **av, const char *prefix) +{ + struct repository *r = the_repository; + struct option options[] = { + OPT_END() + }; + int res = 0; + int bare = 0; + struct config_set cs = { 0 }; + const char *core_worktree; + char *common_config_file = xstrfmt("%s/config", r->commondir); + char *main_worktree_file = xstrfmt("%s/config.worktree", r->commondir); + + /* Report error on any arguments */ + ac = parse_options(ac, av, prefix, options, worktree_usage, 0); + if (ac) + usage_with_options(worktree_usage, options); + + git_configset_init(&cs); + git_configset_add_file(&cs, common_config_file); + + /* + * If the format and extension are already enabled, then we can + * skip the upgrade process. + */ + if (repository_format_worktree_config) + return 0; + + if (upgrade_repository_format(r, 1) < 0) { + res = error(_("unable to upgrade repository format to enable worktreeConfig")); + goto cleanup; + } + if ((res = git_config_set_gently("extensions.worktreeConfig", "true"))) { + error(_("failed to set extensions.worktreeConfig setting")); + goto cleanup; + } + + /* + * If core.bare is true in the common config file, then we need to + * move it to the base worktree's config file or it will break all + * worktrees. If it is false, then leave it in place because it + * _could_ be negating a global core.bare=true. + */ + if (!git_configset_get_bool(&cs, "core.bare", &bare) && bare) { + if ((res = move_config_setting("core.bare", "true", + common_config_file, + main_worktree_file))) + goto cleanup; + } + /* + * If core.worktree is set, then the base worktree is located + * somewhere different than the parent of the common Git dir. + * Relocate that value to avoid breaking all worktrees with this + * upgrade to worktree config. + */ + if (!git_configset_get_string_tmp(&cs, "core.worktree", &core_worktree)) { + if ((res = move_config_setting("core.worktree", core_worktree, + common_config_file, + main_worktree_file))) + goto cleanup; + } + +cleanup: + git_configset_clear(&cs); + free(common_config_file); + free(main_worktree_file); + return res; +} + int cmd_worktree(int ac, const char **av, const char *prefix) { struct option options[] = { @@ -1045,6 +1125,8 @@ int cmd_worktree(int ac, const char **av, const char *prefix) prefix = ""; if (!strcmp(av[1], "add")) return add(ac - 1, av + 1, prefix); + if (!strcmp(av[1], "init-worktree-config")) + return init_worktree_config(ac - 1, av + 1, prefix); if (!strcmp(av[1], "prune")) return prune(ac - 1, av + 1, prefix); if (!strcmp(av[1], "list")) diff --git a/t/t2407-worktree-init-worktree-config.sh b/t/t2407-worktree-init-worktree-config.sh new file mode 100755 index 00000000000..b3bd0fa1322 --- /dev/null +++ b/t/t2407-worktree-init-worktree-config.sh @@ -0,0 +1,68 @@ +#!/bin/sh + +test_description='test git worktree init-worktree-config' + +. ./test-lib.sh + +test_expect_success setup ' + git init base && + test_commit -C base commit && + git -C base worktree add --detach worktree +' + +reset_config_when_finished () { + test_when_finished git -C base config --unset core.repositoryFormatVersion && + test_when_finished git -C base config --unset extensions.worktreeConfig && + rm -rf base/.git/config.worktree && + rm -rf base/.git/worktrees/worktree/config.worktree +} + +test_expect_success 'upgrades repo format and adds extension' ' + reset_config_when_finished && + git -C base worktree init-worktree-config >out 2>err && + test_must_be_empty out && + test_must_be_empty err && + test_cmp_config -C base 1 core.repositoryFormatVersion && + test_cmp_config -C base true extensions.worktreeConfig +' + +test_expect_success 'relocates core.worktree' ' + reset_config_when_finished && + mkdir dir && + git -C base config core.worktree ../../dir && + git -C base worktree init-worktree-config >out 2>err && + test_must_be_empty out && + test_must_be_empty err && + test_cmp_config -C base 1 core.repositoryFormatVersion && + test_cmp_config -C base true extensions.worktreeConfig && + test_cmp_config -C base ../../dir core.worktree && + test_must_fail git -C worktree core.worktree +' + +test_expect_success 'relocates core.bare' ' + reset_config_when_finished && + git -C base config core.bare true && + git -C base worktree init-worktree-config >out 2>err && + test_must_be_empty out && + test_must_be_empty err && + test_cmp_config -C base 1 core.repositoryFormatVersion && + test_cmp_config -C base true extensions.worktreeConfig && + test_cmp_config -C base true core.bare && + test_must_fail git -C worktree core.bare +' + +test_expect_success 'skips upgrade is already upgraded' ' + reset_config_when_finished && + git -C base worktree init-worktree-config && + git -C base config core.bare true && + + # this should be a no-op, even though core.bare + # makes the worktree be broken. + git -C base worktree init-worktree-config >out 2>err && + test_must_be_empty out && + test_must_be_empty err && + test_must_fail git -C base config --worktree core.bare && + git -C base config core.bare +' + +test_done From patchwork Tue Dec 28 21:32:21 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Derrick Stolee X-Patchwork-Id: 12700644 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7AE48C4332F for ; Tue, 28 Dec 2021 21:32:38 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230284AbhL1Vch (ORCPT ); Tue, 28 Dec 2021 16:32:37 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37174 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230091AbhL1Vca (ORCPT ); Tue, 28 Dec 2021 16:32:30 -0500 Received: from mail-wm1-x32f.google.com (mail-wm1-x32f.google.com [IPv6:2a00:1450:4864:20::32f]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 90B5FC061574 for ; Tue, 28 Dec 2021 13:32:29 -0800 (PST) Received: by mail-wm1-x32f.google.com with SMTP id b186-20020a1c1bc3000000b00345734afe78so10761207wmb.0 for ; Tue, 28 Dec 2021 13:32:29 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=message-id:in-reply-to:references:from:date:subject:fcc :content-transfer-encoding:mime-version:to:cc; bh=kLiUVAAe9J6maUmPfcrZC7aWsX5ipUHzPINLlxkbOyM=; b=cUVTPE52J55ZUTbHHuc+nYh4qJCWvE2awPeek0Fx+Q7BDoJtKiqlhJXixhVhY3GO0E X/nWAqknXesG0UogJBhCHlCBS84V/PpAipxf77bRpqSufjh1kusMXAAUpLHPxgEWs9EC WMFaFMo/uL51VXsWsilQnzDrlwTaz9vZphe3zkRJyybqHrmzHrhKfjAGVkhD73Gm3BHq siKeJwArmk1PtlaXhtmicu5Rc5RqLYjO5aNOK0fo6SkP9yqg/JnfewV0gfMzxX4GV3jD W13xnW5VjwAjdbwzXZuZBiPBlygoE02XUuITo87sU5tqX1FbyXrB/MpGaGeeyyuq3n1m 6gxw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:message-id:in-reply-to:references:from:date :subject:fcc:content-transfer-encoding:mime-version:to:cc; bh=kLiUVAAe9J6maUmPfcrZC7aWsX5ipUHzPINLlxkbOyM=; b=rLgmHoQRPehcIfbW/YDUJUcSGtYeiqz8D4fDfXlGcJK1oyU3ECzHEohj6VoDD3gZU7 tqZLhaejmsO6/bUbYt/bzrBtQS8fTu1pOw8SFrwey9xE4DK0Fhg9QE8BKe9PiTkm5jZf XDmQTUUyJQgOmqcYhjz/4mT9bk2LhfRuMxaIrhVKNy/MemCnZwlzKzR191ZE4/WNVvNa vu7OPoM11fcdpTLHgQ1QFQlJIxsDHeVgwPZTwn2nPuahnaU//I+WH7PsXoP/9aSFlW5k /SCrpfO28mJVAhwHRpqus0qEskpK+/oc2K6M2QVNL82theRhNlW5BgF18M7VEAl76id7 M9LA== X-Gm-Message-State: AOAM532ZSnJFE6NCZexT8wYG5PPZKktYZB2OeG51ZbJTj/BppeY+Yxlm y00zO/G8bacSMEnT0CAkZUPt+Ec6JfM= X-Google-Smtp-Source: ABdhPJy3xLdqbrZTfYUO6/bus8DRZW82Z2fTH6nu4pktnrrRKxgssuAG7noRUkD/80Wsp8KZ49KeWg== X-Received: by 2002:a1c:8013:: with SMTP id b19mr18533858wmd.35.1640727148039; Tue, 28 Dec 2021 13:32:28 -0800 (PST) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id e5sm21806322wrq.116.2021.12.28.13.32.27 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 28 Dec 2021 13:32:27 -0800 (PST) Message-Id: <45316cd01c97285d2b8b22d117c4975209f8c3a5.1640727143.git.gitgitgadget@gmail.com> In-Reply-To: References: Date: Tue, 28 Dec 2021 21:32:21 +0000 Subject: [PATCH v3 4/6] config: add repo_config_set_worktree_gently() Fcc: Sent MIME-Version: 1.0 To: git@vger.kernel.org Cc: stolee@gmail.com, sunshine@sunshineco.com, allred.sean@gmail.com, gitster@pobox.com, Elijah Newren , Derrick Stolee , Derrick Stolee Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Derrick Stolee From: Derrick Stolee Some config settings, such as those for sparse-checkout, are likely intended to only apply to one worktree at a time. To make this write easier, add a new config API method, repo_config_set_worktree_gently(). This method will attempt to write to the worktree-specific config, but will instead write to the common config file if worktree config is not enabled. The next change will introduce a consumer of this method. Signed-off-by: Derrick Stolee --- config.c | 21 +++++++++++++++++++++ config.h | 8 ++++++++ 2 files changed, 29 insertions(+) diff --git a/config.c b/config.c index 9c9eef16018..f849aef253c 100644 --- a/config.c +++ b/config.c @@ -21,6 +21,7 @@ #include "dir.h" #include "color.h" #include "refs.h" +#include "worktree.h" struct config_source { struct config_source *prev; @@ -2880,6 +2881,20 @@ int git_config_set_gently(const char *key, const char *value) return git_config_set_multivar_gently(key, value, NULL, 0); } +int repo_config_set_worktree_gently(struct repository *r, + const char *key, const char *value) +{ + /* Only use worktree-specific config if it is is already enabled. */ + if (repository_format_worktree_config) { + char *file = repo_git_path(r, "config.worktree"); + int ret = git_config_set_multivar_in_file_gently( + file, key, value, NULL, 0); + free(file); + return ret; + } + return repo_config_set_gently(r, key, value); +} + void git_config_set(const char *key, const char *value) { repo_config_set(the_repository, key, value); @@ -3195,6 +3210,12 @@ int repo_config_set_multivar_gently(struct repository *r, const char *key, flags); } +int repo_config_set_gently(struct repository *r, + const char *key, const char *value) +{ + return repo_config_set_multivar_gently(r, key, value, NULL, 0); +} + void git_config_set_multivar(const char *key, const char *value, const char *value_pattern, unsigned flags) { diff --git a/config.h b/config.h index 5531fc018e3..1386009fac8 100644 --- a/config.h +++ b/config.h @@ -253,6 +253,13 @@ void git_config_set_in_file(const char *, const char *, const char *); int git_config_set_gently(const char *, const char *); +/** + * Write a config value that should apply to the current worktree. If + * extensions.worktreeConfig is enabled, then the write will happen in the + * current worktree's config. Otherwise, write to the common config file. + */ +int repo_config_set_worktree_gently(struct repository *, const char *, const char *); + /** * write config values to `.git/config`, takes a key/value pair as parameter. */ @@ -288,6 +295,7 @@ int git_config_set_multivar_gently(const char *, const char *, const char *, uns void git_config_set_multivar(const char *, const char *, const char *, unsigned); int repo_config_set_multivar_gently(struct repository *, const char *, const char *, const char *, unsigned); void repo_config_set_multivar(struct repository *, const char *, const char *, const char *, unsigned); +int repo_config_set_gently(struct repository *, const char *, const char *); int git_config_set_multivar_in_file_gently(const char *, const char *, const char *, const char *, unsigned); /** From patchwork Tue Dec 28 21:32:22 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Derrick Stolee X-Patchwork-Id: 12700645 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id E4F62C433EF for ; Tue, 28 Dec 2021 21:32:42 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230131AbhL1Vcm (ORCPT ); Tue, 28 Dec 2021 16:32:42 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37182 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230096AbhL1Vca (ORCPT ); Tue, 28 Dec 2021 16:32:30 -0500 Received: from mail-wm1-x331.google.com (mail-wm1-x331.google.com [IPv6:2a00:1450:4864:20::331]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4D47EC06173E for ; Tue, 28 Dec 2021 13:32:30 -0800 (PST) Received: by mail-wm1-x331.google.com with SMTP id k66-20020a1ca145000000b00345fa984108so5041381wme.2 for ; Tue, 28 Dec 2021 13:32:30 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=message-id:in-reply-to:references:from:date:subject:fcc :content-transfer-encoding:mime-version:to:cc; bh=6TvHtjRK5E40k2krLTn+3gz0FHnsdhcBFGnsl/wJQPw=; b=YpdklIh/+G8Vej7hc8ja7G8X6YEBMI8uKgdor4Hh/HBYxsjQaIgE5KDUaKcdvG/Dm7 Iet89LI616C6Bnz40kwQOsU0jmY7tXf7Ywuig+RfNUaOLtNmyA/W3p6vJ6q7tkHo1Wzf 7+T6jSRVo1ZNy2pdjZ4qPvdbujjL+xcZrA/7468IZb2riXH4+i6uc4+HGplKi42ehsob 1Ba/Tmd7lim7SFMwEwXzHgTgYgNRFsFnf+gw5n3Q1WtH717m+HXzwPhPwDEp5JeB6/GR x1hJ58vBLEdOH2bsWPNghg7ppxlHRLOP9Ghe8ofB7o5Xqb94I+Qd6gAJDjlaWAF7swsE ZD+Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:message-id:in-reply-to:references:from:date :subject:fcc:content-transfer-encoding:mime-version:to:cc; bh=6TvHtjRK5E40k2krLTn+3gz0FHnsdhcBFGnsl/wJQPw=; b=E7dHQqVNuEY7LNyg8QNxokMMjyqV6Ia5zbSfh4g9k4j7PaSb6bkmvWB0Ke0KDk7Pua qX/eT655/thf1cdy9Ez5sTwbdECAdllS8hnoqKUWmPuM1CxpEhYnmzTKLbzsVYcU5tLY gAWejuE/QkwHvQ3Wi2wfQ3yoxwCWZyswzhaRTvE43T/1+nYLNI0Ab6HjLXjg+FdUkH3k HyvDH0LWSLVeKwtdqBKSiMrL/yLi6v+S5V44HgTzU4HbYD9QHBWqGlhQAtereFb9aNFd 8XjaVTHEmOb0Vfo1oj5cJY3JIisRgMETQrd30MvxZD7S3UT66zd4IueupT57TGggjVek VLGg== X-Gm-Message-State: AOAM533SYeFLUxAIbFQNQDB4dO/BcSd5WlrJcatI9LDg4O/DaautDO5u Fil62vwjnBCIOFOXtMkr/gC0vFj8LLc= X-Google-Smtp-Source: ABdhPJxqc753eIr6IaA1rxV+EzDThz5zVBZz5b8y9sJylI5qXUhrlLqiC3cbGTuVWCwV+D6hZdFDmA== X-Received: by 2002:a1c:9851:: with SMTP id a78mr18886841wme.181.1640727148689; Tue, 28 Dec 2021 13:32:28 -0800 (PST) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id i1sm22044840wml.26.2021.12.28.13.32.28 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 28 Dec 2021 13:32:28 -0800 (PST) Message-Id: In-Reply-To: References: Date: Tue, 28 Dec 2021 21:32:22 +0000 Subject: [PATCH v3 5/6] sparse-checkout: use repo_config_set_worktree_gently() Fcc: Sent MIME-Version: 1.0 To: git@vger.kernel.org Cc: stolee@gmail.com, sunshine@sunshineco.com, allred.sean@gmail.com, gitster@pobox.com, Elijah Newren , Derrick Stolee , Derrick Stolee Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Derrick Stolee From: Derrick Stolee The previous change added repo_config_set_worktree_gently() to assist writing config values into the worktree.config file, if enabled. Let the sparse-checkout builtin use this helper instead of attempting to initialize the worktree config on its own. This changes behavior of 'git sparse-checkout set' in a few important ways: 1. Git will no longer upgrade the repository format and add the worktree config extension. The user should run 'git worktree init-worktree-config' to enable this feature. 2. If worktree config is disabled, then this command will set the core.sparseCheckout (and possibly core.sparseCheckoutCone and index.sparse) values in the common config file. 3. If the main worktree is bare, then this command will not put the worktree in a broken state. The main reason to use worktree-specific config for the sparse-checkout builtin was to avoid enabling sparse-checkout patterns in one and causing a loss of files in another. If a worktree does not have a sparse-checkout patterns file, then the sparse-checkout logic will not kick in on that worktree. This new logic introduces a new user pattern that could lead to some confusion. Suppose a user has not upgraded to worktree config and follows these steps in order: 1. Enable sparse-checkout in a worktree. 2. Disable sparse-checkout in that worktree without deleting that worktree's sparse-checkout file. 3. Enable sparse-checkout in another worktree. After these steps, the first worktree will have sparse-checkout enabled with whatever patterns exist. The worktree does not immediately have those patterns applied, but a variety of Git commands would apply the sparse-checkout patterns and update the worktree state to reflect those patterns. This situation is likely very rare and the workaround is to upgrade to worktree specific config on purpose. Users already in this state used the sparse-checkout builtin with a version that upgraded to worktree config, anyway. Reported-by: Sean Allred Helped-by: Eric Sunshine Signed-off-by: Derrick Stolee --- builtin/sparse-checkout.c | 25 +++++-------- sparse-index.c | 10 ++---- t/t1091-sparse-checkout-builtin.sh | 57 +++++++++++++++++++++++++----- 3 files changed, 60 insertions(+), 32 deletions(-) diff --git a/builtin/sparse-checkout.c b/builtin/sparse-checkout.c index 08f8df2648c..d0d6749593e 100644 --- a/builtin/sparse-checkout.c +++ b/builtin/sparse-checkout.c @@ -359,26 +359,17 @@ enum sparse_checkout_mode { static int set_config(enum sparse_checkout_mode mode) { - const char *config_path; - - if (upgrade_repository_format(the_repository, 1) < 0) - die(_("unable to upgrade repository format to enable worktreeConfig")); - if (git_config_set_gently("extensions.worktreeConfig", "true")) { - error(_("failed to set extensions.worktreeConfig setting")); + if (repo_config_set_worktree_gently(the_repository, + "core.sparseCheckout", + mode ? "true" : "false") || + repo_config_set_worktree_gently(the_repository, + "core.sparseCheckoutCone", + mode == MODE_CONE_PATTERNS ? + "true" : "false")) return 1; - } - - config_path = git_path("config.worktree"); - git_config_set_in_file_gently(config_path, - "core.sparseCheckout", - mode ? "true" : NULL); - - git_config_set_in_file_gently(config_path, - "core.sparseCheckoutCone", - mode == MODE_CONE_PATTERNS ? "true" : NULL); if (mode == MODE_NO_PATTERNS) - set_sparse_index_config(the_repository, 0); + return set_sparse_index_config(the_repository, 0); return 0; } diff --git a/sparse-index.c b/sparse-index.c index a1d505d50e9..e93609999e0 100644 --- a/sparse-index.c +++ b/sparse-index.c @@ -99,13 +99,9 @@ static int convert_to_sparse_rec(struct index_state *istate, int set_sparse_index_config(struct repository *repo, int enable) { - int res; - char *config_path = repo_git_path(repo, "config.worktree"); - res = git_config_set_in_file_gently(config_path, - "index.sparse", - enable ? "true" : NULL); - free(config_path); - + int res = repo_config_set_worktree_gently(repo, + "index.sparse", + enable ? "true" : "false"); prepare_repo_settings(repo); repo->settings.sparse_index = enable; return res; diff --git a/t/t1091-sparse-checkout-builtin.sh b/t/t1091-sparse-checkout-builtin.sh index 447a8669e02..15403158c49 100755 --- a/t/t1091-sparse-checkout-builtin.sh +++ b/t/t1091-sparse-checkout-builtin.sh @@ -146,15 +146,54 @@ test_expect_success 'interaction with clone --no-checkout (unborn index)' ' ' test_expect_success 'set enables config' ' - git init empty-config && + git init initial-config && ( - cd empty-config && + cd initial-config && + test_commit file file && + mkdir dir && + test_commit dir dir/file && + git worktree add --detach ../initial-worktree && + git sparse-checkout set --cone + ) && + test_cmp_config -C initial-config true core.sparseCheckout && + test_cmp_config -C initial-worktree true core.sparseCheckout && + test_cmp_config -C initial-config true core.sparseCheckoutCone && + test_cmp_config -C initial-worktree true core.sparseCheckoutCone && + + # initial-config has a sparse-checkout file + # that only contains files at root. + ls initial-config >only-file && + cat >expect <<-EOF && + file + EOF + test_cmp expect only-file && + + # initial-worktree does not have its own sparse-checkout + # file, so the repply does not modify the worktree at all. + git -C initial-worktree sparse-checkout reapply && + ls initial-worktree >all && + cat >expect <<-EOF && + dir + file + EOF + test_cmp expect all +' + +test_expect_success 'set enables worktree config, if enabled' ' + git init worktree-config && + ( + cd worktree-config && test_commit test file && - test_path_is_missing .git/config.worktree && - git sparse-checkout set nothing && - test_path_is_file .git/config.worktree && - test_cmp_config true core.sparseCheckout - ) + git worktree add --detach ../worktree-config2 && + git worktree init-worktree-config && + git sparse-checkout set --cone && + git config --worktree core.sparseCheckout && + git config --worktree core.sparseCheckoutCone + ) && + test_cmp_config -C worktree-config true core.sparseCheckout && + test_must_fail git -C worktree-config2 core.sparseCheckout && + test_cmp_config -C worktree-config true core.sparseCheckoutCone && + test_must_fail git -C worktree-config2 core.sparseCheckoutCone ' test_expect_success 'set sparse-checkout using builtin' ' @@ -202,6 +241,7 @@ test_expect_success 'add to sparse-checkout' ' ' test_expect_success 'cone mode: match patterns' ' + git -C repo worktree init-worktree-config && git -C repo config --worktree core.sparseCheckoutCone true && rm -rf repo/a repo/folder1 repo/folder2 && git -C repo read-tree -mu HEAD 2>err && @@ -241,7 +281,7 @@ test_expect_success 'sparse-index enabled and disabled' ' test-tool -C repo read-cache --table >cache && ! grep " tree " cache && git -C repo config --list >config && - ! grep index.sparse config + test_cmp_config -C repo false index.sparse ) ' @@ -380,6 +420,7 @@ test_expect_success 'fail when lock is taken' ' ' test_expect_success '.gitignore should not warn about cone mode' ' + git -C repo worktree init-worktree-config && git -C repo config --worktree core.sparseCheckoutCone true && echo "**/bin/*" >repo/.gitignore && git -C repo reset --hard 2>err && From patchwork Tue Dec 28 21:32:23 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Derrick Stolee X-Patchwork-Id: 12700646 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id A4FDEC433FE for ; Tue, 28 Dec 2021 21:32:44 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230340AbhL1Vcn (ORCPT ); Tue, 28 Dec 2021 16:32:43 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37188 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230156AbhL1Vcb (ORCPT ); Tue, 28 Dec 2021 16:32:31 -0500 Received: from mail-wm1-x32f.google.com (mail-wm1-x32f.google.com [IPv6:2a00:1450:4864:20::32f]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 34966C061401 for ; Tue, 28 Dec 2021 13:32:31 -0800 (PST) Received: by mail-wm1-x32f.google.com with SMTP id c66so12384574wma.5 for ; Tue, 28 Dec 2021 13:32:31 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=message-id:in-reply-to:references:from:date:subject:fcc :content-transfer-encoding:mime-version:to:cc; bh=znDrSuS0qJDmMNdY4aat1qMorpeFr3VuLb0gkrLPcZ4=; b=d24Z6f87AtfrHdFYktN6LYh71AyNtkCsndwe6vGbHEFc4q0oT9aH04e6cotzaofds3 3KZGPQSRVu76X+plhzQnXgNpUKiXWV4ieUc79yhNtC6ftzHna35Mn8zhKxIBHJMT69rd Pcj/Vqes8ZHedIJh86BOa/M4DmPDHefh4IbIOvPb13B5SU2hs6gb/gSdMfHbpiGOVvuA EkNWmsoOiKOcSjKIQjZNKdBS3Ur4gjycNwBbFuPiKm9cmdp0SdG7xsM1Do/yJLtopHiK DSjqmeR/Lukz9gN2/GkSsqegwJ9BtmdJuXbE68aTX9cUd7PruTmxzKWxKg3DylCpeJ/z eODA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:message-id:in-reply-to:references:from:date :subject:fcc:content-transfer-encoding:mime-version:to:cc; bh=znDrSuS0qJDmMNdY4aat1qMorpeFr3VuLb0gkrLPcZ4=; b=tWs6rXyTLG9wAdvhw/Sw4NcTfnPSltxS6nZv+ixbcpWCNIzOtrxFakwThEp6uBK33r KxhqReZCxI/rqHTKnzFrIK9qFymcJARsUBFc6XJz/Xuxd2afnOumV/tz4/bRxsKxymlJ 9V758Npef9GEsol/luDVbF0pmN70u4VcotsVqJ8GOX00f5jqA8poga0B3e56AFonO8ev D8wjjXhglok9RCuQY/oVcSoV+buaFRq2geL/cVItSxCrUV4sCoj2Yr5IcvhtX+xmUtjp /F5dFBoZlUTEUZJQdLkt8RODeMBDykqyrBxOQE3XZWUserD8LPIQJvWYzUIAckoPqIAE aOog== X-Gm-Message-State: AOAM5322LEGy8tyusFAzrOqjbnb32trwZcq5GOb14WRoaZkHKpUzvhlX /KPf/NOGmo/hsS0vBPCrsjFgHXbDOGc= X-Google-Smtp-Source: ABdhPJwjefKCd55vkrmZWZ5EP7JyNXfufUGdRlOziNNitUIg1wSXFv4mKXl5cKRqaFzGG3qsSVS8eg== X-Received: by 2002:a7b:ca57:: with SMTP id m23mr19328331wml.0.1640727149575; Tue, 28 Dec 2021 13:32:29 -0800 (PST) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id k10sm34998wrz.113.2021.12.28.13.32.28 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 28 Dec 2021 13:32:29 -0800 (PST) Message-Id: In-Reply-To: References: Date: Tue, 28 Dec 2021 21:32:23 +0000 Subject: [PATCH v3 6/6] worktree: copy sparse-checkout patterns and config on add Fcc: Sent MIME-Version: 1.0 To: git@vger.kernel.org Cc: stolee@gmail.com, sunshine@sunshineco.com, allred.sean@gmail.com, gitster@pobox.com, Elijah Newren , Derrick Stolee , Derrick Stolee Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Derrick Stolee From: Derrick Stolee When adding a new worktree, it is reasonable to expect that we want to use the current set of sparse-checkout settings for that new worktree. This is particularly important for repositories where the worktree would become too large to be useful. This is even more important when using partial clone as well, since we want to avoid downloading the missing blobs for files that should not be written to the new worktree. The only way to create such a worktree without this intermediate step of expanding the full worktree is to copy the sparse-checkout patterns and config settings during 'git worktree add'. Each worktree has its own sparse-checkout patterns, and the default behavior when the sparse-checkout file is missing is to include all paths at HEAD. Thus, we need to have patterns from somewhere, they might as well be the current worktree's patterns. These are then modified independently in the future. In addition to the sparse-checkout file, copy the worktree config file if worktree config is enabled and the file exists. This will copy over any important settings to ensure the new worktree behaves the same as the current one. Signed-off-by: Derrick Stolee --- builtin/worktree.c | 41 +++++++++++++++++++++++ t/t1091-sparse-checkout-builtin.sh | 53 ++++++++++++++++++++++++++++-- 2 files changed, 91 insertions(+), 3 deletions(-) diff --git a/builtin/worktree.c b/builtin/worktree.c index 937ee6fc38b..bca49a55f13 100644 --- a/builtin/worktree.c +++ b/builtin/worktree.c @@ -336,6 +336,47 @@ static int add_worktree(const char *path, const char *refname, strbuf_addf(&sb, "%s/commondir", sb_repo.buf); write_file(sb.buf, "../.."); + /* + * If the current worktree has sparse-checkout enabled, then copy + * the sparse-checkout patterns from the current worktree. + */ + if (core_apply_sparse_checkout) { + char *from_file = git_pathdup("info/sparse-checkout"); + char *to_file = xstrfmt("%s/worktrees/%s/info/sparse-checkout", + realpath.buf, name); + + if (file_exists(from_file)) { + if (safe_create_leading_directories(to_file) || + copy_file(to_file, from_file, 0666)) + error(_("failed to copy '%s' to '%s'; sparse-checkout may not work correctly"), + from_file, to_file); + } + + free(from_file); + free(to_file); + } + + /* + * If we are using worktree config, then copy all currenct config + * values from the current worktree into the new one, that way the + * new worktree behaves the same as this one. + */ + if (repository_format_worktree_config) { + char *from_file = git_pathdup("config.worktree"); + char *to_file = xstrfmt("%s/worktrees/%s/config.worktree", + realpath.buf, name); + + if (file_exists(from_file)) { + if (safe_create_leading_directories(to_file) || + copy_file(to_file, from_file, 0666)) + error(_("failed to copy worktree config from '%s' to '%s'"), + from_file, to_file); + } + + free(from_file); + free(to_file); + } + strvec_pushf(&child_env, "%s=%s", GIT_DIR_ENVIRONMENT, sb_git.buf); strvec_pushf(&child_env, "%s=%s", GIT_WORK_TREE_ENVIRONMENT, path); cp.git_cmd = 1; diff --git a/t/t1091-sparse-checkout-builtin.sh b/t/t1091-sparse-checkout-builtin.sh index 15403158c49..ce84819e1f5 100755 --- a/t/t1091-sparse-checkout-builtin.sh +++ b/t/t1091-sparse-checkout-builtin.sh @@ -180,6 +180,53 @@ test_expect_success 'set enables config' ' ' test_expect_success 'set enables worktree config, if enabled' ' + git init worktree-patterns && + ( + cd worktree-patterns && + test_commit test file && + mkdir dir dir2 && + test_commit dir dir/file && + test_commit dir2 dir2/file && + + # By initializing the worktree config here... + git worktree init-worktree-config && + + # This set command places config values in worktree- + # specific config... + git sparse-checkout set --cone dir && + + # Which must be copied, along with the sparse-checkout + # patterns, here. + git worktree add --detach ../worktree-patterns2 + ) && + test_cmp_config -C worktree-patterns true core.sparseCheckout && + test_cmp_config -C worktree-patterns2 true core.sparseCheckout && + test_cmp_config -C worktree-patterns true core.sparseCheckoutCone && + test_cmp_config -C worktree-patterns2 true core.sparseCheckoutCone && + test_cmp worktree-patterns/.git/info/sparse-checkout \ + worktree-patterns/.git/worktrees/worktree-patterns2/info/sparse-checkout && + + ls worktree-patterns >expect && + ls worktree-patterns2 >actual && + test_cmp expect actual && + + # Double check that the copy works from a non-main worktree. + ( + cd worktree-patterns2 && + git sparse-checkout set dir2 && + git worktree add --detach ../worktree-patterns3 + ) && + test_cmp_config -C worktree-patterns3 true core.sparseCheckout && + test_cmp_config -C worktree-patterns3 true core.sparseCheckoutCone && + test_cmp worktree-patterns/.git/worktrees/worktree-patterns2/info/sparse-checkout \ + worktree-patterns/.git/worktrees/worktree-patterns3/info/sparse-checkout && + + ls worktree-patterns2 >expect && + ls worktree-patterns3 >actual && + test_cmp expect actual +' + +test_expect_success 'worktree add copies sparse-checkout patterns' ' git init worktree-config && ( cd worktree-config && @@ -547,11 +594,11 @@ test_expect_success 'interaction with submodules' ' test_expect_success 'different sparse-checkouts with worktrees' ' git -C repo worktree add --detach ../worktree && - check_files worktree "a deep folder1 folder2" && + check_files worktree "a folder1" && git -C worktree sparse-checkout init --cone && - git -C repo sparse-checkout set folder1 && + git -C repo sparse-checkout set folder1 folder2 && git -C worktree sparse-checkout set deep/deeper1 && - check_files repo a folder1 && + check_files repo a folder1 folder2 && check_files worktree a deep '