Merge branch 'dl/submodule-set-branch'
authorJunio C Hamano <gitster@pobox.com>
Thu, 25 Apr 2019 07:41:18 +0000 (16:41 +0900)
committerJunio C Hamano <gitster@pobox.com>
Thu, 25 Apr 2019 07:41:18 +0000 (16:41 +0900)
"git submodule" learns "set-branch" subcommand that allows the
submodule.*.branch settings to be modified.

* dl/submodule-set-branch:
submodule: teach set-branch subcommand
submodule--helper: teach config subcommand --unset
git-submodule.txt: "--branch <branch>" option defaults to 'master'

Documentation/git-submodule.txt
builtin/submodule--helper.c
contrib/completion/git-completion.bash
git-submodule.sh
t/t7411-submodule-config.sh
t/t7419-submodule-set-branch.sh [new file with mode: 0755]
index ac8c6879dda34d1efde94903703e19f09a8af891..0ed5c24dc1ce553d0b0ac90d49fcf161a3320474 100644 (file)
@@ -15,6 +15,7 @@ SYNOPSIS
 'git submodule' [--quiet] init [--] [<path>...]
 'git submodule' [--quiet] deinit [-f|--force] (--all|[--] <path>...)
 'git submodule' [--quiet] update [<options>] [--] [<path>...]
+'git submodule' [--quiet] set-branch [<options>] [--] <path>
 'git submodule' [--quiet] summary [<options>] [--] [<path>...]
 'git submodule' [--quiet] foreach [--recursive] <command>
 'git submodule' [--quiet] sync [--recursive] [--] [<path>...]
@@ -172,6 +173,12 @@ submodule with the `--init` option.
 If `--recursive` is specified, this command will recurse into the
 registered submodules, and update any nested submodules within.
 --
+set-branch ((-d|--default)|(-b|--branch <branch>)) [--] <path>::
+       Sets the default remote tracking branch for the submodule. The
+       `--branch` option allows the remote branch to be specified. The
+       `--default` option removes the submodule.<name>.branch configuration
+       key, which causes the tracking branch to default to 'master'.
+
 summary [--cached|--files] [(-n|--summary-limit) <n>] [commit] [--] [<path>...]::
        Show commit summary between the given commit (defaults to HEAD) and
        working tree/index. For a submodule in question, a series of commits
@@ -259,13 +266,14 @@ OPTIONS
        This option is only valid for the deinit command. Unregister all
        submodules in the working tree.
 
--b::
---branch::
+-b <branch>::
+--branch <branch>::
        Branch of repository to add as submodule.
        The name of the branch is recorded as `submodule.<name>.branch` in
        `.gitmodules` for `update --remote`.  A special value of `.` is used to
        indicate that the name of the branch in the submodule should be the
-       same name as the current branch in the current repository.
+       same name as the current branch in the current repository.  If the
+       option is not specified, it defaults to 'master'.
 
 -f::
 --force::
