Skip to content

Commit 7d40f89

Browse files
committed
Merge branch 'ph/submodule-rebase' (early part)
* 'ph/submodule-rebase' (early part): Rename submodule.<name>.rebase to submodule.<name>.update git-submodule: add support for --rebase. Conflicts: Documentation/git-submodule.txt git-submodule.sh
2 parents 436f66b + 3294842 commit 7d40f89

File tree

4 files changed

+192
-6
lines changed

4 files changed

+192
-6
lines changed

Documentation/git-submodule.txt

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ SYNOPSIS
1313
[--reference <repository>] [--] <repository> <path>
1414
'git submodule' [--quiet] status [--cached] [--] [<path>...]
1515
'git submodule' [--quiet] init [--] [<path>...]
16-
'git submodule' [--quiet] update [--init] [-N|--no-fetch]
16+
'git submodule' [--quiet] update [--init] [-N|--no-fetch] [--rebase]
1717
[--reference <repository>] [--] [<path>...]
1818
'git submodule' [--quiet] summary [--summary-limit <n>] [commit] [--] [<path>...]
1919
'git submodule' [--quiet] foreach <command>
@@ -115,7 +115,8 @@ init::
115115
update::
116116
Update the registered submodules, i.e. clone missing submodules and
117117
checkout the commit specified in the index of the containing repository.
118-
This will make the submodules HEAD be detached.
118+
This will make the submodules HEAD be detached unless '--rebase' is
119+
specified or the key `submodule.$name.update` is set to `rebase`.
119120
+
120121
If the submodule is not yet initialized, and you just want to use the
121122
setting as stored in .gitmodules, you can automatically initialize the
@@ -179,6 +180,15 @@ OPTIONS
179180
This option is only valid for the update command.
180181
Don't fetch new objects from the remote site.
181182

183+
--rebase::
184+
This option is only valid for the update command.
185+
Rebase the current branch onto the commit recorded in the
186+
superproject. If this option is given, the submodule's HEAD will not
187+
be detached. If a a merge failure prevents this process, you will have
188+
to resolve these failures with linkgit:git-rebase[1].
189+
If the key `submodule.$name.update` is set to `rebase`, this option is
190+
implicit.
191+
182192
--reference <repository>::
183193
This option is only valid for add and update commands. These
184194
commands sometimes need to clone a remote repository. In this case,

Documentation/gitmodules.txt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,15 @@ submodule.<name>.path::
3030
submodule.<name>.url::
3131
Defines an url from where the submodule repository can be cloned.
3232

33+
submodule.<name>.update::
34+
Defines what to do when the submodule is updated by the superproject.
35+
If 'checkout' (the default), the new commit specified in the
36+
superproject will be checked out in the submodule on a detached HEAD.
37+
If 'rebase', the current branch of the submodule will be rebased onto
38+
the commit specified in the superproject.
39+
This config option is overridden if 'git submodule update' is given
40+
the '--rebase' option.
41+
3342

3443
EXAMPLES
3544
--------

git-submodule.sh

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ quiet=
1818
reference=
1919
cached=
2020
nofetch=
21+
update=
2122

2223
#
2324
# print stuff on stdout unless -q was specified
@@ -310,6 +311,11 @@ cmd_init()
310311
git config submodule."$name".url "$url" ||
311312
die "Failed to register url for submodule path '$path'"
312313

314+
upd="$(git config -f .gitmodules submodule."$name".update)"
315+
test -z "$upd" ||
316+
git config submodule."$name".update "$upd" ||
317+
die "Failed to register update mode for submodule path '$path'"
318+
313319
say "Submodule '$name' ($url) registered for path '$path'"
314320
done
315321
}
@@ -337,6 +343,10 @@ cmd_update()
337343
shift
338344
nofetch=1
339345
;;
346+
-r|--rebase)
347+
shift
348+
update="rebase"
349+
;;
340350
--reference)
341351
case "$2" in '') usage ;; esac
342352
reference="--reference=$2"
@@ -369,6 +379,7 @@ cmd_update()
369379
do
370380
name=$(module_name "$path") || exit
371381
url=$(git config submodule."$name".url)
382+
update_module=$(git config submodule."$name".update)
372383
if test -z "$url"
373384
then
374385
# Only mention uninitialized submodules when its
@@ -389,6 +400,11 @@ cmd_update()
389400
die "Unable to find current revision in submodule path '$path'"
390401
fi
391402

403+
if ! test -z "$update"
404+
then
405+
update_module=$update
406+
fi
407+
392408
if test "$subsha1" != "$sha1"
393409
then
394410
force=
@@ -404,11 +420,22 @@ cmd_update()
404420
die "Unable to fetch in submodule path '$path'"
405421
fi
406422

