From patchwork Fri Oct 28 20:14:49 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Glen Choo X-Patchwork-Id: 13024264 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 29122C38A02 for ; Fri, 28 Oct 2022 20:15:07 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229565AbiJ1UPE (ORCPT ); Fri, 28 Oct 2022 16:15:04 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33444 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229519AbiJ1UPC (ORCPT ); Fri, 28 Oct 2022 16:15:02 -0400 Received: from mail-wr1-x433.google.com (mail-wr1-x433.google.com [IPv6:2a00:1450:4864:20::433]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B0C323C16C for ; Fri, 28 Oct 2022 13:15:00 -0700 (PDT) Received: by mail-wr1-x433.google.com with SMTP id bs21so7977463wrb.4 for ; Fri, 28 Oct 2022 13:15:00 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=cc:to:mime-version:content-transfer-encoding:fcc:subject:date:from :references:in-reply-to:message-id:from:to:cc:subject:date :message-id:reply-to; bh=/QpniONDadL29AE82dKO6yOtA6u25QaY32iuzyD4GJw=; b=eZ58ruw2AoDr3Kdf2vRgoM0rKthiIbiOXh6RBTFYv/rI0SqcI3ZboMGiJ5Kcm+WzMs g/noeuOU8rQtvtRZeGvi84gNOUTnOhNeYS8YRHxRcmpvXkumDot8Qq/nlhchA4Uu2TOZ d7J1IGigDLF7Z4fSXRfLNIfyepiPCNDu+1y/ahZzlpkEG1urjxFmmFbswgmnKm55vmSo re7t028yXg7J7OlcpZzw8qCGZogFqO8ScNL4j11GqzNv4s+UK6p2IqQcOFMGci9HjvXd Bei9v7dJQk1R1zNQkX1L9k/F8blk1pXq6SHl7iFZsMowMGQ2EapV/vpMO2pIT5KCCwpN nRSQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:mime-version:content-transfer-encoding:fcc:subject:date:from :references:in-reply-to:message-id:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=/QpniONDadL29AE82dKO6yOtA6u25QaY32iuzyD4GJw=; b=Ejg6ti9t8edAKPZPFRQnhdIgMUFLcYDk9lgC0MgJj4X5O661o5QAjAssZ7MYzodYZE Ev2oFeYztbv4DgRt+w0t3A+w5rEnJT5OH+1CNv+aIAmkZjzuru8+xxhj0Rljo3GBWCLy yN4EKiBGINh79KMabmSP6KqjBfs09Ff1l2ddeNTvrSdX14DftvFCu1wfiZz7up22JaJn Yd+SxF96kjEvH3CkmloBBZIsp3xlUMX6y76nL9pKIdVW3tijdXx9i33HrG8Gm+u/sdID 4Q4Wtn6sweRgPGbvNiHqumhMa8JVsxbPwNrLTrEujhBzD4em7IQbeA5yEDzKJ3Jqjd9b Zejw== X-Gm-Message-State: ACrzQf23Cmb9+BPBzrS9TzzPtI16dhJvu+tHU782090miSN7lt4Mxrg+ UO2nVYXj7uuKraHnzkEkKkiLrxtOBFI= X-Google-Smtp-Source: AMsMyM7BhO7f6X6F2B4NYA7yDw7jxD1QGv5Axx7MPctGA/vs/RK/lyO8vsOuyN1u4Zhe6fPmqasXfg== X-Received: by 2002:a5d:4301:0:b0:236:9a64:53cd with SMTP id h1-20020a5d4301000000b002369a6453cdmr576486wrq.459.1666988098985; Fri, 28 Oct 2022 13:14:58 -0700 (PDT) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id i6-20020adfdec6000000b002366ded5864sm4462867wrn.116.2022.10.28.13.14.58 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 28 Oct 2022 13:14:58 -0700 (PDT) Message-Id: <432bc7cb3a42cf39d0033701c2cc677c9109b3dd.1666988096.git.gitgitgadget@gmail.com> In-Reply-To: References: Date: Fri, 28 Oct 2022 20:14:49 +0000 Subject: [PATCH v3 1/8] clone: teach --detach option Fcc: Sent MIME-Version: 1.0 To: git@vger.kernel.org Cc: Philippe Blain , Jonathan Tan , Glen Choo , Glen Choo Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Glen Choo From: Glen Choo Teach "git clone" the "--detach" option, which leaves the cloned repo in detached HEAD (like "git checkout --detach"). In addition, if the clone is not bare, do not create the local branch pointed to by the remote's HEAD symref (bare clones always copy all remote branches directly to local branches, so the branch is still created in the bare case). This is especially useful in the "submodule.propagateBranches" workflow, where local submodule branches are named after the superproject's branches, so it makes no sense to create a local branch named after the submodule's remote's branch. Signed-off-by: Glen Choo --- Documentation/git-clone.txt | 8 +++++++- builtin/clone.c | 12 +++++++++--- t/t5601-clone.sh | 22 ++++++++++++++++++++++ 3 files changed, 38 insertions(+), 4 deletions(-) diff --git a/Documentation/git-clone.txt b/Documentation/git-clone.txt index d6434d262d6..6a4e5d31b46 100644 --- a/Documentation/git-clone.txt +++ b/Documentation/git-clone.txt @@ -16,7 +16,7 @@ SYNOPSIS [--depth ] [--[no-]single-branch] [--no-tags] [--recurse-submodules[=]] [--[no-]shallow-submodules] [--[no-]remote-submodules] [--jobs ] [--sparse] [--[no-]reject-shallow] - [--filter= [--also-filter-submodules]] [--] + [--filter= [--also-filter-submodules] [--detach]] [--] [] DESCRIPTION @@ -210,6 +210,12 @@ objects from the source repository into a pack in the cloned repository. `--branch` can also take tags and detaches the HEAD at that commit in the resulting repository. +--detach:: + If the cloned repository's HEAD points to a branch, point the newly + created HEAD to the branch's commit instead of the branch itself. + Additionally, in a non-bare repository, the corresponding local branch + will not be created. + -u :: --upload-pack :: When given, and the repository to clone from is accessed diff --git a/builtin/clone.c b/builtin/clone.c index 547d6464b3c..e624d3f49a2 100644 --- a/builtin/clone.c +++ b/builtin/clone.c @@ -78,6 +78,7 @@ static int option_filter_submodules = -1; /* unspecified */ static int config_filter_submodules = -1; /* unspecified */ static struct string_list server_options = STRING_LIST_INIT_NODUP; static int option_remote_submodules; +static int option_detach; static const char *bundle_uri; static int recurse_submodules_cb(const struct option *opt, @@ -162,6 +163,8 @@ static struct option builtin_clone_options[] = { N_("any cloned submodules will use their remote-tracking branch")), OPT_BOOL(0, "sparse", &option_sparse_checkout, N_("initialize sparse-checkout file to include only files at root")), + OPT_BOOL(0, "detach", &option_detach, + N_("detach HEAD and don't create a local branch")), OPT_STRING(0, "bundle-uri", &bundle_uri, N_("uri"), N_("a URI for downloading bundles before fetching from origin remote")), OPT_END() @@ -613,10 +616,12 @@ static void update_remote_refs(const struct ref *refs, } static void update_head(const struct ref *our, const struct ref *remote, - const char *unborn, const char *msg) + const char *unborn, int should_detach, + const char *msg) { const char *head; - if (our && skip_prefix(our->name, "refs/heads/", &head)) { + if (our && !should_detach && + skip_prefix(our->name, "refs/heads/", &head)) { /* Local default branch link */ if (create_symref("HEAD", our->name, NULL) < 0) die(_("unable to update HEAD")); @@ -1357,7 +1362,8 @@ int cmd_clone(int argc, const char **argv, const char *prefix) branch_top.buf, reflog_msg.buf, transport, !is_local); - update_head(our_head_points_at, remote_head, unborn_head, reflog_msg.buf); + update_head(our_head_points_at, remote_head, unborn_head, + option_detach, reflog_msg.buf); /* * We want to show progress for recursive submodule clones iff diff --git a/t/t5601-clone.sh b/t/t5601-clone.sh index 45f0803ed4d..418cfd54717 100755 --- a/t/t5601-clone.sh +++ b/t/t5601-clone.sh @@ -333,6 +333,28 @@ test_expect_success 'clone checking out a tag' ' test_cmp fetch.expected fetch.actual ' +test_expect_success '--detach detaches and does not create branch' ' + test_when_finished "rm -fr dst" && + git clone --detach src dst && + ( + cd dst && + test_must_fail git rev-parse main && + test_must_fail git symbolic-ref HEAD && + test_cmp_rev HEAD refs/remotes/origin/HEAD + ) +' + +test_expect_success '--detach with --bare detaches but creates branch' ' + test_when_finished "rm -fr dst" && + git clone --bare --detach src dst && + ( + cd dst && + git rev-parse main && + test_must_fail git symbolic-ref HEAD && + test_cmp_rev HEAD refs/heads/main + ) +' + test_expect_success 'set up ssh wrapper' ' cp "$GIT_BUILD_DIR/t/helper/test-fake-ssh$X" \ "$TRASH_DIRECTORY/ssh$X" && From patchwork Fri Oct 28 20:14:50 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Glen Choo X-Patchwork-Id: 13024266 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 0F169FA3740 for ; Fri, 28 Oct 2022 20:15:12 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229846AbiJ1UPL (ORCPT ); Fri, 28 Oct 2022 16:15:11 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33530 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229455AbiJ1UPD (ORCPT ); Fri, 28 Oct 2022 16:15:03 -0400 Received: from mail-wr1-x432.google.com (mail-wr1-x432.google.com [IPv6:2a00:1450:4864:20::432]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D413640BE1 for ; Fri, 28 Oct 2022 13:15:01 -0700 (PDT) Received: by mail-wr1-x432.google.com with SMTP id j15so7989334wrq.3 for ; Fri, 28 Oct 2022 13:15:01 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=cc:to:mime-version:content-transfer-encoding:fcc:subject:date:from :references:in-reply-to:message-id:from:to:cc:subject:date :message-id:reply-to; bh=DEbtKNQludQ2CNUV9BL5HqEp9djAhuoJN08UPZbz5Bo=; b=aZGmQjb4rZR7szKZiXoVFR6C/657/JlBb8q/UGWGigg+f2/UddiD31vm/8IotrYps/ c9lkznkuj/AVMxJ9nnxubrEnotWDhl1e3Z8YnvIGJctVXeebdKaNs9qmJ1K4gqZjXoIu lk9o4eBrUJJyWnd46WtC7fA1pzya0CZZ2lEF1pvxe91SShPkHWoR5sviYGBFT9DKpIhi YBXsS8yEXj7Dyxi36u/lL+SlnpioKaliluzZACrmy5tkusELi5SWT7B4fT3S97Mud4aG J4N4FnKnpVsG8wVI0RXpb6rEs0+w2BQgShyct2/AAY/n9yyxVpqXSdkt+HfWTXN9DLlz iJLg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:mime-version:content-transfer-encoding:fcc:subject:date:from :references:in-reply-to:message-id:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=DEbtKNQludQ2CNUV9BL5HqEp9djAhuoJN08UPZbz5Bo=; b=GiCGJZMDCgYxyXQsYyYzMfchHiwsaSRahK5qMptXLZusKBgQiBLXXYMqoBKm7QMFB+ zDH+tuIC45Dcld7tYMQorbNXpIWt9f6dlzHHsa9xF1Z6bwrLIYc0yfZVa9IfQwXUZhGt HICyADeXuC3IghbIoj9RQX2tyNB6h6cbr/sU1wsKbERNlkCBVWrZ7fYvIMtyuAYZ+wAG CCgo4TA2W2AUhtsrJi3s2EOBRZ6fObicmWdPHJgNSARr++Kg3SlB/FKeGE/L8CyjSdFm dVLR/guzw0UQ2JyblwON6KJczNCR79zufFS0Px/LfLL3QS4svhFKYU9c3snyJYOY6aoN jJgg== X-Gm-Message-State: ACrzQf2FCGHzbFMVW1XxvlG7Bz7eyMqvtfWXLSjL2SzCWJYC8fm4xsnI +rQeg5VEUUGj//OFBxwUdHbAcY/2Mvs= X-Google-Smtp-Source: AMsMyM7PiNyHKv41twpqvlRegNznDTeq6Q+HkaZQteuEdS+VCg1GK47u3h8VBd1ipfDpcGDBO3K+Tg== X-Received: by 2002:a5d:6147:0:b0:236:aa4:6eca with SMTP id y7-20020a5d6147000000b002360aa46ecamr601372wrt.318.1666988100071; Fri, 28 Oct 2022 13:15:00 -0700 (PDT) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id p6-20020a05600c418600b003c6b874a0dfsm5559069wmh.14.2022.10.28.13.14.59 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 28 Oct 2022 13:14:59 -0700 (PDT) Message-Id: <06d7e15e830f7ede2aee43059b6d8666ecb00298.1666988096.git.gitgitgadget@gmail.com> In-Reply-To: References: Date: Fri, 28 Oct 2022 20:14:50 +0000 Subject: [PATCH v3 2/8] repo-settings: add submodule_propagate_branches Fcc: Sent MIME-Version: 1.0 To: git@vger.kernel.org Cc: Philippe Blain , Jonathan Tan , Glen Choo , Glen Choo Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Glen Choo From: Glen Choo When processes recurse into submodules, the child processes have to use the same value of "submodule.propagateBranches" as the parent process regardless of whether the process is spawned in the superproject or submodule, otherwise the behavior may be inconsistent if the repositories don't agree on the config. We haven't needed a way to propagate the config because the only command that reads "submodule.propagateBranches" is "git branch", which only has one mode of operation with "--recurse-submodules". However, a future commit will teach "submodule.propagateBranches" to "git submodule update", making this necessary. Propagate "submodule.propagateBranches" to child processes by adding a corresponding GIT_INTERNAL_* environment variable and repository setting, and setting the environment variable inside prepare_submodule_repo_env(). Then, refactor builtin/branch.c to read the repository setting. Using an internal environment variable is a potentially leaky abstraction because environment variables can come from sources besides the parent process. A more robust solution would be to teach Git that the repository is a submodule and to only read "submodule.propagateBranches" from the superproject config. There is WIP for this on the ML [1]. Another alternative would be to pass "-c submodule.propagateBranches" to all child processes. This is error-prone because many different processes are invoked directly or indirectly by "git submodule update" (e.g. "git submodule--helper clone", "git clone", "git checkout"). With an environment variable, we can avoid this work because prepare_submodule_repo_env() is already called for submodule child processes. [1] https://lore.kernel.org/git/20220310004423.2627181-1-emilyshaffer@google.com/ Signed-off-by: Glen Choo --- builtin/branch.c | 11 +++-------- cache.h | 1 + repo-settings.c | 13 +++++++++++++ repository.h | 1 + submodule.c | 2 ++ 5 files changed, 20 insertions(+), 8 deletions(-) diff --git a/builtin/branch.c b/builtin/branch.c index e0e0af43202..8279d4eeb15 100644 --- a/builtin/branch.c +++ b/builtin/branch.c @@ -40,7 +40,6 @@ static const char * const builtin_branch_usage[] = { static const char *head; static struct object_id head_oid; static int recurse_submodules = 0; -static int submodule_propagate_branches = 0; static int branch_use_color = -1; static char branch_colors[][COLOR_MAXLEN] = { @@ -106,10 +105,6 @@ static int git_branch_config(const char *var, const char *value, void *cb) recurse_submodules = git_config_bool(var, value); return 0; } - if (!strcasecmp(var, "submodule.propagateBranches")) { - submodule_propagate_branches = git_config_bool(var, value); - return 0; - } return git_color_default_config(var, value, cb); } @@ -723,7 +718,7 @@ int cmd_branch(int argc, const char **argv, const char *prefix) argc = parse_options(argc, argv, prefix, options, builtin_branch_usage, 0); - + prepare_repo_settings(the_repository); if (!delete && !rename && !copy && !edit_description && !new_upstream && !show_current && !unset_upstream && argc == 0) list = 1; @@ -739,7 +734,7 @@ int cmd_branch(int argc, const char **argv, const char *prefix) usage_with_options(builtin_branch_usage, options); if (recurse_submodules_explicit) { - if (!submodule_propagate_branches) + if (!the_repository->settings.submodule_propagate_branches) die(_("branch with --recurse-submodules can only be used if submodule.propagateBranches is enabled")); if (noncreate_actions) die(_("--recurse-submodules can only be used to create branches")); @@ -747,7 +742,7 @@ int cmd_branch(int argc, const char **argv, const char *prefix) recurse_submodules = (recurse_submodules || recurse_submodules_explicit) && - submodule_propagate_branches; + the_repository->settings.submodule_propagate_branches; if (filter.abbrev == -1) filter.abbrev = DEFAULT_ABBREV; diff --git a/cache.h b/cache.h index 26ed03bd6de..151e1d49e77 100644 --- a/cache.h +++ b/cache.h @@ -505,6 +505,7 @@ static inline enum object_type object_type(unsigned int mode) #define GIT_WORK_TREE_ENVIRONMENT "GIT_WORK_TREE" #define GIT_PREFIX_ENVIRONMENT "GIT_PREFIX" #define GIT_SUPER_PREFIX_ENVIRONMENT "GIT_INTERNAL_SUPER_PREFIX" +#define GIT_SUBMODULE_PROPAGATE_BRANCHES_ENVIRONMENT "GIT_INTERNAL_SUBMODULE_PROPAGATE_BRANCHES" #define DEFAULT_GIT_DIR_ENVIRONMENT ".git" #define DB_ENVIRONMENT "GIT_OBJECT_DIRECTORY" #define INDEX_ENVIRONMENT "GIT_INDEX_FILE" diff --git a/repo-settings.c b/repo-settings.c index e8b58151bc4..7ef2da9178d 100644 --- a/repo-settings.c +++ b/repo-settings.c @@ -71,6 +71,19 @@ void prepare_repo_settings(struct repository *r) if (git_env_bool(GIT_TEST_MULTI_PACK_INDEX, 0)) r->settings.core_multi_pack_index = 1; + /* + * If the environment variable is set, assume that it was set by an + * invocation of git running in a superproject with + * submodule.propagateBranches set and that is recursing into this repo + * as a submodule. Therefore, we should ignore whatever is set in this + * repo's config. + */ + r->settings.submodule_propagate_branches = + git_env_bool(GIT_SUBMODULE_PROPAGATE_BRANCHES_ENVIRONMENT, -1); + if (r->settings.submodule_propagate_branches == -1) + repo_cfg_bool(r, "submodule.propagateBranches", + &r->settings.submodule_propagate_branches, 0); + /* * Non-boolean config */ diff --git a/repository.h b/repository.h index 24316ac944e..3df6fdbdd5c 100644 --- a/repository.h +++ b/repository.h @@ -37,6 +37,7 @@ struct repo_settings { int fetch_write_commit_graph; int command_requires_full_index; int sparse_index; + int submodule_propagate_branches; struct fsmonitor_settings *fsmonitor; /* lazily loaded */ diff --git a/submodule.c b/submodule.c index bf7a2c79183..624404957fa 100644 --- a/submodule.c +++ b/submodule.c @@ -503,6 +503,8 @@ static void print_submodule_diff_summary(struct repository *r, struct rev_info * void prepare_submodule_repo_env(struct strvec *out) { + if (the_repository->settings.submodule_propagate_branches) + strvec_pushf(out, "%s=1", GIT_SUBMODULE_PROPAGATE_BRANCHES_ENVIRONMENT); prepare_other_repo_env(out, DEFAULT_GIT_DIR_ENVIRONMENT); } From patchwork Fri Oct 28 20:14:51 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Glen Choo X-Patchwork-Id: 13024267 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 723BFC38A02 for ; Fri, 28 Oct 2022 20:15:15 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229895AbiJ1UPM (ORCPT ); Fri, 28 Oct 2022 16:15:12 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33634 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229615AbiJ1UPE (ORCPT ); Fri, 28 Oct 2022 16:15:04 -0400 Received: from mail-wr1-x429.google.com (mail-wr1-x429.google.com [IPv6:2a00:1450:4864:20::429]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8BB643056B for ; Fri, 28 Oct 2022 13:15:02 -0700 (PDT) Received: by mail-wr1-x429.google.com with SMTP id g12so7957645wrs.10 for ; Fri, 28 Oct 2022 13:15:02 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=cc:to:mime-version:content-transfer-encoding:fcc:subject:date:from :references:in-reply-to:message-id:from:to:cc:subject:date :message-id:reply-to; bh=zk9/n3/N//VgzIqPESF7GvZyvogEh/1TnpqyiDw4ZZA=; b=aiVMifbY5EMVGRKYGlbB4DpXDnjaezBT04tRkmrq5kHg35eXQk3azeOnHMJLI4bRw6 N1+1zwN8s+v8ITrSAGG3iyjSxUxN/NslTwl0bkezQoqI9Y9qNCu1Lv7S6tE8PUGFW30Q x0zMcXAdyTosqSZYYugVRu8HJEP2f58KA1UbuzOg6V29FTAHsqiMN8gTgp5H38ZG/aVl HgPEPhMFyl0JHw6+hcqKTWm9wbPwwwWFxJLrPdBbb0QFu5sv7slVIJdFEkkKeAEoIN+R YZWik0sLQpMLrOpYK7ofZtlKj7Kk/ZRRLDPHpai6K55bx2U57jROBlXsxx9tcO+65O8A IXLw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:mime-version:content-transfer-encoding:fcc:subject:date:from :references:in-reply-to:message-id:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=zk9/n3/N//VgzIqPESF7GvZyvogEh/1TnpqyiDw4ZZA=; b=N3vJsqox/6rhi1750jTaju19U74hr/wtfelPE18RECPI6nWB7lZTfgAixAAzYrJz1N OICSetVvNnP0r2otjHwatWHfEioDjZjD6oSXjoBOcgKUPEQ6nJtLKoCAnhMWPt5j1mln PXuGPbcljTLfLSjYRfMGMq3WAAsGL4tzNYByT5I+/SzLBU3EDVJP1OF1ZdnlfoELsWDI yhESOJHqM0nmaDUURtg02yiePWWc4TFD0W0w/bYzD9ki/+2rgA11c1RrZipc6DTNfdyt Zh1URBfpLGctmo3zHoG1bOkTyuu0kbiZWyneHVnfiT6hu+1hcK9/HzXMP2jrxvVrGDWN +KbA== X-Gm-Message-State: ACrzQf0DSjDsQfo3NzGUUHL+OIqEfVPC3MQ3c3Yvw5cwIZK/jN2O08mX 3CpHVwks03aX+mdngc8UNfCLSGDA60k= X-Google-Smtp-Source: AMsMyM46MHFM7o0WzZk+YEMsjEiEZd9n5V0iAXqraJBWcnBHcUUxtM8YRnlCDN6C2VvFlZLViQOrHA== X-Received: by 2002:adf:e405:0:b0:236:6e0d:6ed2 with SMTP id g5-20020adfe405000000b002366e0d6ed2mr610762wrm.338.1666988100951; Fri, 28 Oct 2022 13:15:00 -0700 (PDT) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id n16-20020a1c7210000000b003c6deb5c1edsm5121617wmc.45.2022.10.28.13.15.00 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 28 Oct 2022 13:15:00 -0700 (PDT) Message-Id: <5a24d7e9255de407e343ce8bd60edb63293505bb.1666988096.git.gitgitgadget@gmail.com> In-Reply-To: References: Date: Fri, 28 Oct 2022 20:14:51 +0000 Subject: [PATCH v3 3/8] submodule--helper clone: create named branch Fcc: Sent MIME-Version: 1.0 To: git@vger.kernel.org Cc: Philippe Blain , Jonathan Tan , Glen Choo , Glen Choo Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Glen Choo From: Glen Choo When submodule branching is enabled (i.e. "submodule.propagateBranches = true"), submodules are expected to have the same set of branches as the superproject. To support this behavior in newly cloned submodules, teach "git submodule--helper clone" to: - clone with the "--detach" flag (so that the submodule doesn't create a branch corresponding to the remote's HEAD) - create a branch when using the --branch and --branch-oid flags The --branch and --branch-oid flags are only allowed when submodule branching is enabled, otherwise the named branch might conflict with the branch from the submodule remote's HEAD. This functionality will be tested in a later commit where "git submodule update" uses it to create and check out the correct branch when submodule branching is enabled. "git submodule add" (which also invokes "git submodule--helper clone") should also do something similar when submodule branching is enabled, but this is left for a later series. Arguably, "--detach" should also be the default for "submodule.propagateBranches=false" since it doesn't make sense to create a submodule branch when the submodule is always expected to be in detached HEAD. But, to be conservative, this commit does not change the behavior of "submodule.propagateBranches=false". Signed-off-by: Glen Choo --- builtin/submodule--helper.c | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index 0b4acb442b2..c974206cad4 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -1503,6 +1503,8 @@ struct module_clone_data { const char *name; const char *url; const char *depth; + const char *branch; + const char *branch_oid; struct list_objects_filter_options *filter_options; unsigned int quiet: 1; unsigned int progress: 1; @@ -1692,6 +1694,8 @@ static int clone_submodule(const struct module_clone_data *clone_data, strvec_push(&cp.args, clone_data->single_branch ? "--single-branch" : "--no-single-branch"); + if (the_repository->settings.submodule_propagate_branches) + strvec_push(&cp.args, "--detach"); strvec_push(&cp.args, "--"); strvec_push(&cp.args, clone_data->url); @@ -1704,6 +1708,21 @@ static int clone_submodule(const struct module_clone_data *clone_data, if(run_command(&cp)) die(_("clone of '%s' into submodule path '%s' failed"), clone_data->url, clone_data_path); + + if (clone_data->branch) { + struct child_process branch_cp = CHILD_PROCESS_INIT; + + branch_cp.git_cmd = 1; + prepare_other_repo_env(&branch_cp.env, sm_gitdir); + + strvec_pushl(&branch_cp.args, "branch", + clone_data->branch, clone_data->branch_oid, + NULL); + + if (run_command(&branch_cp)) + die(_("could not create branch '%s' in submodule path '%s'"), + clone_data->branch, clone_data_path); + } } else { char *path; @@ -1778,6 +1797,12 @@ static int module_clone(int argc, const char **argv, const char *prefix) N_("disallow cloning into non-empty directory")), OPT_BOOL(0, "single-branch", &clone_data.single_branch, N_("clone only one branch, HEAD or --branch")), + OPT_STRING(0, "branch", &clone_data.branch, + N_("string"), + N_("name of branch to be created")), + OPT_STRING(0, "branch-oid", &clone_data.branch_oid, + N_("object-id"), + N_("commit id for new branch")), OPT_PARSE_LIST_OBJECTS_FILTER(&filter_options), OPT_END() }; @@ -1785,12 +1810,14 @@ static int module_clone(int argc, const char **argv, const char *prefix) N_("git submodule--helper clone [--prefix=] [--quiet] " "[--reference ] [--name ] [--depth ] " "[--single-branch] [--filter ] " + "[--branch --branch-oid ]" "--url --path "), NULL }; argc = parse_options(argc, argv, prefix, module_clone_options, git_submodule_helper_usage, 0); + prepare_repo_settings(the_repository); clone_data.dissociate = !!dissociate; clone_data.quiet = !!quiet; @@ -1802,6 +1829,12 @@ static int module_clone(int argc, const char **argv, const char *prefix) usage_with_options(git_submodule_helper_usage, module_clone_options); + if (!!clone_data.branch != !!clone_data.branch_oid) + BUG("--branch and --branch-oid must be set/unset together"); + if ((clone_data.branch && + !the_repository->settings.submodule_propagate_branches)) + BUG("--branch is only expected with submodule.propagateBranches"); + clone_submodule(&clone_data, &reference); list_objects_filter_release(&filter_options); string_list_clear(&reference, 1); From patchwork Fri Oct 28 20:14:52 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Glen Choo X-Patchwork-Id: 13024269 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 35E44ECAAA1 for ; Fri, 28 Oct 2022 20:15:21 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229458AbiJ1UPS (ORCPT ); Fri, 28 Oct 2022 16:15:18 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33692 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229636AbiJ1UPF (ORCPT ); Fri, 28 Oct 2022 16:15:05 -0400 Received: from mail-wr1-x42d.google.com (mail-wr1-x42d.google.com [IPv6:2a00:1450:4864:20::42d]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 93E2B520BD for ; Fri, 28 Oct 2022 13:15:03 -0700 (PDT) Received: by mail-wr1-x42d.google.com with SMTP id y16so7940229wrt.12 for ; Fri, 28 Oct 2022 13:15:03 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=cc:to:mime-version:content-transfer-encoding:fcc:subject:date:from :references:in-reply-to:message-id:from:to:cc:subject:date :message-id:reply-to; bh=n+HssYl2LLbJYOQvNh3qEP9sTGLgHERbvBGu9EZ2czU=; b=IIK8XCsyTUPD+NkjqybWB0gs/dAWzTgXm6gheuD/+9FakC9V2dmN8x3yXEPim2FuJR 0zxEmAduBEw++yLPhnEVvOqVoqNoVwYV/sawBt0ngqjP8qQcT+QpnOmbLRU9TPkrSLTa Ds2iUWQHT1j4lNCeXB8JtV32waAdGSnvn11VCC3PR2YNcVIn9+OUfsQWsQZSMBJStoZM nYkECpb+6WhXJapRmygZpylg2wwP9CuR8bHUlpPNyGiAYuI4O6Z5p1iCUu+NYOX75xj0 Fp7HC5Oef0pvRFVps/U2VRJ2buz12t+tv8a8VCxaSZScG6jX8zwRXV95FZcEtlmb7E27 +IDA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:mime-version:content-transfer-encoding:fcc:subject:date:from :references:in-reply-to:message-id:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=n+HssYl2LLbJYOQvNh3qEP9sTGLgHERbvBGu9EZ2czU=; b=AaYPFg3U6okhv5iClS44+RDv5/23Gf8+1cclGXKHchmsLtrrw2N4gO002pTgfPHVIu ypMgddvpRWKVYoPIxX1ukCBPNP8vhB2faJkkEcV7mA/kQMmDQMiot/klUmuGzAxymkpS gfp/e4FlG3AEYW9s1cWuRzs5NwRCqToPI2aWLU+d5FuApIrRRtLgfD56GB9HfVSybXDt COjWFv5XJzVu/k9qcKmHeNX838pFvW0+tAl3UTv1z3qi4su1KDsy6bPI2e9V/UqXkre9 7COsAsGSPXfMO0cIZ6GY5Vjr3LikuP0J/0DoTbZV4jMguceFgSCftJ1kYhsDf2VeqfSQ s0nA== X-Gm-Message-State: ACrzQf0ro+qfhU1lsue6lLQnswFwtsP98z9zLP2lvhNli/x5o+33OQqI UumnyPenVUO0Yzy39AteVGPTBD/OznU= X-Google-Smtp-Source: AMsMyM4IxLHgaR7sbPs0ksJYh1PCI7cszzN+SjMcRl89PyTIaUWFikNvWiPHZaHwxeDrdBeSpcdWvg== X-Received: by 2002:a05:6000:71d:b0:22e:71d1:8c50 with SMTP id bs29-20020a056000071d00b0022e71d18c50mr584006wrb.239.1666988101937; Fri, 28 Oct 2022 13:15:01 -0700 (PDT) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id q65-20020a1c4344000000b003c71358a42dsm9369157wma.18.2022.10.28.13.15.01 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 28 Oct 2022 13:15:01 -0700 (PDT) Message-Id: <3a08f2ab776b037e00a47fb7ed63a3f50056350b.1666988096.git.gitgitgadget@gmail.com> In-Reply-To: References: Date: Fri, 28 Oct 2022 20:14:52 +0000 Subject: [PATCH v3 4/8] t5617: drop references to remote-tracking branches Fcc: Sent MIME-Version: 1.0 To: git@vger.kernel.org Cc: Philippe Blain , Jonathan Tan , Glen Choo , Glen Choo Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Glen Choo From: Glen Choo It has included submodule cloning tests without remote-tracking branches tests since f05da2b48b (clone, submodule: pass partial clone filters to submodules, 2022-02-04) at least. Rename it accordingly so that we can put future submodule cloning tests there. Signed-off-by: Glen Choo --- ...617-clone-submodules-remote.sh => t5617-clone-submodules.sh} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename t/{t5617-clone-submodules-remote.sh => t5617-clone-submodules.sh} (97%) diff --git a/t/t5617-clone-submodules-remote.sh b/t/t5617-clone-submodules.sh similarity index 97% rename from t/t5617-clone-submodules-remote.sh rename to t/t5617-clone-submodules.sh index 68843382493..c43a5b26fab 100755 --- a/t/t5617-clone-submodules-remote.sh +++ b/t/t5617-clone-submodules.sh @@ -1,6 +1,6 @@ #!/bin/sh -test_description='Test cloning repos with submodules using remote-tracking branches' +test_description='Test cloning repos with submodules' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME From patchwork Fri Oct 28 20:14:53 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Glen Choo X-Patchwork-Id: 13024268 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 EBEF4FA3740 for ; Fri, 28 Oct 2022 20:15:17 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229911AbiJ1UPQ (ORCPT ); Fri, 28 Oct 2022 16:15:16 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33658 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229629AbiJ1UPF (ORCPT ); Fri, 28 Oct 2022 16:15:05 -0400 Received: from mail-wr1-x432.google.com (mail-wr1-x432.google.com [IPv6:2a00:1450:4864:20::432]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8FD782FFF3 for ; Fri, 28 Oct 2022 13:15:03 -0700 (PDT) Received: by mail-wr1-x432.google.com with SMTP id j15so7989476wrq.3 for ; Fri, 28 Oct 2022 13:15:03 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=cc:to:mime-version:content-transfer-encoding:fcc:subject:date:from :references:in-reply-to:message-id:from:to:cc:subject:date :message-id:reply-to; bh=h+7Pkum1CZN6Gu+UTIed++mZ1ap2H6PJ3zGktaEIrgg=; b=J+RkPwC8c//oScAxxqvrBqAotw3zCdDbtAhT1EPuz5CPfDPMU/pX3SOnUe7vfiiJWM kMcPjHDI1OKM3h+hpFZc69QeoB2aC9P7tqnmjmIkuQWgu5CdIZ9bnZDBYIcXPJy1wubb lPPyEnGlwdgkeEp+t1hJ7KsXYovn1E9AXrDCBrzyyOBdzdkMWOnxQuvbK2FT2DndCmEk Bn++bKwWAKijskbe97qrNUBX5Kr0z37ZgJaCF8ZBjTjaBHtnMvX6MBRGbXQRIonlGH95 y8PeEMYHP1rZFpOl85PLUuOQesEKExRHPDheeqDQez3PDCnf4IbQDWXmvfXDOgoUhIam iZLA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:mime-version:content-transfer-encoding:fcc:subject:date:from :references:in-reply-to:message-id:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=h+7Pkum1CZN6Gu+UTIed++mZ1ap2H6PJ3zGktaEIrgg=; b=zZ7Z/gGSdixPnXDQGBD74gruD2kRQQas3Aw1dP/KYbqryk7Vr7GP7KuuQjknsVd/65 bGsBVKNPcHbZ4Chigyr0fuPZ4AnB3RZkfRILzQyM6dbL9f0AEALxyriKNp3kjFdEJuT2 jJUCogwLJldnU3/KvdRFhKZhRgL2QGeG/rmcUHFecoaSha2HZTzM2LbB90Euh1ufRhPU T+vSsPzUcWcYIbdNUE2J23hFVKbVeNbqi5MUlDRjUzwvK/mT9S+ZNgSm6jHpK6fH20+P m4r+FIXt4dL9E4s4NmWn68JWCopVYIpvDd2Gw/fbuqj6TsD3SrwmL1ZB5OcRzcGH6BZP aOZA== X-Gm-Message-State: ACrzQf1p0TikfyMdXYz0YrQrnhYjoIN5bP+sibweCg0JUgi1ymDtskRM lnI68pRi8Q+toV2i1P1DxMKu5I+94G4= X-Google-Smtp-Source: AMsMyM57ku7f7Vnn3Zabun7Na1NP/1ExD03Y8hULzAHJ4gpqAV4kLh1DC4PKyDhVnJXsT+4/5A17WA== X-Received: by 2002:adf:e610:0:b0:236:737f:8e5d with SMTP id p16-20020adfe610000000b00236737f8e5dmr620507wrm.316.1666988102876; Fri, 28 Oct 2022 13:15:02 -0700 (PDT) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id x18-20020adfdcd2000000b00236863c02f5sm4247288wrm.96.2022.10.28.13.15.02 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 28 Oct 2022 13:15:02 -0700 (PDT) Message-Id: In-Reply-To: References: Date: Fri, 28 Oct 2022 20:14:53 +0000 Subject: [PATCH v3 5/8] submodule: return target of submodule symref Fcc: Sent MIME-Version: 1.0 To: git@vger.kernel.org Cc: Philippe Blain , Jonathan Tan , Glen Choo , Glen Choo Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Glen Choo From: Glen Choo resolve_gitlink_ref() can tell us which oid the submodule ref is pointing to, but in a future commit, we would also like to know the symbolic ref target if we are checking a symbolic ref. Teach resolve_gitlink_ref() to "return" the symbolic ref's target via an "out" parameter. This changes resolve_gitlink_ref()'s signature so that new callers trying to use the old signature will be stopped by the compiler. If we returned the target instead (just like refs_resolve_ref_unsafe()), we would be more consistent with refs_resolve_ref_unsafe(), but callers expecting the old signature will get the opposite return value from what they expect (since exit code 0 means success, but NULL pointer means failure). We should do this refactor once we think that nobody will try to use the old signature. Signed-off-by: Glen Choo --- builtin/submodule--helper.c | 8 +++++--- builtin/update-index.c | 4 ++-- combine-diff.c | 3 ++- diff-lib.c | 2 +- dir.c | 2 +- object-file.c | 2 +- read-cache.c | 4 ++-- refs.c | 10 ++++++---- refs.h | 5 ++++- unpack-trees.c | 3 ++- 10 files changed, 26 insertions(+), 17 deletions(-) diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index c974206cad4..9ca138374b7 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -2533,7 +2533,8 @@ static int update_submodule(struct update_data *update_data) if (update_data->just_cloned) oidcpy(&update_data->suboid, null_oid()); - else if (resolve_gitlink_ref(update_data->sm_path, "HEAD", &update_data->suboid)) + else if (resolve_gitlink_ref(update_data->sm_path, "HEAD", + &update_data->suboid, NULL)) return die_message(_("Unable to find current revision in submodule path '%s'"), update_data->displaypath); @@ -2560,7 +2561,8 @@ static int update_submodule(struct update_data *update_data) update_data->sm_path); } - if (resolve_gitlink_ref(update_data->sm_path, remote_ref, &update_data->oid)) + if (resolve_gitlink_ref(update_data->sm_path, remote_ref, + &update_data->oid, NULL)) return die_message(_("Unable to find %s revision in submodule path '%s'"), remote_ref, update_data->sm_path); @@ -3305,7 +3307,7 @@ static void die_on_repo_without_commits(const char *path) strbuf_addstr(&sb, path); if (is_nonbare_repository_dir(&sb)) { struct object_id oid; - if (resolve_gitlink_ref(path, "HEAD", &oid) < 0) + if (resolve_gitlink_ref(path, "HEAD", &oid, NULL) < 0) die(_("'%s' does not have a commit checked out"), path); } strbuf_release(&sb); diff --git a/builtin/update-index.c b/builtin/update-index.c index b62249905f1..19a21a4586c 100644 --- a/builtin/update-index.c +++ b/builtin/update-index.c @@ -339,7 +339,7 @@ static int process_directory(const char *path, int len, struct stat *st) if (S_ISGITLINK(ce->ce_mode)) { /* Do nothing to the index if there is no HEAD! */ - if (resolve_gitlink_ref(path, "HEAD", &oid) < 0) + if (resolve_gitlink_ref(path, "HEAD", &oid, NULL) < 0) return 0; return add_one_path(ce, path, len, st); @@ -365,7 +365,7 @@ static int process_directory(const char *path, int len, struct stat *st) } /* No match - should we add it as a gitlink? */ - if (!resolve_gitlink_ref(path, "HEAD", &oid)) + if (!resolve_gitlink_ref(path, "HEAD", &oid, NULL)) return add_one_path(NULL, path, len, st); /* Error out. */ diff --git a/combine-diff.c b/combine-diff.c index b0ece954808..88efcaeefa7 100644 --- a/combine-diff.c +++ b/combine-diff.c @@ -1060,7 +1060,8 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent, elem->mode = canon_mode(st.st_mode); } else if (S_ISDIR(st.st_mode)) { struct object_id oid; - if (resolve_gitlink_ref(elem->path, "HEAD", &oid) < 0) + if (resolve_gitlink_ref(elem->path, "HEAD", &oid, + NULL) < 0) result = grab_blob(opt->repo, &elem->oid, elem->mode, &result_size, NULL, NULL); diff --git a/diff-lib.c b/diff-lib.c index 2edea41a234..ac94b6234ca 100644 --- a/diff-lib.c +++ b/diff-lib.c @@ -53,7 +53,7 @@ static int check_removed(const struct index_state *istate, const struct cache_en * a directory --- the blob was removed! */ if (!S_ISGITLINK(ce->ce_mode) && - resolve_gitlink_ref(ce->name, "HEAD", &sub)) + resolve_gitlink_ref(ce->name, "HEAD", &sub, NULL)) return 1; } return 0; diff --git a/dir.c b/dir.c index d604d1bab98..81d232424c1 100644 --- a/dir.c +++ b/dir.c @@ -3251,7 +3251,7 @@ static int remove_dir_recurse(struct strbuf *path, int flag, int *kept_up) struct object_id submodule_head; if ((flag & REMOVE_DIR_KEEP_NESTED_GIT) && - !resolve_gitlink_ref(path->buf, "HEAD", &submodule_head)) { + !resolve_gitlink_ref(path->buf, "HEAD", &submodule_head, NULL)) { /* Do not descend and nuke a nested git work tree. */ if (kept_up) *kept_up = 1; diff --git a/object-file.c b/object-file.c index 5e309602346..a3c6580c16e 100644 --- a/object-file.c +++ b/object-file.c @@ -2522,7 +2522,7 @@ int index_path(struct index_state *istate, struct object_id *oid, strbuf_release(&sb); break; case S_IFDIR: - return resolve_gitlink_ref(path, "HEAD", oid); + return resolve_gitlink_ref(path, "HEAD", oid, NULL); default: return error(_("%s: unsupported file type"), path); } diff --git a/read-cache.c b/read-cache.c index 32024029274..4c1bf33ef48 100644 --- a/read-cache.c +++ b/read-cache.c @@ -285,7 +285,7 @@ static int ce_compare_gitlink(const struct cache_entry *ce) * * If so, we consider it always to match. */ - if (resolve_gitlink_ref(ce->name, "HEAD", &oid) < 0) + if (resolve_gitlink_ref(ce->name, "HEAD", &oid, NULL) < 0) return 0; return !oideq(&oid, &ce->oid); } @@ -781,7 +781,7 @@ int add_to_index(struct index_state *istate, const char *path, struct stat *st, namelen = strlen(path); if (S_ISDIR(st_mode)) { - if (resolve_gitlink_ref(path, "HEAD", &oid) < 0) + if (resolve_gitlink_ref(path, "HEAD", &oid, NULL) < 0) return error(_("'%s' does not have a commit checked out"), path); while (namelen && path[namelen-1] == '/') namelen--; diff --git a/refs.c b/refs.c index 1491ae937eb..a32a25ccb69 100644 --- a/refs.c +++ b/refs.c @@ -1904,19 +1904,21 @@ const char *resolve_ref_unsafe(const char *refname, int resolve_flags, } int resolve_gitlink_ref(const char *submodule, const char *refname, - struct object_id *oid) + struct object_id *oid, const char **target_out) { struct ref_store *refs; int flags; + const char *target; refs = get_submodule_ref_store(submodule); if (!refs) return -1; - - if (!refs_resolve_ref_unsafe(refs, refname, 0, oid, &flags) || - is_null_oid(oid)) + target = refs_resolve_ref_unsafe(refs, refname, 0, oid, &flags); + if (!target || is_null_oid(oid)) return -1; + if (target_out) + *target_out = target; return 0; } diff --git a/refs.h b/refs.h index 8958717a17d..d5c32fac000 100644 --- a/refs.h +++ b/refs.h @@ -137,9 +137,12 @@ int peel_iterated_oid(const struct object_id *base, struct object_id *peeled); * submodule (which must be non-NULL). If the resolution is * successful, return 0 and set oid to the name of the object; * otherwise, return a non-zero value. + * + * FIXME: Return "target" just like refs_resolve_ref_unsafe(). This will be + * safe to do once we merge resolve_gitlink_ref() into master. */ int resolve_gitlink_ref(const char *submodule, const char *refname, - struct object_id *oid); + struct object_id *oid, const char **target); /* * Return true iff abbrev_name is a possible abbreviation for diff --git a/unpack-trees.c b/unpack-trees.c index bae812156c4..db12bfcaffd 100644 --- a/unpack-trees.c +++ b/unpack-trees.c @@ -2288,7 +2288,8 @@ static int verify_clean_subdirectory(const struct cache_entry *ce, if (S_ISGITLINK(ce->ce_mode)) { struct object_id oid; - int sub_head = resolve_gitlink_ref(ce->name, "HEAD", &oid); + int sub_head = + resolve_gitlink_ref(ce->name, "HEAD", &oid, NULL); /* * If we are not going to update the submodule, then * we don't care. From patchwork Fri Oct 28 20:14:54 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Glen Choo X-Patchwork-Id: 13024271 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 1021AC38A02 for ; Fri, 28 Oct 2022 20:15:41 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230039AbiJ1UPi (ORCPT ); Fri, 28 Oct 2022 16:15:38 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33818 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229728AbiJ1UPH (ORCPT ); Fri, 28 Oct 2022 16:15:07 -0400 Received: from mail-wr1-x42d.google.com (mail-wr1-x42d.google.com [IPv6:2a00:1450:4864:20::42d]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id AEB5152FF9 for ; Fri, 28 Oct 2022 13:15:05 -0700 (PDT) Received: by mail-wr1-x42d.google.com with SMTP id k8so8003225wrh.1 for ; Fri, 28 Oct 2022 13:15:05 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=cc:to:mime-version:content-transfer-encoding:fcc:subject:date:from :references:in-reply-to:message-id:from:to:cc:subject:date :message-id:reply-to; bh=hU9HVHrNabwm24/YjLnxK0iByLEvRtPIehyF5akJ4gI=; b=mL+eVFA/z0IxmEVmODwseOXAKjrLHEU6uUy3muwAlp6FrKbB5l0FZw3tJ40Am06dVA 585b6g3efIV0Ywm7kN/G0TDetEbxNO3b8PYqtweb0bDdPoYV5gZYVwPIMBl5ARUUUnfV 2wQoSXw95MKYtXUK3qrbQgGP5hhZGcln9ko++Dy51BglWD+QSD3bSPoTuOih/GNKGuFM Fk1m6zYgr0OD2hs1sBxgAS7NQmBl7QbW1ezchzW6kpu0BEZSCmVNUKrh8lSDjQ3hsYks xzAqtkleiuaPKs9cgklL8y6D8pk1EdUE22WwuKGDwq0IRQCa5J9XSw8BDSF16bwMaLYS NodQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:mime-version:content-transfer-encoding:fcc:subject:date:from :references:in-reply-to:message-id:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=hU9HVHrNabwm24/YjLnxK0iByLEvRtPIehyF5akJ4gI=; b=OHYI2ODlkoR5/xtR46rEAN5nIs52auaVumbQ1biF0FGuTX1CVx8vLDGZ3ZOvolKHZe ml+ORhUnn1mFmjyPZVIDrjM8n6LwY5WiFfMRUbMHDJ2gGgQm47VoCFznAlgnd4988t7u BGyGwTEZUCDs/QaOJQEeQG2hkkEeqbK0Ls8tRygEarvwGI5eMXk1rKdCl24jLQGcNLKa z5puEfe5jNMStPNhTQ+ySq3zaRP3mbkgNWUA971Vp7RMkR54jHlbbYnnwk94LXfzQcvc Cbx5rV53mAzzvxuI7esjfO7y20y856hTe5RfrOh6hhqV1sWt/s0YxXA0X3O85Ewf7LhU hrjw== X-Gm-Message-State: ACrzQf2y2fVlCchgSX9u2dgxSKa4F91/uk0KdYuHoRQuRM8UavyzWG2W upoTir7+F1TU2J0LWUvtLYrYYKst89w= X-Google-Smtp-Source: AMsMyM7cyQ2myKmojNrWDo2gMqGzSXWdKffJYh3A/ATux4AQ0zfjpTSNd5xhr6gw2hAl/rnptYhHQw== X-Received: by 2002:a5d:5847:0:b0:231:21fa:ba96 with SMTP id i7-20020a5d5847000000b0023121faba96mr572688wrf.477.1666988103990; Fri, 28 Oct 2022 13:15:03 -0700 (PDT) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id k1-20020adff281000000b0022ac672654dsm4362098wro.58.2022.10.28.13.15.03 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 28 Oct 2022 13:15:03 -0700 (PDT) Message-Id: In-Reply-To: References: Date: Fri, 28 Oct 2022 20:14:54 +0000 Subject: [PATCH v3 6/8] submodule update: refactor update targets Fcc: Sent MIME-Version: 1.0 To: git@vger.kernel.org Cc: Philippe Blain , Jonathan Tan , Glen Choo , Glen Choo Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Glen Choo From: Glen Choo Refactor two "git submodule update" code locations so that they no longer refer to oids directly. This shrinks a subsequent commit's diff, where this code will need to handle branches. Signed-off-by: Glen Choo --- builtin/submodule--helper.c | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index 9ca138374b7..894be133b3f 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -2255,7 +2255,7 @@ static int fetch_in_submodule(const char *module_path, int depth, int quiet, static int run_update_command(const struct update_data *ud, int subforce) { struct child_process cp = CHILD_PROCESS_INIT; - char *oid = oid_to_hex(&ud->oid); + const char *update_target = oid_to_hex(&ud->oid);; int ret; switch (ud->update_strategy.type) { @@ -2285,7 +2285,7 @@ static int run_update_command(const struct update_data *ud, int subforce) BUG("unexpected update strategy type: %d", ud->update_strategy.type); } - strvec_push(&cp.args, oid); + strvec_push(&cp.args, update_target); cp.dir = ud->sm_path; prepare_submodule_repo_env(&cp.env); @@ -2293,20 +2293,20 @@ static int run_update_command(const struct update_data *ud, int subforce) switch (ud->update_strategy.type) { case SM_UPDATE_CHECKOUT: die_message(_("Unable to checkout '%s' in submodule path '%s'"), - oid, ud->displaypath); + update_target, ud->displaypath); /* No "ret" assignment, use "git checkout"'s */ break; case SM_UPDATE_REBASE: ret = die_message(_("Unable to rebase '%s' in submodule path '%s'"), - oid, ud->displaypath); + update_target, ud->displaypath); break; case SM_UPDATE_MERGE: ret = die_message(_("Unable to merge '%s' in submodule path '%s'"), - oid, ud->displaypath); + update_target, ud->displaypath); break; case SM_UPDATE_COMMAND: ret = die_message(_("Execution of '%s %s' failed in submodule path '%s'"), - ud->update_strategy.command, oid, ud->displaypath); + ud->update_strategy.command, update_target, ud->displaypath); break; default: BUG("unexpected update strategy type: %d", @@ -2322,19 +2322,19 @@ static int run_update_command(const struct update_data *ud, int subforce) switch (ud->update_strategy.type) { case SM_UPDATE_CHECKOUT: printf(_("Submodule path '%s': checked out '%s'\n"), - ud->displaypath, oid); + ud->displaypath, update_target); break; case SM_UPDATE_REBASE: printf(_("Submodule path '%s': rebased into '%s'\n"), - ud->displaypath, oid); + ud->displaypath, update_target); break; case SM_UPDATE_MERGE: printf(_("Submodule path '%s': merged in '%s'\n"), - ud->displaypath, oid); + ud->displaypath, update_target); break; case SM_UPDATE_COMMAND: printf(_("Submodule path '%s': '%s %s'\n"), - ud->displaypath, ud->update_strategy.command, oid); + ud->displaypath, ud->update_strategy.command, update_target); break; default: BUG("unexpected update strategy type: %d", @@ -2521,6 +2521,7 @@ static void update_data_to_args(const struct update_data *update_data, static int update_submodule(struct update_data *update_data) { + int submodule_up_to_date; int ret; ret = determine_submodule_update_strategy(the_repository, @@ -2569,7 +2570,8 @@ static int update_submodule(struct update_data *update_data) free(remote_ref); } - if (!oideq(&update_data->oid, &update_data->suboid) || update_data->force) { + submodule_up_to_date = oideq(&update_data->oid, &update_data->suboid); + if (!submodule_up_to_date || update_data->force) { ret = run_update_procedure(update_data); if (ret) return ret; From patchwork Fri Oct 28 20:14:55 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Glen Choo X-Patchwork-Id: 13024272 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 EE5C4C38A02 for ; Fri, 28 Oct 2022 20:15:43 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229728AbiJ1UPl (ORCPT ); Fri, 28 Oct 2022 16:15:41 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33692 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229674AbiJ1UPI (ORCPT ); Fri, 28 Oct 2022 16:15:08 -0400 Received: from mail-wr1-x42b.google.com (mail-wr1-x42b.google.com [IPv6:2a00:1450:4864:20::42b]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7C67C53A63 for ; Fri, 28 Oct 2022 13:15:06 -0700 (PDT) Received: by mail-wr1-x42b.google.com with SMTP id v1so7959439wrt.11 for ; Fri, 28 Oct 2022 13:15:06 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=cc:to:mime-version:content-transfer-encoding:fcc:subject:date:from :references:in-reply-to:message-id:from:to:cc:subject:date :message-id:reply-to; bh=Xv5jxGDqP4i8h4L7UXLO2UZHu0ST4taarwBqS9qr/rg=; b=Xx8mZT/X+S7ZDvNDwnLg8ZTXWaTZW0HNEwu3mwE9ONFPhpRSY9fSoMMo/etsBlO2En 1lwTi+AXTYUhCRBKlmgtnUKh/13RVzXqEhhFLJgxV17xtfGiSRYoJjCW0kfVV6QlqXEG lA3B+JPXPlBuI6V5wswPI3RYN3XtzqW0MTNjdcs0vstgBPit3Ewy3JkQAsg1FIq+Zbk4 GWCnCY45Z5yWhQMF0798aGcG59iDGouha/f9uU4np32pNRwf4ZOsyOpe5T7A8dQoJOop r0wi0/bgPzdubGdx3Ow8IAJYCHpWbcTuvD6yNlzZ9nI5jLWALDnZiTOqRPR8brOghRZ/ o9QQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:mime-version:content-transfer-encoding:fcc:subject:date:from :references:in-reply-to:message-id:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=Xv5jxGDqP4i8h4L7UXLO2UZHu0ST4taarwBqS9qr/rg=; b=ChqWX5Mw6wklSWRNTb5/j8cdPoWiifiB5LE43w7dPCYwEv0CFclQ4yEqbiAROOCDX9 LxCkw1hXs2MQeBc7BMzTuPY1SAkFyeIjQAsQKWbpQ7BJBq2h6FBS8vCyUM/6+Y6BCDVU d4uPVFhS3wzwwz6YJnnmaOxf2mcNkNKqbX1wI/5nSKvG9MQbJBFJ7QrGSRmdnic0RMYn jvP7sEcZ/DDvUiNGMdxau29Witjq7EIi2ErcwTWqgMECs+gRcnwlHpHNb8rXi3fROq+m fw80laFxe3c/ZWGxrHZC2MfuBJ9x+PD6UbVJLrufVjK+sFWk1PiaasbUf3g03og41Q5D qgGw== X-Gm-Message-State: ACrzQf2wAopv7H8VxxKLrAIHmgEgvGJBiZLIim773j+Zw7429qNVG2bp t3BJ9mFQNaZcpVcWuN9tkkCHNFHTGJg= X-Google-Smtp-Source: AMsMyM73jevreLP/JUE40YtXK7UJHqXYpofnqQRjLoPA6enz8+j6mCjcx1S/zjcLtJluzgKsxFfbWw== X-Received: by 2002:adf:f843:0:b0:236:9d21:4c79 with SMTP id d3-20020adff843000000b002369d214c79mr560010wrq.606.1666988104886; Fri, 28 Oct 2022 13:15:04 -0700 (PDT) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id h7-20020a5d6887000000b002356c051b9csm4245926wru.66.2022.10.28.13.15.04 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 28 Oct 2022 13:15:04 -0700 (PDT) Message-Id: <4e402b67145c6e33c13826f1daf1883a66cd9cd4.1666988096.git.gitgitgadget@gmail.com> In-Reply-To: References: Date: Fri, 28 Oct 2022 20:14:55 +0000 Subject: [PATCH v3 7/8] submodule--helper: remove update_data.suboid Fcc: Sent MIME-Version: 1.0 To: git@vger.kernel.org Cc: Philippe Blain , Jonathan Tan , Glen Choo , Glen Choo Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Glen Choo From: Glen Choo update_data.suboid's value is only used in update_submodule()'s call chain, where it represents the OID of the submodule's HEAD. If the submodule is newly cloned, it is set to null_oid(). Instead of checking for the null OID, just check if the submodule is newly cloned. This makes update_submodule() the only function where update_data.suboid is used, so replace it with a local variable. As a result, the submodule_up_to_date check is more explicit, which makes the next commit slightly easier to reason about. Signed-off-by: Glen Choo --- builtin/submodule--helper.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index 894be133b3f..ef76a111c7f 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -1918,7 +1918,6 @@ struct update_data { const char *prefix; char *displaypath; enum submodule_update_type update_default; - struct object_id suboid; struct string_list references; struct submodule_update_strategy update_strategy; struct list_objects_filter_options *filter_options; @@ -2346,7 +2345,7 @@ static int run_update_command(const struct update_data *ud, int subforce) static int run_update_procedure(const struct update_data *ud) { - int subforce = is_null_oid(&ud->suboid) || ud->force; + int subforce = ud->just_cloned || ud->force; if (!ud->nofetch) { /* @@ -2523,6 +2522,7 @@ static int update_submodule(struct update_data *update_data) { int submodule_up_to_date; int ret; + struct object_id suboid; ret = determine_submodule_update_strategy(the_repository, update_data->just_cloned, @@ -2532,10 +2532,8 @@ static int update_submodule(struct update_data *update_data) if (ret) return ret; - if (update_data->just_cloned) - oidcpy(&update_data->suboid, null_oid()); - else if (resolve_gitlink_ref(update_data->sm_path, "HEAD", - &update_data->suboid, NULL)) + if (!update_data->just_cloned && + resolve_gitlink_ref(update_data->sm_path, "HEAD", &suboid, NULL)) return die_message(_("Unable to find current revision in submodule path '%s'"), update_data->displaypath); @@ -2570,7 +2568,8 @@ static int update_submodule(struct update_data *update_data) free(remote_ref); } - submodule_up_to_date = oideq(&update_data->oid, &update_data->suboid); + submodule_up_to_date = !update_data->just_cloned && + oideq(&update_data->oid, &suboid); if (!submodule_up_to_date || update_data->force) { ret = run_update_procedure(update_data); if (ret) @@ -2583,7 +2582,6 @@ static int update_submodule(struct update_data *update_data) next.prefix = NULL; oidcpy(&next.oid, null_oid()); - oidcpy(&next.suboid, null_oid()); cp.dir = update_data->sm_path; cp.git_cmd = 1; From patchwork Fri Oct 28 20:14:56 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Glen Choo X-Patchwork-Id: 13024270 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 1A17BC38A02 for ; Fri, 28 Oct 2022 20:15:37 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229959AbiJ1UPf (ORCPT ); Fri, 28 Oct 2022 16:15:35 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33820 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229777AbiJ1UPH (ORCPT ); Fri, 28 Oct 2022 16:15:07 -0400 Received: from mail-wr1-x42d.google.com (mail-wr1-x42d.google.com [IPv6:2a00:1450:4864:20::42d]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 62E8753025 for ; Fri, 28 Oct 2022 13:15:06 -0700 (PDT) Received: by mail-wr1-x42d.google.com with SMTP id y16so7940399wrt.12 for ; Fri, 28 Oct 2022 13:15:06 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=cc:to:mime-version:content-transfer-encoding:fcc:subject:date:from :references:in-reply-to:message-id:from:to:cc:subject:date :message-id:reply-to; bh=jfb9vpVMq7FbscgphHNXqmVqFeU2OEeEOTA7euf3Zeg=; b=b3LsxxboesNBOt3sSvXaed8nai5PAP4UtggG2XEiK5Z7ehC4n5vX+C8CFztpx1eAZs nLfov2J8KGOuYCUZBlQ8pPyPjVDlY5dYzNiJU4z1DGEHtYJmVnIqoZflAykkrsi8Km85 Z+VDHvgoAI/2JGdjCIA4g/6Wr7IDL0IWQN55+l1KL/hcUq5x8ZhldpVZtPccESjwFv2d EvZ1GzWKGbANwbpOy/PGKqGcOnROwEOfXXgzJQraRLS7LOamMoFVd0UI8QZg50Ij8pi6 Yp5GonmAmi3tSYdzdN2cqArbk5WifUC1rE/JA8VZXwX5W0ier9l84JBjiKTVEWqXOu6O tI9A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:mime-version:content-transfer-encoding:fcc:subject:date:from :references:in-reply-to:message-id:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=jfb9vpVMq7FbscgphHNXqmVqFeU2OEeEOTA7euf3Zeg=; b=pKvhXlkdvJsGcqr/LfzkzpdDopRGYj2XA2GRifGjY9ZrxEx5U9AVwyDklAStKEZU6w PR16Oks4ccICyESt+c/hoMCcVo+MJmCAPm3seOExcRldq9Lg0OG/OrdmjlfOinAZfdrI GayhpHFTk9ZFuiNyW5BmuiAU/eVwRilRo0DEUGETEvgNm9DjBibEDfeTnmKJ2nCuQyvT ZY/KTAZEGng0kf+PIlGHzgt5mJK/fXUhFv9/0ziI3WHb/Y/BrlveiRYF1N9dytBeDfzK 7SH+TuhYjAcIvM2rhqIR83EriLF5/bpCWnTtV3+MfmJQTSl7K9yQ+WOW1lGh/m3P0yXM M8pw== X-Gm-Message-State: ACrzQf3AWRdVuXhDlr5ZTGMpIkMqD3ci8hBx2PqMHVcQQDcKd1slNrjY LZhnU3QExfJMd+0/spel/d4tP0zz1Ck= X-Google-Smtp-Source: AMsMyM6gF2VdSNp5g+ec4Y9qytrJQkCgG2K+vcyoSMPfZ1+sevoVtsZGu/zNhL26HzUx3ugeJM/JNA== X-Received: by 2002:adf:f6c9:0:b0:236:547f:698a with SMTP id y9-20020adff6c9000000b00236547f698amr586162wrp.180.1666988105708; Fri, 28 Oct 2022 13:15:05 -0700 (PDT) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id n3-20020a5d6b83000000b00236644228besm4274839wrx.40.2022.10.28.13.15.05 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 28 Oct 2022 13:15:05 -0700 (PDT) Message-Id: <7cdd6c4184da2d3109498589167f10ecf972edc9.1666988096.git.gitgitgadget@gmail.com> In-Reply-To: References: Date: Fri, 28 Oct 2022 20:14:56 +0000 Subject: [PATCH v3 8/8] clone, submodule update: create and check out branches Fcc: Sent MIME-Version: 1.0 To: git@vger.kernel.org Cc: Philippe Blain , Jonathan Tan , Glen Choo , Glen Choo Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Glen Choo From: Glen Choo Teach "git submodule update" to: - create the branch with the same name as the current superproject branch when cloning a submodule - check out that branch (instead of the commit OID) when updating the submodule worktree when submodule branching is enabled (submodule.propagateBranches = true) on the superproject and a branch is checked out. "git clone --recurse-submodules" also learns this trick because it is implemented with "git submodule update --recursive". This approach of checking out the branch will not result in a dirty worktree for freshly cloned submodules because we can ensure that the submodule branch points to the superproject gitlink. In other cases, it does not work as well, but we can handle them incrementally: - "git pull --recurse-submodules" merges the superproject tree, (changing the gitlink without updating the submodule branches), and runs "git submodule update" to update the worktrees, so it is almost guaranteed to result in a dirty worktree. The implementation of "git pull --recurse-submodules" is likely to change drastically as submodule.propagateBranches work progresses (e.g. "git merge" learns to recurse in to submodules), and we may be able to replace the "git submodule update" invocation, or teach it new tricks that make the update behave well. - The user might make changes to the submodule branch without committing them back to superproject. This is primarily affects "git checkout --recurse-submodules", since that is the primary way of switching away from a branch and leaving behind WIP (as opposed to "git submodule update", which is run post-checkout). In a future series, "git checkout --recurse-submodules" will learn to consider submodule branches. We can introduce appropriate guardrails then, e.g. requiring that the superproject working tree is not dirty before switching away. Signed-off-by: Glen Choo --- builtin/submodule--helper.c | 37 ++++++++- t/t5617-clone-submodules.sh | 38 +++++++++ t/t7406-submodule-update.sh | 156 ++++++++++++++++++++++++++++++++++++ 3 files changed, 227 insertions(+), 4 deletions(-) diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index ef76a111c7f..767a0c81cde 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -1917,6 +1917,7 @@ static void submodule_update_clone_release(struct submodule_update_clone *suc) struct update_data { const char *prefix; char *displaypath; + const char *super_branch; enum submodule_update_type update_default; struct string_list references; struct submodule_update_strategy update_strategy; @@ -2091,6 +2092,11 @@ static int prepare_to_clone_next_submodule(const struct cache_entry *ce, strvec_push(&child->args, suc->update_data->single_branch ? "--single-branch" : "--no-single-branch"); + if (ud->super_branch) { + strvec_pushf(&child->args, "--branch=%s", ud->super_branch); + strvec_pushf(&child->args, "--branch-oid=%s", + oid_to_hex(&ce->oid)); + } cleanup: free(displaypath); @@ -2254,9 +2260,14 @@ static int fetch_in_submodule(const char *module_path, int depth, int quiet, static int run_update_command(const struct update_data *ud, int subforce) { struct child_process cp = CHILD_PROCESS_INIT; - const char *update_target = oid_to_hex(&ud->oid);; + const char *update_target; int ret; + if (ud->update_strategy.type == SM_UPDATE_CHECKOUT && ud->super_branch) + update_target = ud->super_branch; + else + update_target = oid_to_hex(&ud->oid); + switch (ud->update_strategy.type) { case SM_UPDATE_CHECKOUT: cp.git_cmd = 1; @@ -2523,6 +2534,7 @@ static int update_submodule(struct update_data *update_data) int submodule_up_to_date; int ret; struct object_id suboid; + const char *submodule_head = NULL; ret = determine_submodule_update_strategy(the_repository, update_data->just_cloned, @@ -2533,7 +2545,8 @@ static int update_submodule(struct update_data *update_data) return ret; if (!update_data->just_cloned && - resolve_gitlink_ref(update_data->sm_path, "HEAD", &suboid, NULL)) + resolve_gitlink_ref(update_data->sm_path, "HEAD", &suboid, + &submodule_head)) return die_message(_("Unable to find current revision in submodule path '%s'"), update_data->displaypath); @@ -2568,8 +2581,17 @@ static int update_submodule(struct update_data *update_data) free(remote_ref); } - submodule_up_to_date = !update_data->just_cloned && - oideq(&update_data->oid, &suboid); + if (update_data->just_cloned) + submodule_up_to_date = 0; + else if (update_data->super_branch) + /* Check that the submodule's HEAD points to super_branch. */ + submodule_up_to_date = + skip_prefix(submodule_head, "refs/heads/", + &submodule_head) && + !strcmp(update_data->super_branch, submodule_head); + else + submodule_up_to_date = oideq(&update_data->oid, &suboid); + if (!submodule_up_to_date || update_data->force) { ret = run_update_procedure(update_data); if (ret) @@ -2603,6 +2625,12 @@ static int update_submodules(struct update_data *update_data) int i, ret = 0; struct submodule_update_clone suc = SUBMODULE_UPDATE_CLONE_INIT; + if (the_repository->settings.submodule_propagate_branches) { + struct branch *current_branch = branch_get(NULL); + if (current_branch) + update_data->super_branch = current_branch->name; + } + suc.update_data = update_data; run_processes_parallel_tr2(suc.update_data->max_jobs, update_clone_get_next_task, update_clone_start_failure, @@ -2718,6 +2746,7 @@ static int module_update(int argc, const char **argv, const char *prefix) argc = parse_options(argc, argv, prefix, module_update_options, git_submodule_helper_usage, 0); + prepare_repo_settings(the_repository); if (opt.require_init) opt.init = 1; diff --git a/t/t5617-clone-submodules.sh b/t/t5617-clone-submodules.sh index c43a5b26fab..43f9b52bd44 100755 --- a/t/t5617-clone-submodules.sh +++ b/t/t5617-clone-submodules.sh @@ -13,10 +13,17 @@ test_expect_success 'setup' ' git config --global protocol.file.allow always && git checkout -b main && test_commit commit1 && + mkdir subsub && + ( + cd subsub && + git init && + test_commit subsubcommit1 + ) && mkdir sub && ( cd sub && git init && + git submodule add "file://$pwd/subsub" subsub && test_commit subcommit1 && git tag sub_when_added_to_super && git branch other @@ -107,4 +114,35 @@ test_expect_success '--no-also-filter-submodules overrides clone.filterSubmodule test_cmp_config -C super_clone3/sub false --default false remote.origin.promisor ' +test_expect_success 'submodule.propagateBranches checks out branches at correct commits' ' + test_when_finished "git checkout main" && + + git checkout -b checked-out && + git -C sub checkout -b not-in-clone && + git -C subsub checkout -b not-in-clone && + git clone --recurse-submodules \ + --branch checked-out \ + -c submodule.propagateBranches=true \ + "file://$pwd/." super_clone4 && + + # Assert that each repo is pointing to "checked-out" + for REPO in "super_clone4" "super_clone4/sub" "super_clone4/sub/subsub" + do + HEAD_BRANCH=$(git -C $REPO symbolic-ref HEAD) && + test $HEAD_BRANCH = "refs/heads/checked-out" || return 1 + done && + + # Assert that the submodule branches are pointing to the right revs + EXPECT_SUB_OID="$(git -C super_clone4 rev-parse :sub)" && + ACTUAL_SUB_OID="$(git -C super_clone4/sub rev-parse refs/heads/checked-out)" && + test $EXPECT_SUB_OID = $ACTUAL_SUB_OID && + EXPECT_SUBSUB_OID="$(git -C super_clone4/sub rev-parse :subsub)" && + ACTUAL_SUBSUB_OID="$(git -C super_clone4/sub/subsub rev-parse refs/heads/checked-out)" && + test $EXPECT_SUBSUB_OID = $ACTUAL_SUBSUB_OID && + + # Assert that the submodules do not have branches from their upstream + test_must_fail git -C super_clone4/sub rev-parse not-in-clone && + test_must_fail git -C super_clone4/sub/subsub rev-parse not-in-clone +' + test_done diff --git a/t/t7406-submodule-update.sh b/t/t7406-submodule-update.sh index f094e3d7f36..b749d35f784 100755 --- a/t/t7406-submodule-update.sh +++ b/t/t7406-submodule-update.sh @@ -1179,4 +1179,160 @@ test_expect_success 'submodule update --recursive skip submodules with strategy= test_cmp expect.err actual.err ' +test_expect_success 'setup superproject with submodule.propagateBranches' ' + git init sub1 && + test_commit -C sub1 "sub1" && + git init branch-super && + git -C branch-super submodule add ../sub1 sub1 && + git -C branch-super commit -m "super" && + + # Clone into a clean repo that we can cp around + git clone --recurse-submodules \ + -c submodule.propagateBranches=true \ + branch-super branch-super-clean && + git -C branch-super-clean config submodule.propagateBranches true && + + # sub2 will not be in the clone. We will fetch the containing + # superproject commit and clone sub2 with "git submodule update". + git init sub2 && + test_commit -C sub2 "sub2" && + git -C branch-super submodule add ../sub2 sub2 && + git -C branch-super commit -m "add sub2" +' + +test_clean_submodule () +{ + local negate super_dir sub_dir expect_oid actual_oid && + if test "$1" = "!" + then + negate=t + shift + fi + super_dir="$1" && + sub_dir="$2" && + expect_oid="$(git -C "$super_dir" rev-parse ":$sub_dir")" && + actual_oid="$(git -C "$super_dir/$sub_dir" rev-parse HEAD)" && + if test -n "$negate" + then + ! test "$expect_oid" = "$actual_oid" + else + test "$expect_oid" = "$actual_oid" + fi +} + +# Test the behavior of a newly cloned submodule +test_expect_success 'branches - newly-cloned submodule, detached HEAD' ' + test_when_finished "rm -fr branch-super-cloned" && + cp -r branch-super-clean branch-super-cloned && + + git -C branch-super-cloned fetch origin main && + git -C branch-super-cloned checkout FETCH_HEAD && + git -C branch-super-cloned/sub1 checkout --detach && + git -C branch-super-cloned submodule update && + + # sub1 and sub2 should be in detached HEAD + git -C branch-super-cloned/sub1 rev-parse --verify HEAD && + test_must_fail git -C branch-super-cloned/sub1 symbolic-ref HEAD && + test_clean_submodule branch-super-cloned sub1 && + git -C branch-super-cloned/sub2 rev-parse --verify HEAD && + test_must_fail git -C branch-super-cloned/sub2 symbolic-ref HEAD && + test_clean_submodule branch-super-cloned sub2 +' + +test_expect_success 'branches - newly-cloned submodule, branch checked out' ' + test_when_finished "rm -fr branch-super-cloned" && + cp -r branch-super-clean branch-super-cloned && + + git -C branch-super-cloned fetch origin main && + git -C branch-super-cloned checkout FETCH_HEAD && + git -C branch-super-cloned branch new-branch && + git -C branch-super-cloned checkout new-branch && + git -C branch-super-cloned/sub1 branch new-branch && + git -C branch-super-cloned submodule update && + + # Ignore sub1, we will test it later. + # sub2 should check out the branch + HEAD_BRANCH2=$(git -C branch-super-cloned/sub2 symbolic-ref HEAD) && + test $HEAD_BRANCH2 = "refs/heads/new-branch" && + test_clean_submodule branch-super-cloned sub2 +' + +# Test the behavior of an already-cloned submodule. +# NEEDSWORK When updating with branches, we always use the branch instead of the +# gitlink's OID. This results in some imperfect behavior: +# +# - If the gitlink's OID disagrees with the branch OID, updating with branches +# may result in a dirty worktree +# - If the branch does not exist, the update fails. +# +# We will reevaluate when "git checkout --recurse-submodules" supports branches +# For now, just test for this imperfect behavior. +test_expect_success 'branches - correct branch checked out, OIDs agree' ' + test_when_finished "rm -fr branch-super-cloned" && + cp -r branch-super-clean branch-super-cloned && + + git -C branch-super-cloned branch --recurse-submodules new-branch && + git -C branch-super-cloned checkout new-branch && + git -C branch-super-cloned/sub1 checkout new-branch && + git -C branch-super-cloned submodule update && + + HEAD_BRANCH1=$(git -C branch-super-cloned/sub1 symbolic-ref HEAD) && + test $HEAD_BRANCH1 = "refs/heads/new-branch" && + test_clean_submodule branch-super-cloned sub1 +' + +test_expect_success 'branches - correct branch checked out, OIDs disagree' ' + test_when_finished "rm -fr branch-super-cloned" && + cp -r branch-super-clean branch-super-cloned && + + git -C branch-super-cloned branch --recurse-submodules new-branch && + git -C branch-super-cloned checkout new-branch && + git -C branch-super-cloned/sub1 checkout new-branch && + test_commit -C branch-super-cloned/sub1 new-commit && + git -C branch-super-cloned submodule update && + + HEAD_BRANCH1=$(git -C branch-super-cloned/sub1 symbolic-ref HEAD) && + test $HEAD_BRANCH1 = "refs/heads/new-branch" && + test_clean_submodule ! branch-super-cloned sub1 +' + +test_expect_success 'branches - other branch checked out, correct branch exists, OIDs agree' ' + test_when_finished "rm -fr branch-super-cloned" && + cp -r branch-super-clean branch-super-cloned && + + git -C branch-super-cloned branch --recurse-submodules new-branch && + git -C branch-super-cloned checkout new-branch && + git -C branch-super-cloned/sub1 checkout main && + git -C branch-super-cloned submodule update && + + HEAD_BRANCH1=$(git -C branch-super-cloned/sub1 symbolic-ref HEAD) && + test $HEAD_BRANCH1 = "refs/heads/new-branch" && + test_clean_submodule branch-super-cloned sub1 +' + +test_expect_success 'branches - other branch checked out, correct branch exists, OIDs disagree' ' + test_when_finished "rm -fr branch-super-cloned" && + cp -r branch-super-clean branch-super-cloned && + + git -C branch-super-cloned branch --recurse-submodules new-branch && + git -C branch-super-cloned checkout new-branch && + git -C branch-super-cloned/sub1 checkout new-branch && + test_commit -C branch-super-cloned/sub1 new-commit && + git -C branch-super-cloned/sub1 checkout main && + git -C branch-super-cloned submodule update && + + HEAD_BRANCH1=$(git -C branch-super-cloned/sub1 symbolic-ref HEAD) && + test $HEAD_BRANCH1 = "refs/heads/new-branch" && + test_clean_submodule ! branch-super-cloned sub1 +' + +test_expect_success 'branches - other branch checked out, correct branch does not exist' ' + test_when_finished "rm -fr branch-super-cloned" && + cp -r branch-super-clean branch-super-cloned && + + git -C branch-super-cloned branch new-branch && + git -C branch-super-cloned checkout new-branch && + test_must_fail git -C branch-super-cloned submodule update +' + test_done