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] add [-b branch] [--] <repository> <path>
|
||||||
'git submodule' [--quiet] status [--cached] [--] [<path>...]
|
'git submodule' [--quiet] status [--cached] [--] [<path>...]
|
||||||
'git submodule' [--quiet] init [--] [<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] summary [--summary-limit <n>] [commit] [--] [<path>...]
|
||||||
'git submodule' [--quiet] foreach <command>
|
'git submodule' [--quiet] foreach <command>
|
||||||
'git submodule' [--quiet] sync [--] [<path>...]
|
'git submodule' [--quiet] sync [--] [<path>...]
|
||||||
@ -113,7 +113,8 @@ init::
|
|||||||
update::
|
update::
|
||||||
Update the registered submodules, i.e. clone missing submodules and
|
Update the registered submodules, i.e. clone missing submodules and
|
||||||
checkout the commit specified in the index of the containing repository.
|
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
|
If the submodule is not yet initialized, and you just want to use the
|
||||||
setting as stored in .gitmodules, you can automatically initialize 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.
|
This option is only valid for the update command.
|
||||||
Don't fetch new objects from the remote site.
|
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>...::
|
<path>...::
|
||||||
Paths to submodule(s). When specified this will restrict the command
|
Paths to submodule(s). When specified this will restrict the command
|
||||||
to only operate on the submodules found at the specified paths.
|
to only operate on the submodules found at the specified paths.
|
||||||
|
@ -30,6 +30,9 @@ submodule.<name>.path::
|
|||||||
submodule.<name>.url::
|
submodule.<name>.url::
|
||||||
Defines an url from where the submodule repository can be cloned.
|
Defines an url from where the submodule repository can be cloned.
|
||||||
|
|
||||||
|
submodule.<name>.rebase::
|
||||||
|
Defines that the submodule should be rebased by default.
|
||||||
|
|
||||||
|
|
||||||
EXAMPLES
|
EXAMPLES
|
||||||
--------
|
--------
|
||||||
|
@ -17,6 +17,7 @@ branch=
|
|||||||
quiet=
|
quiet=
|
||||||
cached=
|
cached=
|
||||||
nofetch=
|
nofetch=
|
||||||
|
rebase=
|
||||||
|
|
||||||
#
|
#
|
||||||
# print stuff on stdout unless -q was specified
|
# print stuff on stdout unless -q was specified
|
||||||
@ -294,6 +295,11 @@ cmd_init()
|
|||||||
git config submodule."$name".url "$url" ||
|
git config submodule."$name".url "$url" ||
|
||||||
die "Failed to register url for submodule path '$path'"
|
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'"
|
say "Submodule '$name' ($url) registered for path '$path'"
|
||||||
done
|
done
|
||||||
}
|
}
|
||||||
@ -321,6 +327,10 @@ cmd_update()
|
|||||||
shift
|
shift
|
||||||
nofetch=1
|
nofetch=1
|
||||||
;;
|
;;
|
||||||
|
-r|--rebase)
|
||||||
|
shift
|
||||||
|
rebase=true
|
||||||
|
;;
|
||||||
--)
|
--)
|
||||||
shift
|
shift
|
||||||
break
|
break
|
||||||
@ -339,6 +349,7 @@ cmd_update()
|
|||||||
do
|
do
|
||||||
name=$(module_name "$path") || exit
|
name=$(module_name "$path") || exit
|
||||||
url=$(git config submodule."$name".url)
|
url=$(git config submodule."$name".url)
|
||||||
|
rebase_module=$(git config --bool submodule."$name".rebase)
|
||||||
if test -z "$url"
|
if test -z "$url"
|
||||||
then
|
then
|
||||||
# Only mention uninitialized submodules when its
|
# Only mention uninitialized submodules when its
|
||||||
@ -359,6 +370,11 @@ cmd_update()
|
|||||||
die "Unable to find current revision in submodule path '$path'"
|
die "Unable to find current revision in submodule path '$path'"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if test true = "$rebase"
|
||||||
|
then
|
||||||
|
rebase_module=true
|
||||||
|
fi
|
||||||
|
|
||||||
if test "$subsha1" != "$sha1"
|
if test "$subsha1" != "$sha1"
|
||||||
then
|
then
|
||||||
force=
|
force=
|
||||||
@ -374,11 +390,20 @@ cmd_update()
|
|||||||
die "Unable to fetch in submodule path '$path'"
|
die "Unable to fetch in submodule path '$path'"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
(unset GIT_DIR; cd "$path" &&
|
if test true = "$rebase_module"
|
||||||
git-checkout $force -q "$sha1") ||
|
then
|
||||||
die "Unable to checkout '$sha1' in submodule path '$path'"
|
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
|
fi
|
||||||
done
|
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