git-submodule: add support for --rebase.
'git submodule update --rebase' rebases your local branch on top of what would have been checked out to a detached HEAD otherwise. In some cases, detaching the HEAD when updating a submodule complicates the workflow to commit to this submodule (checkout master, rebase, then commit). For submodules that require frequent updates but infrequent (if any) commits, a rebase can be executed directly by the git-submodule command, ensuring that the submodules stay on their respective branches. git-config key: submodule.$name.rebase (bool) Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net> Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
parent
ea0b767c1e
commit
ca2cedba70
@ -12,7 +12,7 @@ SYNOPSIS
|
||||
'git submodule' [--quiet] add [-b branch] [--] <repository> <path>
|
||||
'git submodule' [--quiet] status [--cached] [--] [<path>...]
|
||||
'git submodule' [--quiet] init [--] [<path>...]
|
||||
'git submodule' [--quiet] update [--init] [-N|--no-fetch] [--] [<path>...]
|
||||
'git submodule' [--quiet] update [--init] [-N|--no-fetch] [--rebase] [--] [<path>...]
|
||||
'git submodule' [--quiet] summary [--summary-limit <n>] [commit] [--] [<path>...]
|
||||
'git submodule' [--quiet] foreach <command>
|
||||
'git submodule' [--quiet] sync [--] [<path>...]
|
||||
@ -113,7 +113,8 @@ init::
|
||||
update::
|
||||
Update the registered submodules, i.e. clone missing submodules and
|
||||
checkout the commit specified in the index of the containing repository.
|
||||
This will make the submodules HEAD be detached.
|
||||
This will make the submodules HEAD be detached unless '--rebase' is
|
||||
specified or the key `submodule.$name.rebase` is set to `true`.
|
||||
+
|
||||
If the submodule is not yet initialized, and you just want to use the
|
||||
setting as stored in .gitmodules, you can automatically initialize the
|
||||
@ -177,6 +178,15 @@ OPTIONS
|
||||
This option is only valid for the update command.
|
||||
Don't fetch new objects from the remote site.
|
||||
|
||||
--rebase::
|
||||
This option is only valid for the update command.
|
||||
Rebase the current branch onto the commit recorded in the
|
||||
superproject. If this option is given, the submodule's HEAD will not
|
||||
be detached. If a a merge failure prevents this process, you will have
|
||||
to resolve these failures with linkgit:git-rebase[1].
|
||||
If the key `submodule.$name.rebase` is set to `true`, this option is
|
||||
implicit.
|
||||
|
||||
<path>...::
|
||||
Paths to submodule(s). When specified this will restrict the command
|
||||
to only operate on the submodules found at the specified paths.
|
||||
|
@ -30,6 +30,9 @@ submodule.<name>.path::
|
||||
submodule.<name>.url::
|
||||
Defines an url from where the submodule repository can be cloned.
|
||||
|
||||
submodule.<name>.rebase::
|
||||
Defines that the submodule should be rebased by default.
|
||||
|
||||
|
||||
EXAMPLES
|
||||
--------
|
||||
|
@ -17,6 +17,7 @@ branch=
|
||||
quiet=
|
||||
cached=
|
||||
nofetch=
|
||||
rebase=
|
||||
|
||||
#
|
||||
# print stuff on stdout unless -q was specified
|
||||
@ -294,6 +295,11 @@ cmd_init()
|
||||
git config submodule."$name".url "$url" ||
|
||||
die "Failed to register url for submodule path '$path'"
|
||||
|
||||
test true != "$(git config -f .gitmodules --bool \
|
||||
submodule."$name".rebase)" ||
|
||||
git config submodule."$name".rebase true ||
|
||||
die "Failed to register submodule path '$path' as rebasing"
|
||||
|
||||
say "Submodule '$name' ($url) registered for path '$path'"
|
||||
done
|
||||
}
|
||||
@ -321,6 +327,10 @@ cmd_update()
|
||||
shift
|
||||
nofetch=1
|
||||
;;
|
||||
-r|--rebase)
|
||||
shift
|
||||
rebase=true
|
||||
;;
|
||||
--)
|
||||
shift
|
||||
break
|
||||
@ -339,6 +349,7 @@ cmd_update()
|
||||
do
|
||||
name=$(module_name "$path") || exit
|
||||
url=$(git config submodule."$name".url)
|
||||
rebase_module=$(git config --bool submodule."$name".rebase)
|
||||
if test -z "$url"
|
||||
then
|
||||
# Only mention uninitialized submodules when its
|
||||
@ -359,6 +370,11 @@ cmd_update()
|
||||
die "Unable to find current revision in submodule path '$path'"
|
||||
fi
|
||||
|
||||
if test true = "$rebase"
|
||||
then
|
||||
rebase_module=true
|
||||
fi
|
||||
|
||||
if test "$subsha1" != "$sha1"
|
||||
then
|
||||
force=
|
||||
@ -374,11 +390,20 @@ cmd_update()
|
||||
die "Unable to fetch in submodule path '$path'"
|
||||
fi
|
||||
|
||||
(unset GIT_DIR; cd "$path" &&
|
||||
git-checkout $force -q "$sha1") ||
|
||||
die "Unable to checkout '$sha1' in submodule path '$path'"
|
||||
if test true = "$rebase_module"
|
||||
then
|
||||
command="git-rebase"
|
||||
action="rebase"
|
||||
msg="rebased onto"
|
||||
else
|
||||
command="git-checkout $force -q"
|
||||
action="checkout"
|
||||
msg="checked out"
|
||||
fi
|
||||
|
||||
say "Submodule path '$path': checked out '$sha1'"
|
||||
(unset GIT_DIR; cd "$path" && $command "$sha1") ||
|
||||
die "Unable to $action '$sha1' in submodule path '$path'"
|
||||
say "Submodule path '$path': $msg '$sha1'"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
140
t/t7406-submodule-update.sh
Executable file
140
t/t7406-submodule-update.sh
Executable file
@ -0,0 +1,140 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright (c) 2009 Red Hat, Inc.
|
||||
#
|
||||
|
||||
test_description='Test updating submodules
|
||||
|
||||
This test verifies that "git submodule update" detaches the HEAD of the
|
||||
submodule and "git submodule update --rebase" does not detach the HEAD.
|
||||
'
|
||||
|
||||
. ./test-lib.sh
|
||||
|
||||
|
||||
compare_head()
|
||||
{
|
||||
sha_master=`git-rev-list --max-count=1 master`
|
||||
sha_head=`git-rev-list --max-count=1 HEAD`
|
||||
|
||||
test "$sha_master" = "$sha_head"
|
||||
}
|
||||
|
||||
|
||||
test_expect_success 'setup a submodule tree' '
|
||||
echo file > file &&
|
||||
git add file &&
|
||||
test_tick &&
|
||||
git commit -m upstream
|
||||
git clone . super &&
|
||||
git clone super submodule &&
|
||||
(cd super &&
|
||||
git submodule add ../submodule submodule &&
|
||||
test_tick &&
|
||||
git commit -m "submodule" &&
|
||||
git submodule init submodule
|
||||
) &&
|
||||
(cd submodule &&
|
||||
echo "line2" > file &&
|
||||
git add file &&
|
||||
git commit -m "Commit 2"
|
||||
) &&
|
||||
(cd super &&
|
||||
(cd submodule &&
|
||||
git pull --rebase origin
|
||||
) &&
|
||||
git add submodule &&
|
||||
git commit -m "submodule update"
|
||||
)
|
||||
'
|
||||
|
||||
test_expect_success 'submodule update detaching the HEAD ' '
|
||||
(cd super/submodule &&
|
||||
git reset --hard HEAD~1
|
||||
) &&
|
||||
(cd super &&
|
||||
(cd submodule &&
|
||||
compare_head
|
||||
) &&
|
||||
git submodule update submodule &&
|
||||
cd submodule &&
|
||||
! compare_head
|
||||
)
|
||||
'
|
||||
|
||||
test_expect_success 'submodule update --rebase staying on master' '
|
||||
(cd super/submodule &&
|
||||
git checkout master
|
||||
) &&
|
||||
(cd super &&
|
||||
(cd submodule &&
|
||||
compare_head
|
||||
) &&
|
||||
git submodule update --rebase submodule &&
|
||||
cd submodule &&
|
||||
compare_head
|
||||
)
|
||||
'
|
||||
|
||||
test_expect_success 'submodule update - rebase true in .git/config' '
|
||||
(cd super &&
|
||||
git config submodule.submodule.rebase true
|
||||
) &&
|
||||
(cd super/submodule &&
|
||||
git reset --hard HEAD~1
|
||||
) &&
|
||||
(cd super &&
|
||||
(cd submodule &&
|
||||
compare_head
|
||||
) &&
|
||||
git submodule update submodule &&
|
||||
cd submodule &&
|
||||
compare_head
|
||||
)
|
||||
'
|
||||
|
||||
test_expect_success 'submodule update - rebase false in .git/config but --rebase given' '
|
||||
(cd super &&
|
||||
git config submodule.submodule.rebase false
|
||||
) &&
|
||||
(cd super/submodule &&
|
||||
git reset --hard HEAD~1
|
||||
) &&
|
||||
(cd super &&
|
||||
(cd submodule &&
|
||||
compare_head
|
||||
) &&
|
||||
git submodule update --rebase submodule &&
|
||||
cd submodule &&
|
||||
compare_head
|
||||
)
|
||||
'
|
||||
|
||||
test_expect_success 'submodule update - rebase false in .git/config' '
|
||||
(cd super &&
|
||||
git config submodule.submodule.rebase false
|
||||
) &&
|
||||
(cd super/submodule &&
|
||||
git reset --hard HEAD^
|
||||
) &&
|
||||
(cd super &&
|
||||
(cd submodule &&
|
||||
compare_head
|
||||
) &&
|
||||
git submodule update submodule &&
|
||||
cd submodule &&
|
||||
! compare_head
|
||||
)
|
||||
'
|
||||
|
||||
test_expect_success 'submodule init picks up rebase' '
|
||||
(cd super &&
|
||||
git config submodule.rebasing.url git://non-existing/git &&
|
||||
git config submodule.rebasing.path does-not-matter &&
|
||||
git config submodule.rebasing.rebase true &&
|
||||
git submodule init rebasing &&
|
||||
test true = $(git config --bool submodule.rebasing.rebase)
|
||||
)
|
||||
'
|
||||
|
||||
test_done
|
Loading…
Reference in New Issue
Block a user