From patchwork Thu Oct 20 20:20:32 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Glen Choo X-Patchwork-Id: 13014002 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 698CBC433FE for ; Thu, 20 Oct 2022 20:20:51 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229895AbiJTUUu (ORCPT ); Thu, 20 Oct 2022 16:20:50 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43360 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229514AbiJTUUr (ORCPT ); Thu, 20 Oct 2022 16:20:47 -0400 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 DB2B41F0438 for ; Thu, 20 Oct 2022 13:20:44 -0700 (PDT) Received: by mail-wr1-x42a.google.com with SMTP id i9so1157481wrv.5 for ; Thu, 20 Oct 2022 13:20:44 -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=gdf5JsPWQAe2q40D5LosQfkOjNMruKIb7axop/1PutrLaB4xkka+Tw7P9Sl3fuqzu6 jII2VLNut8FGFrUAghEv/WaUblMpaONR7L8G67OijfhN3n7CG/kigBimO93QCGPvaj+G VrcUKdNpuhDkJWIqEnQIJXnaeIoTDEWKOx+64iISKlh101soSOn0dv0sQy2Qo/+aNLY9 yjYg0r0MpPx8kD8APSKdGGyeJDzGUq448tJXPU3N5mFkvfFHRhuLSKSXTd7AjTQp1AiE 5sDj05UAygCV1Iv7056obKM7tBvjZmaOk3R5EPAIoNPRw3tGLu1lRIOekl7rIP8do1Ml xzZA== 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=g0PgQjT6zs2s7c6TALG5vn22CmmU9Hjk8AvyoAgYtQXx9YUHZa7IB22UgvxVNwThPg NTIib/EnLvMYg65v+BWeaKhyxTy0e+Ny9jJ122/ecMatEulVG5An/iQHWklsL1ztEeli Of6/Tmc24cOSYBMzcW0aziguyPlWu4jmKr55rbsvkbkSglndl175ehVLzQaeT4INwIeG 4UvtwPyZfc7HrSvZo9ZnmT7cVVj5qYwCospDJJtnAySBlUhj4YtHhuS1RrN5oXbeDmK5 QjA+r4oM53aJ0A/YcKYlPoSv5Yv91BS4EQanDux1sC4jdTbEa139a9OMW0dy/Dv98yjt 8d/A== X-Gm-Message-State: ACrzQf21Sr83SnTcfgY+2yeAgER+3sgBgOuG8IbsUZzS149Nuf/Bwv4I MxnRe2Wt47oopyCORZB6+kaBduM6PB4= X-Google-Smtp-Source: AMsMyM7G3u1FjUmFF8N+nFqNahzuPszh815w0olcbEm4pr+UupHlfM0CoDDfZn8cROLzh4ZrOiD+mg== X-Received: by 2002:a05:6000:1f04:b0:22e:5e0b:e1fb with SMTP id bv4-20020a0560001f0400b0022e5e0be1fbmr9413467wrb.222.1666297243094; Thu, 20 Oct 2022 13:20:43 -0700 (PDT) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id o5-20020a5d62c5000000b00228cbac7a25sm17549319wrv.64.2022.10.20.13.20.41 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 20 Oct 2022 13:20:41 -0700 (PDT) Message-Id: <432bc7cb3a42cf39d0033701c2cc677c9109b3dd.1666297239.git.gitgitgadget@gmail.com> In-Reply-To: References: Date: Thu, 20 Oct 2022 20:20:32 +0000 Subject: [PATCH v2 1/7] 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 Thu Oct 20 20:20:33 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Glen Choo X-Patchwork-Id: 13014004 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 66CF1C43217 for ; Thu, 20 Oct 2022 20:20:54 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229839AbiJTUUw (ORCPT ); Thu, 20 Oct 2022 16:20:52 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43378 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229736AbiJTUUr (ORCPT ); Thu, 20 Oct 2022 16:20:47 -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 36A20349B9 for ; Thu, 20 Oct 2022 13:20:46 -0700 (PDT) Received: by mail-wr1-x42d.google.com with SMTP id i9so1157617wrv.5 for ; Thu, 20 Oct 2022 13:20:46 -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=0ZXD53u12TpvC4tUu3XTYLK+x7wjUPFP/KcHE9B4uaI=; b=dDsNxXSDwRT00FAVGmyzsEvjVU/LUMX3vaNCy2WDe1uyliG5M7+951Cffu0dmKyiyp 7IYu2PbaNOHB39s88pR+TVh0rMfLD1HCzs0DB+smUzAqAjDPAHU25YsraAuAT8+LMYru k91QOh3PDoydGQiiPnp5w0www5Ma7K23//oDSJugsFEZKNDxvKNbn1JIj1w6N1+IfgKi W6FwTD+BWIDSifPnySsYvVKmRJtpTd5RM6u25yiOWaspKZdxhVuAMzMDVLdNmpG6FtBb gc3mbUirTYujnG1JhNE3TdhSAUIVg/+Ls/vihfHrhHrTvuGrt2MiOdBKvvkvC2EIwUq+ LpRw== 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=0ZXD53u12TpvC4tUu3XTYLK+x7wjUPFP/KcHE9B4uaI=; b=iUAtXE87kte7pxwJ5rcXXDWZck8hNFyECB4dhZEzpT5jFKEMG5xMIMIlJYprJSITkQ OmJ7MTcMz72TVyLiVFQZHzeQlgVMfVfhJK7N8TUkAipuuwrWZoG5VbbHltPDIXr8NT7q APZVx78ATJN1pX3WzSWfvkJesP6X4yA6IfkjhhirfcxSPi0sTj+2ilWYZGAUIrrxGxsn qf7mi7kskv8Bwyj+hgxQXBJMFo/9CUMFoAJhIx7xg0DNH3VPapj3JOBOroz2DC+35FhY SCw35xbAaSC07zWzp5B2NrkMTpq/qXiyX6grJZo6hvcTL/nwepiUi7aVlG4YZbLiO2ir H+fw== X-Gm-Message-State: ACrzQf1o2Z0BCyKXHdypa6J0aZuqMdWNKO43NPwofBVN3LCPoMi++Ngq KJsWDvCwVgoony9sEXP1/c9SRUVsXW4= X-Google-Smtp-Source: AMsMyM5s2wbla96EJ4+7fACGpbPoJqje3BCrJ24ktYe14oLUdVIWFSX3WOf1AqNScupQrmHV8YgGyw== X-Received: by 2002:adf:e187:0:b0:234:6c1b:cf7e with SMTP id az7-20020adfe187000000b002346c1bcf7emr5476770wrb.395.1666297244356; Thu, 20 Oct 2022 13:20:44 -0700 (PDT) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id g15-20020adfe40f000000b00226dfac0149sm17354709wrm.114.2022.10.20.13.20.43 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 20 Oct 2022 13:20:43 -0700 (PDT) Message-Id: <20499c62065d640b57bdcfd959e10b214f7e7297.1666297239.git.gitgitgadget@gmail.com> In-Reply-To: References: Date: Thu, 20 Oct 2022 20:20:33 +0000 Subject: [PATCH v2 2/7] 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 | 10 ++++++++++ repository.h | 1 + submodule.c | 2 ++ 5 files changed, 17 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..180df14e45f 100644 --- a/repo-settings.c +++ b/repo-settings.c @@ -71,6 +71,16 @@ 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 came from the + * superproject and ignore the 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 Thu Oct 20 20:20:34 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Glen Choo X-Patchwork-Id: 13014005 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 8A7A0C433FE for ; Thu, 20 Oct 2022 20:20:56 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229949AbiJTUUy (ORCPT ); Thu, 20 Oct 2022 16:20:54 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43406 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229866AbiJTUUs (ORCPT ); Thu, 20 Oct 2022 16:20:48 -0400 Received: from mail-wr1-x42f.google.com (mail-wr1-x42f.google.com [IPv6:2a00:1450:4864:20::42f]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1DE0D1F0439 for ; Thu, 20 Oct 2022 13:20:47 -0700 (PDT) Received: by mail-wr1-x42f.google.com with SMTP id bp11so957989wrb.9 for ; Thu, 20 Oct 2022 13:20:47 -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=xbNIbJt4seS/lviG3MQ8OZqWiqRLSxNNEzvoHb/B5ro=; b=efXAI+3bOJL/iWANjU5uhATmJKn707jzBOEzLGiZ4zKfK8sm2puv1/i/ez5kgg4SQc PFNHWUNYPvGH3ahTSQgdZuEWbtZbsoVZIVnumIFLDAlOKWRnFiW+JWy0/OShMW7JbmSR xumFd+KE5X7vwfTgh5/Qbtq3pKog4ReQ3BjJAWp1g8j+KO06CkMyT6lo/DuC6rsjXzK0 oZS4oDMROvKXXt58VkqiH1mHu7A+PG2s2KU0UzZ0Uh/7man3y9wHc2vGob0tLML1fFvW GeZg97iXVyy5kc7F50M68VuZdVwDZKgLZSn4l2VPEfh+V4203KnCYBZMMRyHX0CQ4nOB SkzQ== 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=xbNIbJt4seS/lviG3MQ8OZqWiqRLSxNNEzvoHb/B5ro=; b=wQ0DpWpaFzuvWSS2EUz0PQOoT9LTqG7MMRuLcVRHmdxyrTWIJMrG1mLi/E7AAieB5O rIOTHlLTvyJWlGuIu5phGzJrxkqfVuZo6B1xzeHJWAx+zwFWO4rgECP5/Q6YeJhNcolx 1Nb7PyfluxXGc62MNlBYM5GEFqFMgP9gL91LH4gS3yQq8nkR1QhWnIlR/yYvmDy/bu/W tB76M3368Q2lB/+j8CxQXmtVXlhZoE+YvF0Z7hALAfVIxcJ2TtfMnTo4BQTQs8sIYJ8H ChDyftMx34LdjEOg0rxBllRoXN4wBB/715pTyCv9rTb30Bw53KeBdDLCsMEouKh6vIHj aRZw== X-Gm-Message-State: ACrzQf3OMwaGAQHpXIiU1133C7gqTR3i7XJqOOL3H8X7O4H7EsZW58XQ cfvY/NaHQQBcBrn+RZFe6Q9nGIlXKb8= X-Google-Smtp-Source: AMsMyM5KQpMpEpXn6LiSVEjnMgBTSDxR1kwfIPvJ8ggUUnyuqQJVOMj+mP/y+JN75QRT1zPS/U+5Wg== X-Received: by 2002:a5d:6dab:0:b0:231:3a49:3079 with SMTP id u11-20020a5d6dab000000b002313a493079mr9680440wrs.148.1666297245336; Thu, 20 Oct 2022 13:20:45 -0700 (PDT) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id c5-20020a05600c0a4500b003bdd2add8fcsm785075wmq.24.2022.10.20.13.20.44 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 20 Oct 2022 13:20:44 -0700 (PDT) Message-Id: In-Reply-To: References: Date: Thu, 20 Oct 2022 20:20:34 +0000 Subject: [PATCH v2 3/7] 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. These flags will be used by `git submodule update` in a later commit. "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, 32 insertions(+), 1 deletion(-) diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index 0b4acb442b2..1ce3458a29c 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; @@ -1798,9 +1825,13 @@ static int module_clone(int argc, const char **argv, const char *prefix) clone_data.require_init = !!require_init; clone_data.filter_options = &filter_options; - if (argc || !clone_data.url || !clone_data.path || !*(clone_data.path)) + if (argc || !clone_data.url || !clone_data.path || !*(clone_data.path) + || (!!clone_data.branch != !!clone_data.branch_oid)) usage_with_options(git_submodule_helper_usage, module_clone_options); + 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); From patchwork Thu Oct 20 20:20:35 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Glen Choo X-Patchwork-Id: 13014006 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 93BAAC4332F for ; Thu, 20 Oct 2022 20:20:59 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229981AbiJTUU6 (ORCPT ); Thu, 20 Oct 2022 16:20:58 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43434 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229892AbiJTUUt (ORCPT ); Thu, 20 Oct 2022 16:20:49 -0400 Received: from mail-wr1-x431.google.com (mail-wr1-x431.google.com [IPv6:2a00:1450:4864:20::431]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 295D4349B9 for ; Thu, 20 Oct 2022 13:20:48 -0700 (PDT) Received: by mail-wr1-x431.google.com with SMTP id a3so1295742wrt.0 for ; Thu, 20 Oct 2022 13:20:48 -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=UJNg9E+dDaHsXh6JnDP/SguhYED499AQr2b4y/CtZO/Y+zIsgsMbd8hp/s9vOjG8gU KdBN5kT6DC55yK9fdsy0ySI9apRfFeUTSz9Xa0R5ZY/PYc8pUxuakpJlim7lEjOyELaQ mPdIN3F2HTeNKeIF791ZGqB5OjBiiibfsY/DxuFXxXdeNGy/axx8jVNebiwKpfWMFKOL 73elgf1njNFedLpyRGG9VoVaKFB0Wdcg55xKX5Lf0BO20rE5FdPVA3F0rLZ2QjZHvLZV EvpvZSKfvXWY2ILJ54Y0RgpBLXXMU0qqhsnnhbULbeuahlwwGGEqgF0vNoK+sUD0EYVE 9ycA== 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=PFqOTq2S2V/O0i3S7lTq1ZBmgN8i51nVfgCiB/yc/uMJzH5lKXs4UHVrx3zWK08tQS l0M4iFbpL2+ZlpXMRpahq1v+D8iuPETSMdEg/mtWO7xFYy4w8rg4Rl5wGjk0e3F4uHYI Tygd5LjxpnTXL4gXOnsEZNHh+UvLhpdFoj2f/FMWo5cMZ9sX+y6/W55u02ayjHvGJDq0 +PIrl/AafJFTvz8rI5ydnfMxrte9dPO/EeE8+zkTT/u4s0Mep+XIHLts7HF27uWzjvoR 7B0Up5edbbVpeVG7YK2kjLPfsgP7rTXzhGYzsEnWjCMVWXElZA91qecZWZFQmcefgZQw 3tCg== X-Gm-Message-State: ACrzQf3LESuHLv5VFeA38Vg8LBA+accELhcootLp21RDKNT96eA/qs6L AOuqZQ7Vk1wDxVwUOVRIt2S4YwAsZi0= X-Google-Smtp-Source: AMsMyM4xccwcFM1EM3LL91TNqr/89DrKtzblTyACJoOzzP/Ohs0IjBWKad84u2MzjXAAc+5DCGTscg== X-Received: by 2002:a5d:5265:0:b0:235:e1fa:98a2 with SMTP id l5-20020a5d5265000000b00235e1fa98a2mr3460641wrc.73.1666297246468; Thu, 20 Oct 2022 13:20:46 -0700 (PDT) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id o16-20020a056000011000b0022e38c93195sm16876181wrx.34.2022.10.20.13.20.45 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 20 Oct 2022 13:20:45 -0700 (PDT) Message-Id: In-Reply-To: References: Date: Thu, 20 Oct 2022 20:20:35 +0000 Subject: [PATCH v2 4/7] 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 Thu Oct 20 20:20:36 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Glen Choo X-Patchwork-Id: 13014007 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 938ECC43217 for ; Thu, 20 Oct 2022 20:21:15 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230052AbiJTUVO (ORCPT ); Thu, 20 Oct 2022 16:21:14 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43520 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229835AbiJTUUv (ORCPT ); Thu, 20 Oct 2022 16:20:51 -0400 Received: from mail-wm1-x32e.google.com (mail-wm1-x32e.google.com [IPv6:2a00:1450:4864:20::32e]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 48B681F041F for ; Thu, 20 Oct 2022 13:20:49 -0700 (PDT) Received: by mail-wm1-x32e.google.com with SMTP id e18so777506wmq.3 for ; Thu, 20 Oct 2022 13:20:49 -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=509B6hLh+GFBVnreBIuyCPrTI9ul8YARq/8O+F03Gjs=; b=I1trWHw5ty/i6IB4E36qiJtiSCYYTBkm7X2qK1+aQrUIchZNyLI59YpaxlM4EwA+9W eDW+IHi1bvbhJ2o5c4XQCa/bPaiMJ1lQA47lSCQRnWAzTD7Zhe8jkIT5daOwymtnJODz ILi05aBom34mIsuoE/N1moAOQkQot586mooLnQ12S471wtmFoGIvd619iWKKiqLe3S80 8iqI7l0lX1jndv5wTA1IUrxKaOKegNWDLzjsS+bSyxkxuYyyqHwR2lRyrMbiQnUpp1pd +lMr+U5zTRkn2RgKWK6SWPlxdqv8XHdAjQTvcvRkr5pL+S9ev1o+D1CfAEF5PG8bUkR8 WKXg== 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=509B6hLh+GFBVnreBIuyCPrTI9ul8YARq/8O+F03Gjs=; b=ALxwv7ptq/vpymV5k+UyVO+YatVWITmh3yVvi5DPExuAh1ChtSqAwMS0RmDUl3vni1 gYAp2gptmlVm8wFeV2khLlQsR2nNYe3upOEntMbw6BhSnLx0g1TXd89GL/YhHXpL7/S3 62cT8eFmLE6zuCjSlbPdHeMIX9qLU5KxMIl7e5wqfEmctard390DxFceOjJwZI8j+cQK 6oIYLEj00Y4T20C+MJRWtDxbEKyu/MnhijY+hJvtF5GUblh7qWRAWbvebTl14lxBlV2e Edg2yigd3++QwgGl8kDayXGuuxPGXQ4NCVp78XICmZu5UbfZvU9v72kpw/UsWWnaLs5e 6L5g== X-Gm-Message-State: ACrzQf3HIMMK+1tN/fW5tmM1KNbGpJY3Cf0aAY1/DeHIh8ryd7IbWAU+ irRCVQjd8iOXgs1MRdTQ5RzOnNoSv4I= X-Google-Smtp-Source: AMsMyM7xwRUQEGc4D+4LlxpnxuhlJS3nx26ejnM0PfWaVsN/A6KI4BTciBOMa0iugkx3lDje2BKJAw== X-Received: by 2002:a05:600c:5122:b0:3c6:fcce:e4e2 with SMTP id o34-20020a05600c512200b003c6fccee4e2mr11474182wms.65.1666297247449; Thu, 20 Oct 2022 13:20:47 -0700 (PDT) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id l3-20020adfe583000000b002205a5de337sm17068367wrm.102.2022.10.20.13.20.46 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 20 Oct 2022 13:20:46 -0700 (PDT) Message-Id: <6f769cb80ad0bd7df98b8c7d207922f8631133f2.1666297239.git.gitgitgadget@gmail.com> In-Reply-To: References: Date: Thu, 20 Oct 2022 20:20:36 +0000 Subject: [PATCH v2 5/7] 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 1ce3458a29c..138b133790f 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -2531,7 +2531,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); @@ -2558,7 +2559,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); @@ -3303,7 +3305,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 Thu Oct 20 20:20:37 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Glen Choo X-Patchwork-Id: 13014008 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 76270C433FE for ; Thu, 20 Oct 2022 20:21:17 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229998AbiJTUVP (ORCPT ); Thu, 20 Oct 2022 16:21:15 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43618 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229923AbiJTUUx (ORCPT ); Thu, 20 Oct 2022 16:20:53 -0400 Received: from mail-wr1-x42f.google.com (mail-wr1-x42f.google.com [IPv6:2a00:1450:4864:20::42f]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3973F1F0418 for ; Thu, 20 Oct 2022 13:20:50 -0700 (PDT) Received: by mail-wr1-x42f.google.com with SMTP id bv10so1176069wrb.4 for ; Thu, 20 Oct 2022 13:20:49 -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=9qzbLJuQnEYqXpEYDjBQWuosE+DZ0ly05x2Pb3GFYM0=; b=OqsV+54yS0emx2scw4Su+gYKXziOlVR4BNdu/fNXA3jARu39kmAcgr4WcFouCIZ3Se h2lOR/kJu38wldia5AhBta7G+iGmZE3Sq6s1lufPmU0ybekZN/U4+SA/qhNnWb3Yj1ES UpqWQXuQYAwSQ2Cv1ACRN44O9CkpCO5nC0vuLkfBein5i0C4/S+SpGTzLXdtCf+e3Lv6 dEIDTtAmXYWoGlxjp3IrM07Pwye9dLBhp2lnIbk6Bswu68SkXIYwKBd3ur+5XczAl0AF f/OuHx+b8JqMzoX6Ou72iqMR4MuPeWLBhfjWRmYvFguBMqEYGSxIAeH32L2OKH+PBniE 6xGQ== 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=9qzbLJuQnEYqXpEYDjBQWuosE+DZ0ly05x2Pb3GFYM0=; b=kdUb0yds+H1IBTfGb39rIxtDD9O8l6H1bEXvcnMKM5mFOdonJuCoqf5jnKvbgimIow FpstCxXphnmNfPJqEJlEyyVvcmKTjai4LvB2TaIuXxKySiI2ckW6L5L+sk69gSJEquF7 gCOXbzPpw/TY3fUPRWZSSnd/nm6w+JujcKe8IAefqh2Tv4E5CI1CxUT7VjO+R5ikFPBe M04OCzPpSYDGnp/6S9oXrmTS5Y4ZKnATiS7LNeCNOuyrQXM4MwSDPWbNA2E1ReqqSJO4 pwqEb9j0pTHr4KYVFxwqy8YCT7H9dr3Vl5xnF/Ra/OkZRwpCCOmAdKCYTdI85UGFmSVy n7oA== X-Gm-Message-State: ACrzQf2eMgMGJw5q2hmF9LWnkZXQKJy1gaTrIRmGwgUHh7eCYBzAAkd2 OIILEGshwXBHWOGngAiw3wKsVcHoa04= X-Google-Smtp-Source: AMsMyM7Ieej1S0y08/HGS/vyx1cQPbSl/gfAaNJnpc2xV+sS8ZOYG17Xkd5l/XkL+hoDII150L+tTA== X-Received: by 2002:a5d:59a4:0:b0:230:eaa4:88d7 with SMTP id p4-20020a5d59a4000000b00230eaa488d7mr10200914wrr.35.1666297248420; Thu, 20 Oct 2022 13:20:48 -0700 (PDT) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id z9-20020a5d44c9000000b0022917d58603sm17419259wrr.32.2022.10.20.13.20.47 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 20 Oct 2022 13:20:47 -0700 (PDT) Message-Id: In-Reply-To: References: Date: Thu, 20 Oct 2022 20:20:37 +0000 Subject: [PATCH v2 6/7] 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 the next 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 138b133790f..990adeb2e19 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -2253,7 +2253,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) { @@ -2283,7 +2283,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); @@ -2291,20 +2291,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", @@ -2320,19 +2320,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", @@ -2519,6 +2519,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, @@ -2567,7 +2568,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 Thu Oct 20 20:20:38 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Glen Choo X-Patchwork-Id: 13014009 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 41AB2C4167B for ; Thu, 20 Oct 2022 20:21:19 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230108AbiJTUVR (ORCPT ); Thu, 20 Oct 2022 16:21:17 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44510 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229802AbiJTUVM (ORCPT ); Thu, 20 Oct 2022 16:21:12 -0400 Received: from mail-wm1-x330.google.com (mail-wm1-x330.google.com [IPv6:2a00:1450:4864:20::330]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 505F31F1817 for ; Thu, 20 Oct 2022 13:20:51 -0700 (PDT) Received: by mail-wm1-x330.google.com with SMTP id e18so777563wmq.3 for ; Thu, 20 Oct 2022 13:20:51 -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=tA1DOd92lGFpSUEZY0uHYmx9909W8B8xZGNXKtVPPqA=; b=d8SsWatC34eM5XztAXvUkJf9ZbYnyQiXAxTIlbYtiXf/XooMBBf8Vrks0XkAX8Y1iq HjJynyICf1UIzZyt5FuGCJHCvvcTEAnMYYgvFmXixlDZO1lst+hGmsM6OhAzt25OMSPk ulsaTrXbG6H0GLydo4TbvDG1Is2ZWRUBUXNlKXtLxOHIF3r9sMlkJN7LP6KZ91uPwLD6 aopg4WLCYwOKasYFONodbxxT9tF51y1sK/RMKcDtcPrAnQGNEfKLXqNDn5zvKA4ZvITP xQVmUC+VEXgVjoUH+aT9QwV+GFAe90xzHEcw5zL7WnSIMNZ0UNcvhQjO4GYtbdZRRCFl kctw== 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=tA1DOd92lGFpSUEZY0uHYmx9909W8B8xZGNXKtVPPqA=; b=ET9AkUMz0/ay7IddgYnBd7Iuy2plq7vIn2Hh0iHT3NDmANoKgfmJ81WGUUIZQE85Sd gPxj0Nh/YXIg/imZZMxJdeLyi4P2zfOwnfTJT3NZJlBXpu8KLbxXoQAr92u96tI2nYLC SGDUFpFqobvJJd0yaNl0b/GB/y/ZbXrcabApXlTki1Bjjx0/+l4f/xlsFJ4vVzv2uRnH kuWTIvz4O21Dsw7oXKQueUlLMN4p5265IGCGfloibFEF2nvzD9hfEE0QveF+SUHiyc3X LVF7WvXYNsMusyA1CagfgJpm39X7suvOnBjg1wfpSbq6w5PL1FU6Nx+ieJogvA9S9MdV 9gLg== X-Gm-Message-State: ACrzQf3jQCsgQF3d+y6RBy9gt+ztwVZX7kYkVGglvHP//1s7kVXNQ+Vf RNTUnavetrx0q4QHh+SSsTS6hBMqyDQ= X-Google-Smtp-Source: AMsMyM5MK4aDYdwyC/mh1ihDRY18gUEx9chm1YoYaDEfukynW4DKTulH3i1PD0mMhx4qqeHu6zloAw== X-Received: by 2002:a05:600c:2219:b0:3c4:cf31:8a13 with SMTP id z25-20020a05600c221900b003c4cf318a13mr31289863wml.122.1666297249352; Thu, 20 Oct 2022 13:20:49 -0700 (PDT) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id u10-20020a5d468a000000b0021badf3cb26sm20752459wrq.63.2022.10.20.13.20.48 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 20 Oct 2022 13:20:48 -0700 (PDT) Message-Id: <3f98b0d17397dbce85aa87a9591981c790f8f7a2.1666297239.git.gitgitgadget@gmail.com> In-Reply-To: References: Date: Thu, 20 Oct 2022 20:20:38 +0000 Subject: [PATCH v2 7/7] 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 (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 | 32 +++++++++++++++++-- t/t5617-clone-submodules.sh | 34 ++++++++++++++++++++ t/t7406-submodule-update.sh | 64 +++++++++++++++++++++++++++++++++++++ 3 files changed, 127 insertions(+), 3 deletions(-) diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index 990adeb2e19..4576ba22544 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -1915,6 +1915,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 object_id suboid; struct string_list references; @@ -2090,6 +2091,10 @@ 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); @@ -2253,9 +2258,15 @@ 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; @@ -2521,6 +2532,7 @@ static int update_submodule(struct update_data *update_data) { int submodule_up_to_date; int ret; + const char *submodule_head = "HEAD"; ret = determine_submodule_update_strategy(the_repository, update_data->just_cloned, @@ -2533,7 +2545,7 @@ 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, NULL)) + &update_data->suboid, &submodule_head)) return die_message(_("Unable to find current revision in submodule path '%s'"), update_data->displaypath); @@ -2568,7 +2580,14 @@ static int update_submodule(struct update_data *update_data) free(remote_ref); } - submodule_up_to_date = oideq(&update_data->oid, &update_data->suboid); + if (!update_data->super_branch) + submodule_up_to_date = oideq(&update_data->oid, &update_data->suboid); + else if (skip_prefix(submodule_head, "refs/heads/", &submodule_head)) + submodule_up_to_date = !strcmp(update_data->super_branch, submodule_head); + /* submodule_branch is "HEAD"; the submodule is in detached HEAD */ + else + submodule_up_to_date = 0; + if (!submodule_up_to_date || update_data->force) { ret = run_update_procedure(update_data); if (ret) @@ -2603,6 +2622,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 +2743,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..51593376ce4 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,31 @@ 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' ' + git -C sub checkout -b not-main && + git -C subsub checkout -b not-main && + git clone --recurse-submodules \ + -c submodule.propagateBranches=true \ + "file://$pwd/." super_clone4 && + + # Assert that each repo is pointing to "main" + 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/main" || 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/main)" && + 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/main)" && + 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-main && + test_must_fail git -C super_clone4/sub/subsub rev-parse not-main +' + test_done diff --git a/t/t7406-submodule-update.sh b/t/t7406-submodule-update.sh index f094e3d7f36..54aa8c5cb54 100755 --- a/t/t7406-submodule-update.sh +++ b/t/t7406-submodule-update.sh @@ -1179,4 +1179,68 @@ 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 && + + # Create an upstream submodule not in the clone + 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_expect_success 'submodule.propagateBranches - detached HEAD' ' + test_when_finished "rm -fr branch-super-cloned" && + cp -r branch-super-clean branch-super-cloned && + + git -C branch-super-cloned checkout --detach && + git -C branch-super-cloned pull origin main && + git -C branch-super-cloned submodule update && + + # sub2 should be in detached HEAD + git -C branch-super-cloned/sub2 rev-parse --verify HEAD && + test_must_fail git -C branch-super-cloned/sub2 symbolic-ref HEAD +' + +test_expect_success 'submodule.propagateBranches - branch checked out' ' + 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 --recurse-submodules new-branch && + git -C branch-super-cloned pull origin 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" && + HEAD_BRANCH2=$(git -C branch-super-cloned/sub2 symbolic-ref HEAD) && + test $HEAD_BRANCH2 = "refs/heads/new-branch" +' + +test_expect_success 'submodule.propagateBranches - other branch checked out' ' + 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 --recurse-submodules new-branch && + git -C branch-super-cloned/sub1 checkout -b other-branch && + git -C branch-super-cloned pull origin 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" && + HEAD_BRANCH2=$(git -C branch-super-cloned/sub2 symbolic-ref HEAD) && + test $HEAD_BRANCH2 = "refs/heads/new-branch" +' + test_done