index 8342b78add833808ebe71d7862639290c4b7a677..168be97ffba6c7691531811893130160d060c984 100644 (file)
@@ -2147,17 +2147,22 @@ static int check_name(int argc, const char **argv, const char *prefix)
 static int module_config(int argc, const char **argv, const char *prefix)
 {
        enum {
-               CHECK_WRITEABLE = 1
+               CHECK_WRITEABLE = 1,
+               DO_UNSET = 2
        } command = 0;
 
        struct option module_config_options[] = {
                OPT_CMDMODE(0, "check-writeable", &command,
                            N_("check if it is safe to write to the .gitmodules file"),
                            CHECK_WRITEABLE),
+               OPT_CMDMODE(0, "unset", &command,
+                           N_("unset the config in the .gitmodules file"),
+                           DO_UNSET),
                OPT_END()
        };
        const char *const git_submodule_helper_usage[] = {
-               N_("git submodule--helper config name [value]"),
+               N_("git submodule--helper config <name> [<value>]"),
+               N_("git submodule--helper config --unset <name>"),
                N_("git submodule--helper config --check-writeable"),
                NULL
        };
@@ -2169,15 +2174,17 @@ static int module_config(int argc, const char **argv, const char *prefix)
                return is_writing_gitmodules_ok() ? 0 : -1;
 
        /* Equivalent to ACTION_GET in builtin/config.c */
-       if (argc == 2)
+       if (argc == 2 && command != DO_UNSET)
                return print_config_from_gitmodules(the_repository, argv[1]);
 
        /* Equivalent to ACTION_SET in builtin/config.c */
-       if (argc == 3) {
+       if (argc == 3 || (argc == 2 && command == DO_UNSET)) {
+               const char *value = (argc == 3) ? argv[2] : NULL;
+
                if (!is_writing_gitmodules_ok())
                        die(_("please make sure that the .gitmodules file is in the working tree"));
 
-               return config_set_in_gitmodules_file_gently(argv[1], argv[2]);
+               return config_set_in_gitmodules_file_gently(argv[1], value);
        }
 
        usage_with_options(git_submodule_helper_usage, module_config_options);
index 42a3c8e52417d42a255c68a4f6f24a1518bb3404..3eefbabdb12266cd94729bdeacc088785d917967 100644 (file)
@@ -2611,7 +2611,7 @@ _git_submodule ()
 {
        __git_has_doubledash && return
 
-       local subcommands="add status init deinit update summary foreach sync absorbgitdirs"
+       local subcommands="add status init deinit update set-branch summary foreach sync absorbgitdirs"
        local subcommand="$(__git_find_on_cmdline "$subcommands")"
        if [ -z "$subcommand" ]; then
                case "$cur" in
@@ -2642,6 +2642,9 @@ _git_submodule ()
                        --force --rebase --merge --reference --depth --recursive --jobs
                "
                ;;
+       set-branch,--*)
+               __gitcomp "--default --branch"
+               ;;
        summary,--*)
                __gitcomp "--cached --files --summary-limit"
                ;;
index 2c0fb6d723b74bb5bccba1ea49f97cdf23def361..99fba417b1e742e70f6ff8ccb31b58ee181bc4f7 100755 (executable)
@@ -11,6 +11,7 @@ USAGE="[--quiet] [--cached]
    or: $dashless [--quiet] init [--] [<path>...]
    or: $dashless [--quiet] deinit [-f|--force] (--all| [--] <path>...)
    or: $dashless [--quiet] update [--init] [--remote] [-N|--no-fetch] [-f|--force] [--checkout|--merge|--rebase] [--[no-]recommend-shallow] [--reference <repository>] [--recursive] [--] [<path>...]
+   or: $dashless [--quiet] set-branch (--default|--branch <branch>) [--] <path>
    or: $dashless [--quiet] summary [--cached|--files] [--summary-limit <n>] [commit] [--] [<path>...]
    or: $dashless [--quiet] foreach [--recursive] <command>
    or: $dashless [--quiet] sync [--recursive] [--] [<path>...]
@@ -685,6 +686,72 @@ cmd_update()
        }
 }
 
+#
+# Configures a submodule's default branch
+#
+# $@ = requested path
+#
+cmd_set_branch() {
+       unset_branch=false
+       branch=
+
+       while test $# -ne 0
+       do
+               case "$1" in
+               -q|--quiet)
+                       # we don't do anything with this but we need to accept it
+                       ;;
+               -d|--default)
+                       unset_branch=true
+                       ;;
+               -b|--branch)
+                       case "$2" in '') usage ;; esac
+                       branch=$2
+                       shift
+                       ;;
+               --)
+                       shift
+                       break
+                       ;;
+               -*)
+                       usage
+                       ;;
+               *)
+                       break
+                       ;;
+               esac
+               shift
+       done
+
+       if test $# -ne 1
+       then
+               usage
+       fi
+
+       # we can't use `git submodule--helper name` here because internally, it
+       # hashes the path so a trailing slash could lead to an unintentional no match
+       name="$(git submodule--helper list "$1" | cut -f2)"
+       if test -z "$name"
+       then
+               exit 1
+       fi
+
+       test -n "$branch"; has_branch=$?
+       test "$unset_branch" = true; has_unset_branch=$?
+
+       if test $((!$has_branch != !$has_unset_branch)) -eq 0
+       then
+               usage
+       fi
+
+       if test $has_branch -eq 0
+       then
+               git submodule--helper config submodule."$name".branch "$branch"
+       else
+               git submodule--helper config --unset submodule."$name".branch
+       fi
+}
+
 #
 # Show commit summary for submodules in index or working tree
 #
@@ -984,7 +1051,7 @@ cmd_absorbgitdirs()
 while test $# != 0 && test -z "$command"
 do
        case "$1" in