407-
(unset GIT_DIR; cd "$path" &&
408-
git-checkout $force -q "$sha1") ||
409-
die "Unable to checkout '$sha1' in submodule path '$path'"
423+
case "$update_module" in
424+
rebase)
425+
command="git rebase"
426+
action="rebase"
427+
msg="rebased onto"
428+
;;
429+
*)
430+
command="git checkout $force -q"
431+
action="checkout"
432+
msg="checked out"
433+
;;
434+
esac
410435

411-
say "Submodule path '$path': checked out '$sha1'"
436+
(unset GIT_DIR; cd "$path" && $command "$sha1") ||
437+
die "Unable to $action '$sha1' in submodule path '$path'"
438+
say "Submodule path '$path': $msg '$sha1'"
412439
fi
413440
done
414441
}

t/t7406-submodule-update.sh

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
#!/bin/sh
2+
#
3+
# Copyright (c) 2009 Red Hat, Inc.
4+
#
5+
6+
test_description='Test updating submodules
7+
8+
This test verifies that "git submodule update" detaches the HEAD of the
9+
submodule and "git submodule update --rebase" does not detach the HEAD.
10+
'
11+
12+
. ./test-lib.sh
13+
14+
15+
compare_head()
16+
{
17+
sha_master=`git-rev-list --max-count=1 master`
18+
sha_head=`git-rev-list --max-count=1 HEAD`
19+
20+
test "$sha_master" = "$sha_head"
21+
}
22+
23+
24+
test_expect_success 'setup a submodule tree' '
25+
echo file > file &&
26+
git add file &&
27+
test_tick &&
28+
git commit -m upstream
29+
git clone . super &&
30+
git clone super submodule &&
31+
(cd super &&
32+
git submodule add ../submodule submodule &&
33+
test_tick &&
34+
git commit -m "submodule" &&
35+
git submodule init submodule
36+
) &&
37+
(cd submodule &&
38+
echo "line2" > file &&
39+
git add file &&
40+
git commit -m "Commit 2"
41+
) &&
42+
(cd super &&
43+
(cd submodule &&
44+
git pull --rebase origin
45+
) &&
46+
git add submodule &&
47+
git commit -m "submodule update"
48+
)
49+
'
50+
51+
test_expect_success 'submodule update detaching the HEAD ' '
52+
(cd super/submodule &&
53+
git reset --hard HEAD~1
54+
) &&
55+
(cd super &&
56+
(cd submodule &&
57+
compare_head
58+
) &&
59+
git submodule update submodule &&
60+
cd submodule &&
61+
! compare_head
62+
)
63+
'
64+
65+
test_expect_success 'submodule update --rebase staying on master' '
66+
(cd super/submodule &&
67+
git checkout master
68+
) &&
69+
(cd super &&
70+
(cd submodule &&
71+
compare_head
72+
) &&
73+
git submodule update --rebase submodule &&
74+
cd submodule &&
75+
compare_head
76+
)
77+
'
78+
79+
test_expect_success 'submodule update - rebase in .git/config' '
80+
(cd super &&
81+
git config submodule.submodule.update rebase
82+
) &&
83+
(cd super/submodule &&
84+
git reset --hard HEAD~1
85+
) &&
86+
(cd super &&
87+
(cd submodule &&
88+
compare_head
89+
) &&
90+
git submodule update submodule &&
91+
cd submodule &&
92+
compare_head
93+
)
94+
'
95+
96+
test_expect_success 'submodule update - checkout in .git/config but --rebase given' '
97+
(cd super &&
98+
git config submodule.submodule.update checkout
99+
) &&
100+
(cd super/submodule &&
101+
git reset --hard HEAD~1
102+
) &&
103+
(cd super &&
104+
(cd submodule &&
105+
compare_head
106+
) &&
107+
git submodule update --rebase submodule &&
108+
cd submodule &&
109+
compare_head
110+
)
111+
'
112+
113+
test_expect_success 'submodule update - checkout in .git/config' '
114+
(cd super &&
115+
git config submodule.submodule.update checkout
116+
) &&
117+
(cd super/submodule &&
118+
git reset --hard HEAD^
119+
) &&
120+
(cd super &&
121+
(cd submodule &&
122+
compare_head
123+
) &&
124+
git submodule update submodule &&
125+
cd submodule &&
126+
! compare_head
127+
)
128+
'
129+
130+
test_expect_success 'submodule init picks up rebase' '
131+
(cd super &&
132+
git config submodule.rebasing.url git://non-existing/git &&
133+
git config submodule.rebasing.path does-not-matter &&
134+
git config submodule.rebasing.update rebase &&
135+
git submodule init rebasing &&
136+
test "rebase" = $(git config submodule.rebasing.update)
137+
)
138+
'
139+
140+
test_done

0 commit comments

Comments
 (0)