submodule: teach set-branch subcommand
This teaches git-submodule the set-branch subcommand which allows the branch of a submodule to be set through a porcelain command without having to manually manipulate the .gitmodules file. Signed-off-by: Denton Liu <liu.denton@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Denton Liu committed
Feb 8, 2019 at 03:21 UTC
b57e8119e6e08f731308923ef2b033eb45152bc6
4 files changed
+175
-5
Documentation/git-submodule.txt
+7
@@ -14,6 +14,7 @@ SYNOPSIS
14
'git submodule' [--quiet] init [--] [<path>...]
15
'git submodule' [--quiet] deinit [-f|--force] (--all|[--] <path>...)
16
'git submodule' [--quiet] update [<options>] [--] [<path>...]
17
+'git submodule' [--quiet] set-branch [<options>] [--] <path>
18
'git submodule' [--quiet] summary [<options>] [--] [<path>...]
19
'git submodule' [--quiet] foreach [--recursive] <command>
20
'git submodule' [--quiet] sync [--recursive] [--] [<path>...]
@@ -168,6 +169,12 @@ submodule with the `--init` option.
169
If `--recursive` is specified, this command will recurse into the
170
registered submodules, and update any nested submodules within.
171
--
172
+set-branch ((-d|--default)|(-b|--branch <branch>)) [--] <path>::
173
+ Sets the default remote tracking branch for the submodule. The
174
+ `--branch` option allows the remote branch to be specified. The
175
+ `--default` option removes the submodule.<name>.branch configuration
176
+ key, which causes the tracking branch to default to 'master'.
177
+
178
summary [--cached|--files] [(-n|--summary-limit) <n>] [commit] [--] [<path>...]::
179
Show commit summary between the given commit (defaults to HEAD) and
180
working tree/index. For a submodule in question, a series of commits
contrib/completion/git-completion.bash
+4
-1
@@ -2573,7 +2573,7 @@ _git_submodule ()
2573
{
2574
__git_has_doubledash && return
2575
2576
- local subcommands="add status init deinit update summary foreach sync"
2576
+ local subcommands="add status init deinit update set-branch summary foreach sync"
2577
local subcommand="$(__git_find_on_cmdline "$subcommands")"
2578
if [ -z "$subcommand" ]; then
2579
case "$cur" in
@@ -2604,6 +2604,9 @@ _git_submodule ()
2604
--force --rebase --merge --reference --depth --recursive --jobs
2605
"
2606
;;
2607
+ set-branch,--*)
2608
+ __gitcomp "--default --branch"
2609
+ ;;
2610
summary,--*)
2611
__gitcomp "--cached --files --summary-limit"
2612
;;
git-submodule.sh
+71
-4
@@ -10,6 +10,7 @@ USAGE="[--quiet] add [-b <branch>] [-f|--force] [--name <name>] [--reference <re
10
or: $dashless [--quiet] init [--] [<path>...]
11
or: $dashless [--quiet] deinit [-f|--force] (--all| [--] <path>...)
12
or: $dashless [--quiet] update [--init] [--remote] [-N|--no-fetch] [-f|--force] [--checkout|--merge|--rebase] [--[no-]recommend-shallow] [--reference <repository>] [--recursive] [--] [<path>...]
13
+ or: $dashless [--quiet] set-branch (--default|--branch <branch>) [--] <path>
14
or: $dashless [--quiet] summary [--cached|--files] [--summary-limit <n>] [commit] [--] [<path>...]
15
or: $dashless [--quiet] foreach [--recursive] <command>
16
or: $dashless [--quiet] sync [--recursive] [--] [<path>...]
@@ -684,6 +685,72 @@ cmd_update()
685
}
686
}
687
688
+#
689
+# Configures a submodule's default branch
690
+#
691
+# $@ = requested path
692
+#
693
+cmd_set_branch() {
694
+ unset_branch=false
695
+ branch=
696
+
697
+ while test $# -ne 0
698
+ do
699
+ case "$1" in
700
+ -q|--quiet)
701
+ # we don't do anything with this but we need to accept it
702
+ ;;
703
+ -d|--default)
704
+ unset_branch=true
705
+ ;;
706
+ -b|--branch)
707
+ case "$2" in '') usage ;; esac
708
+ branch=$2
709
+ shift
710
+ ;;
711
+ --)
712
+ shift
713
+ break
714
+ ;;
715
+ -*)
716
+ usage
717
+ ;;
718
+ *)
719
+ break
720
+ ;;
721
+ esac
722
+ shift
723
+ done
724
+
725
+ if test $# -ne 1
726
+ then
727
+ usage
728
+ fi
729
+
730
+ # we can't use `git submodule--helper name` here because internally, it
731
+ # hashes the path so a trailing slash could lead to an unintentional no match
732
+ name="$(git submodule--helper list "$1" | cut -f2)"
733
+ if test -z "$name"
734
+ then
735
+ exit 1
736
+ fi
737
+
738
+ test -n "$branch"; has_branch=$?
739
+ test "$unset_branch" = true; has_unset_branch=$?
740
+
741
+ if test $((!$has_branch != !$has_unset_branch)) -eq 0
742
+ then
743
+ usage
744
+ fi
745
+
746
+ if test $has_branch -eq 0
747
+ then
748
+ git submodule--helper config submodule."$name".branch "$branch"
749
+ else
750
+ git submodule--helper config --unset submodule."$name".branch
751
+ fi
752
+}
753
+
754
#
755
# Show commit summary for submodules in index or working tree
756
#
@@ -983,7 +1050,7 @@ cmd_absorbgitdirs()
1050
while test $# != 0 && test -z "$command"
1051
do
1052
case "$1" in
986
- add | foreach | init | deinit | update | status | summary | sync | absorbgitdirs)
1053
+ add | foreach | init | deinit | update | set-branch | status | summary | sync | absorbgitdirs)
1054
command=$1
1055
;;
1056
-q|--quiet)
@@ -1024,8 +1091,8 @@ then
1091
fi
1092
fi
1093
1027
-# "-b branch" is accepted only by "add"
1028
-if test -n "$branch" && test "$command" != add
1094
+# "-b branch" is accepted only by "add" and "set-branch"
1095
+if test -n "$branch" && (test "$command" != add || test "$command" != set-branch)
1096
then
1097
usage
1098
fi
@@ -1036,4 +1103,4 @@ then
1103
usage
1104
fi
1105
1039
-"cmd_$command" "$@"
1106
+"cmd_$(echo $command | sed -e s/-/_/g)" "$@"
t/t7419-submodule-set-branch.sh
new
+93
@@ -0,0 +1,93 @@
1
+#!/bin/sh
2
+#
3
+# Copyright (c) 2019 Denton Liu
4
+#
5
+
6
+test_description='Test submodules set-branch subcommand
7
+
8
+This test verifies that the set-branch subcommand of git-submodule is working
9
+as expected.
10
+'
11
+
12
+TEST_NO_CREATE_REPO=1
13
+. ./test-lib.sh
14
+
15
+test_expect_success 'submodule config cache setup' '
16
+ mkdir submodule &&
17
+ (cd submodule &&
18
+ git init &&
19
+ echo a >a &&
20
+ git add . &&
21
+ git commit -ma &&
22
+ git checkout -b topic &&
23
+ echo b >a &&
24
+ git add . &&
25
+ git commit -mb
26
+ ) &&
27
+ mkdir super &&
28
+ (cd super &&
29
+ git init &&
30
+ git submodule add ../submodule &&
31
+ git commit -m "add submodule"
32
+ )
33
+'
34
+
35
+test_expect_success 'ensure submodule branch is unset' '
36
+ (cd super &&
37
+ test_must_fail grep branch .gitmodules
38
+ )
39
+'
40
+
41
+test_expect_success 'test submodule set-branch --branch' '
42
+ (cd super &&
43
+ git submodule set-branch --branch topic submodule &&
44
+ grep "branch = topic" .gitmodules &&
45
+ git submodule update --remote &&
46
+ cat <<-\EOF >expect &&
47
+ b
48
+ EOF
49
+ git -C submodule show -s --pretty=%s >actual &&
50
+ test_cmp expect actual
51
+ )
52
+'
53
+
54
+test_expect_success 'test submodule set-branch --default' '
55
+ (cd super &&
56
+ git submodule set-branch --default submodule &&
57
+ test_must_fail grep branch .gitmodules &&
58
+ git submodule update --remote &&
59
+ cat <<-\EOF >expect &&
60
+ a
61
+ EOF
62
+ git -C submodule show -s --pretty=%s >actual &&
63
+ test_cmp expect actual
64
+ )
65
+'
66
+
67
+test_expect_success 'test submodule set-branch -b' '
68
+ (cd super &&
69
+ git submodule set-branch -b topic submodule &&
70
+ grep "branch = topic" .gitmodules &&
71
+ git submodule update --remote &&
72
+ cat <<-\EOF >expect &&
73
+ b
74
+ EOF
75
+ git -C submodule show -s --pretty=%s >actual &&
76
+ test_cmp expect actual
77
+ )
78
+'
79
+
80
+test_expect_success 'test submodule set-branch -d' '
81
+ (cd super &&
82
+ git submodule set-branch -d submodule &&
83
+ test_must_fail grep branch .gitmodules &&
84
+ git submodule update --remote &&
85
+ cat <<-\EOF >expect &&
86
+ a
87
+ EOF
88
+ git -C submodule show -s --pretty=%s >actual &&
89
+ test_cmp expect actual
90
+ )
91
+'
92
+
93
+test_done