-       add | foreach | init | deinit | update | status | summary | sync | absorbgitdirs)
+       add | foreach | init | deinit | update | set-branch | status | summary | sync | absorbgitdirs)
                command=$1
                ;;
        -q|--quiet)
@@ -1025,8 +1092,8 @@ then
     fi
 fi
 
-# "-b branch" is accepted only by "add"
-if test -n "$branch" && test "$command" != add
+# "-b branch" is accepted only by "add" and "set-branch"
+if test -n "$branch" && (test "$command" != add || test "$command" != set-branch)
 then
        usage
 fi
@@ -1037,4 +1104,4 @@ then
        usage
 fi
 
-"cmd_$command" "$@"
+"cmd_$(echo $command | sed -e s/-/_/g)" "$@"
index 89690b7adb85a9dbcda4fe85c5ab672716f41de8..fcc0fb82d8adb15c592056a259b5f8c5c264d9a2 100755 (executable)
@@ -142,6 +142,15 @@ test_expect_success 'reading submodules config from the working tree with "submo
        )
 '
 
+test_expect_success 'unsetting submodules config from the working tree with "submodule--helper config --unset"' '
+       (cd super &&
+               git submodule--helper config --unset submodule.submodule.url &&
+               git submodule--helper config submodule.submodule.url >actual &&
+               test_must_be_empty actual
+       )
+'
+
+
 test_expect_success 'writing submodules config with "submodule--helper config"' '
        (cd super &&
                echo "new_url" >expect &&
diff --git a/t/t7419-submodule-set-branch.sh b/t/t7419-submodule-set-branch.sh
new file mode 100755 (executable)
index 0000000..c4b370e
--- /dev/null
@@ -0,0 +1,93 @@
+#!/bin/sh
+#
+# Copyright (c) 2019 Denton Liu
+#
+
+test_description='Test submodules set-branch subcommand
+
+This test verifies that the set-branch subcommand of git-submodule is working
+as expected.
+'
+
+TEST_NO_CREATE_REPO=1
+. ./test-lib.sh
+
+test_expect_success 'submodule config cache setup' '
+       mkdir submodule &&
+       (cd submodule &&
+               git init &&
+               echo a >a &&
+               git add . &&
+               git commit -ma &&
+               git checkout -b topic &&
+               echo b >a &&
+               git add . &&
+               git commit -mb
+       ) &&
+       mkdir super &&
+       (cd super &&
+               git init &&
+               git submodule add ../submodule &&
+               git commit -m "add submodule"
+       )
+'
+
+test_expect_success 'ensure submodule branch is unset' '
+       (cd super &&
+               test_must_fail grep branch .gitmodules
+       )
+'
+
+test_expect_success 'test submodule set-branch --branch' '
+       (cd super &&
+               git submodule set-branch --branch topic submodule &&
+               grep "branch = topic" .gitmodules &&
+               git submodule update --remote &&
+               cat <<-\EOF >expect &&
+               b
+               EOF
+               git -C submodule show -s --pretty=%s >actual &&
+               test_cmp expect actual
+       )
+'
+
+test_expect_success 'test submodule set-branch --default' '
+       (cd super &&
+               git submodule set-branch --default submodule &&
+               test_must_fail grep branch .gitmodules &&
+               git submodule update --remote &&
+               cat <<-\EOF >expect &&
+               a
+               EOF
+               git -C submodule show -s --pretty=%s >actual &&
+               test_cmp expect actual
+       )
+'
+
+test_expect_success 'test submodule set-branch -b' '
+       (cd super &&
+               git submodule set-branch -b topic submodule &&
+               grep "branch = topic" .gitmodules &&
+               git submodule update --remote &&
+               cat <<-\EOF >expect &&
+               b
+               EOF
+               git -C submodule show -s --pretty=%s >actual &&
+               test_cmp expect actual
+       )
+'
+
+test_expect_success 'test submodule set-branch -d' '
+       (cd super &&
+               git submodule set-branch -d submodule &&
+               test_must_fail grep branch .gitmodules &&
+               git submodule update --remote &&
+               cat <<-\EOF >expect &&
+               a
+               EOF
+               git -C submodule show -s --pretty=%s >actual &&
+               test_cmp expect actual
+       )
+'
+
+test_done