2007-05-26 21:56:40 +08:00
|
|
|
#!/bin/sh
|
|
|
|
#
|
2007-06-25 05:06:07 +08:00
|
|
|
# git-submodules.sh: add, init, update or list git submodules
|
2007-05-26 21:56:40 +08:00
|
|
|
#
|
|
|
|
# Copyright (c) 2007 Lars Hjemli
|
|
|
|
|
2009-08-19 09:45:19 +08:00
|
|
|
dashless=$(basename "$0" | sed -e 's/-/ /')
|
2009-09-22 23:10:12 +08:00
|
|
|
USAGE="[--quiet] add [-b branch] [--reference <repository>] [--] <repository> [<path>]
|
2009-08-19 09:45:24 +08:00
|
|
|
or: $dashless [--quiet] status [--cached] [--recursive] [--] [<path>...]
|
2009-08-19 09:45:19 +08:00
|
|
|
or: $dashless [--quiet] init [--] [<path>...]
|
2009-08-19 09:45:23 +08:00
|
|
|
or: $dashless [--quiet] update [--init] [-N|--no-fetch] [--rebase] [--reference <repository>] [--merge] [--recursive] [--] [<path>...]
|
2009-08-28 07:59:25 +08:00
|
|
|
or: $dashless [--quiet] summary [--cached|--files] [--summary-limit <n>] [commit] [--] [<path>...]
|
2009-08-19 09:45:22 +08:00
|
|
|
or: $dashless [--quiet] foreach [--recursive] <command>
|
2009-08-19 09:45:19 +08:00
|
|
|
or: $dashless [--quiet] sync [--] [<path>...]"
|
2007-11-06 17:50:02 +08:00
|
|
|
OPTIONS_SPEC=
|
2007-05-26 21:56:40 +08:00
|
|
|
. git-sh-setup
|
2008-08-25 02:46:10 +08:00
|
|
|
. git-parse-remote
|
2007-05-26 21:56:40 +08:00
|
|
|
require_work_tree
|
|
|
|
|
2008-01-15 18:48:45 +08:00
|
|
|
command=
|
2007-06-25 05:06:07 +08:00
|
|
|
branch=
|
2009-05-05 03:30:01 +08:00
|
|
|
reference=
|
2007-05-26 21:56:40 +08:00
|
|
|
cached=
|
2009-08-14 03:32:50 +08:00
|
|
|
files=
|
2009-02-06 06:18:32 +08:00
|
|
|
nofetch=
|
Rename submodule.<name>.rebase to submodule.<name>.update
The addition of "submodule.<name>.rebase" demonstrates the usefulness of
alternatives to the default behaviour of "git submodule update". However,
by naming the config variable "submodule.<name>.rebase", and making it a
boolean choice, we are artificially constraining future git versions that
may want to add _more_ alternatives than just "rebase".
Therefore, while "submodule.<name>.rebase" is not yet in a stable git
release, future-proof it, by changing it from
submodule.<name>.rebase = true/false
to
submodule.<name>.update = rebase/checkout
where "checkout" specifies the default behaviour of "git submodule update"
(checking out the new commit to a detached HEAD), and "rebase" specifies
the --rebase behaviour (where the current local branch in the submodule is
rebase onto the new commit). Thus .update == checkout is equivalent to
.rebase == false, and .update == rebase is equivalent to .rebase == true.
Finally, leaving .update unset is equivalent to leaving .rebase unset.
In future git versions, other alternatives to "git submodule update"
behaviour can be included by adding them to the list of allowable values
for the submodule.<name>.update variable.
Signed-off-by: Johan Herland <johan@herland.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-06-03 14:27:06 +08:00
|
|
|
update=
|
2009-08-19 09:45:22 +08:00
|
|
|
prefix=
|
2007-05-26 21:56:40 +08:00
|
|
|
|
2007-09-24 10:19:42 +08:00
|
|
|
# Resolve relative url by appending to parent's url
|
|
|
|
resolve_relative_url ()
|
|
|
|
{
|
2008-08-25 02:46:10 +08:00
|
|
|
remote=$(get_default_remote)
|
2008-06-15 01:09:41 +08:00
|
|
|
remoteurl=$(git config "remote.$remote.url") ||
|
|
|
|
die "remote ($remote) does not have a url defined in .git/config"
|
2007-09-24 10:19:42 +08:00
|
|
|
url="$1"
|
git-submodule.sh - Remove trailing / from URL if found
git clone does not complain if a trailing '/' is included in the origin
URL, but doing so causes resolution of a submodule's URL relative to the
superproject to fail. Trailing /'s are likely when cloning locally using
tab-completion, so the slash may appear in either superproject or
submodule URL. So, ignore the trailing slash if it already exists in
the superproject's URL, and don't record one for the submodule (which
could itself have submodules...).
The problem I'm trying to fix is that a number of folks have
superprojects checked out where the recorded origin URL has a trailing
/, and a submodule has its origin in a directory sitting right next to
the superproject on the server. Thus, we have:
superproject url = server:/public/super
submodoule url = server:/public/sub1
However, in the checked out superproject's .git/config
[remote "origin"]
url = server:/public/super/
and for similar reasons, the submodule has its URL recorded in .gitmodules as
[submodule "sub"]
path = submodule1
url = ../sub1/
resolve_relative_url gets the submodule's recorded url as $1, which
the caller retrieved from .gitmodules, and retrieves the superprojects
origin from .git/config. So in this case resolve_relative_url has
that:
url = ../sub1/
remoteurl = server:/public/super/
So, without any patch, resolve_relative_url computes the submodule's URL as:
server:/public/super/sub1/
rather than
server:/public/sub1
In summary, it is essential that resolve_relative_url strip the
trailing / from the superproject's url before starting, and
beneficial if it assures that the result does not contain
a trailing / as the submodule may itself also be a superproject.
Signed-off-by: Mark Levedahl <mlevedahl@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2008-08-22 07:54:01 +08:00
|
|
|
remoteurl=${remoteurl%/}
|
2007-09-24 10:19:42 +08:00
|
|
|
while test -n "$url"
|
|
|
|
do
|
|
|
|
case "$url" in
|
|
|
|
../*)
|
|
|
|
url="${url#../}"
|
|
|
|
remoteurl="${remoteurl%/*}"
|
|
|
|
;;
|
|
|
|
./*)
|
|
|
|
url="${url#./}"
|
|
|
|
;;
|
|
|
|
*)
|
|
|
|
break;;
|
|
|
|
esac
|
|
|
|
done
|
git-submodule.sh - Remove trailing / from URL if found
git clone does not complain if a trailing '/' is included in the origin
URL, but doing so causes resolution of a submodule's URL relative to the
superproject to fail. Trailing /'s are likely when cloning locally using
tab-completion, so the slash may appear in either superproject or
submodule URL. So, ignore the trailing slash if it already exists in
the superproject's URL, and don't record one for the submodule (which
could itself have submodules...).
The problem I'm trying to fix is that a number of folks have
superprojects checked out where the recorded origin URL has a trailing
/, and a submodule has its origin in a directory sitting right next to
the superproject on the server. Thus, we have:
superproject url = server:/public/super
submodoule url = server:/public/sub1
However, in the checked out superproject's .git/config
[remote "origin"]
url = server:/public/super/
and for similar reasons, the submodule has its URL recorded in .gitmodules as
[submodule "sub"]
path = submodule1
url = ../sub1/
resolve_relative_url gets the submodule's recorded url as $1, which
the caller retrieved from .gitmodules, and retrieves the superprojects
origin from .git/config. So in this case resolve_relative_url has
that:
url = ../sub1/
remoteurl = server:/public/super/
So, without any patch, resolve_relative_url computes the submodule's URL as:
server:/public/super/sub1/
rather than
server:/public/sub1
In summary, it is essential that resolve_relative_url strip the
trailing / from the superproject's url before starting, and
beneficial if it assures that the result does not contain
a trailing / as the submodule may itself also be a superproject.
Signed-off-by: Mark Levedahl <mlevedahl@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2008-08-22 07:54:01 +08:00
|
|
|
echo "$remoteurl/${url%/}"
|
2007-09-24 10:19:42 +08:00
|
|
|
}
|
|
|
|
|
2008-08-22 15:30:50 +08:00
|
|
|
#
|
|
|
|
# Get submodule info for registered submodules
|
|
|
|
# $@ = path to limit submodule list
|
|
|
|
#
|
|
|
|
module_list()
|
|
|
|
{
|
2009-11-24 07:56:32 +08:00
|
|
|
git ls-files --error-unmatch --stage -- "$@" | sane_grep '^160000 '
|
2008-08-22 15:30:50 +08:00
|
|
|
}
|
|
|
|
|
2007-06-12 03:12:24 +08:00
|
|
|
#
|
|
|
|
# Map submodule path to submodule name
|
|
|
|
#
|
|
|
|
# $1 = path
|
|
|
|
#
|
|
|
|
module_name()
|
|
|
|
{
|
2007-07-26 06:51:26 +08:00
|
|
|
# Do we have "submodule.<something>.path = $1" defined in .gitmodules file?
|
2008-06-11 21:09:19 +08:00
|
|
|
re=$(printf '%s\n' "$1" | sed -e 's/[].[^$\\*]/\\&/g')
|
2008-05-15 15:42:58 +08:00
|
|
|
name=$( git config -f .gitmodules --get-regexp '^submodule\..*\.path$' |
|
2007-07-26 06:51:26 +08:00
|
|
|
sed -n -e 's|^submodule\.\(.*\)\.path '"$re"'$|\1|p' )
|
2007-06-12 03:12:24 +08:00
|
|
|
test -z "$name" &&
|
|
|
|
die "No submodule mapping found in .gitmodules for path '$path'"
|
|
|
|
echo "$name"
|
|
|
|
}
|
2007-06-06 17:13:01 +08:00
|
|
|
|
|
|
|
#
|
|
|
|
# Clone a submodule
|
|
|
|
#
|
2008-01-15 18:35:49 +08:00
|
|
|
# Prior to calling, cmd_update checks that a possibly existing
|
2007-06-25 05:06:07 +08:00
|
|
|
# path is not a git repository.
|
2008-01-15 18:35:49 +08:00
|
|
|
# Likewise, cmd_add checks that path does not exist at all,
|
2007-06-25 05:06:07 +08:00
|
|
|
# since it is the location of a new submodule.
|
|
|
|
#
|
2007-06-06 17:13:01 +08:00
|
|
|
module_clone()
|
|
|
|
{
|
|
|
|
path=$1
|
|
|
|
url=$2
|
2009-05-05 03:30:01 +08:00
|
|
|
reference="$3"
|
2007-06-06 17:13:01 +08:00
|
|
|
|
|
|
|
# If there already is a directory at the submodule path,
|
|
|
|
# expect it to be empty (since that is the default checkout
|
|
|
|
# action) and try to remove it.
|
|
|
|
# Note: if $path is a symlink to a directory the test will
|
|
|
|
# succeed but the rmdir will fail. We might want to fix this.
|
|
|
|
if test -d "$path"
|
|
|
|
then
|
|
|
|
rmdir "$path" 2>/dev/null ||
|
2009-09-29 13:42:25 +08:00
|
|
|
die "Directory '$path' exists, but is neither empty nor a git repository"
|
2007-06-06 17:13:01 +08:00
|
|
|
fi
|
|
|
|
|
|
|
|
test -e "$path" &&
|
|
|
|
die "A file already exist at path '$path'"
|
|
|
|
|
2009-05-05 03:30:01 +08:00
|
|
|
if test -n "$reference"
|
|
|
|
then
|
|
|
|
git-clone "$reference" -n "$url" "$path"
|
|
|
|
else
|
|
|
|
git-clone -n "$url" "$path"
|
|
|
|
fi ||
|
2007-06-12 03:12:24 +08:00
|
|
|
die "Clone of '$url' into submodule path '$path' failed"
|
2007-06-06 17:13:01 +08:00
|
|
|
}
|
|
|
|
|
2007-06-25 05:06:07 +08:00
|
|
|
#
|
|
|
|
# Add a new submodule to the working tree, .gitmodules and the index
|
|
|
|
#
|
git-submodule - make "submodule add" more strict, and document it
This change makes "submodule add" much more strict in the arguments it
takes, and is intended to address confusion as recently noted on the
git-list. With this change, the required syntax is:
$ git submodule add URL path
Specifically, this eliminates the form
$ git submodule add URL
which was confused by more than one person as
$ git submodule add path
With this patch, the URL locating the submodule's origin repository can be
either an absolute URL, or (if it begins with ./ or ../) can express the
submodule's repository location relative to the superproject's origin.
This patch also eliminates a third form of URL, which was relative to the
superproject's top-level directory (not its repository). Any URL that was
neither absolute nor matched ./*|../* was assumed to point to a
subdirectory of the superproject as the location of the submodule's origin
repository. This URL form was confusing and does not seem to correspond
to an important use-case. Specifically, no-one has identified the need to
clone from a repository already in the superproject's tree, but if this is
needed it is easily done using an absolute URL: $(pwd)/relative-path. So,
no functionality is lost with this patch. (t6008-rev-list-submodule.sh did
rely upon this relative URL, fixed by using $(pwd).)
Following this change, there are exactly four variants of
submodule-add, as both arguments have two flavors:
URL can be absolute, or can begin with ./|../ and thus names the
submodule's origin relative to the superproject's origin.
Note: With this patch, "submodule add" discerns an absolute URL as
matching /*|*:*: e.g., URL begins with /, or it contains a :. This works
for all valid URLs, an absolute path in POSIX, as well as an absolute path
on Windows).
path can either already exist as a valid git repo, or will be cloned from
the given URL. The first form here eases creation of a new submodule in
an existing superproject as the submodule can be added and tested in-tree
before pushing to the public repository. However, the more usual form is
the second, where the repo is cloned from the given URL.
This specifically addresses the issue of
$ git submodule add a/b/c
attempting to clone from a repository at "a/b/c" to create a new module
in "c". This also simplifies description of "relative URL" as there is now
exactly *one* form: a URL relative to the parent's origin repo.
Signed-off-by: Mark Levedahl <mlevedahl@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2008-07-10 09:05:40 +08:00
|
|
|
# $@ = repo path
|
2007-06-25 05:06:07 +08:00
|
|
|
#
|
|
|
|
# optional branch is stored in global branch variable
|
|
|
|
#
|
2008-01-15 18:35:49 +08:00
|
|
|
cmd_add()
|
2007-06-25 05:06:07 +08:00
|
|
|
{
|
2008-01-15 18:48:45 +08:00
|
|
|
# parse $args after "submodule ... add".
|
|
|
|
while test $# -ne 0
|
|
|
|
do
|
|
|
|
case "$1" in
|
|
|
|
-b | --branch)
|
|
|
|
case "$2" in '') usage ;; esac
|
|
|
|
branch=$2
|
|
|
|
shift
|
|
|
|
;;
|
|
|
|
-q|--quiet)
|
2009-06-17 06:33:00 +08:00
|
|
|
GIT_QUIET=1
|
2008-01-15 18:48:45 +08:00
|
|
|
;;
|
2009-05-05 03:30:01 +08:00
|
|
|
--reference)
|
|
|
|
case "$2" in '') usage ;; esac
|
|
|
|
reference="--reference=$2"
|
|
|
|
shift
|
|
|
|
;;
|
|
|
|
--reference=*)
|
|
|
|
reference="$1"
|
|
|
|
shift
|
|
|
|
;;
|
2008-01-15 18:48:45 +08:00
|
|
|
--)
|
|
|
|
shift
|
|
|
|
break
|
|
|
|
;;
|
|
|
|
-*)
|
|
|
|
usage
|
|
|
|
;;
|
|
|
|
*)
|
|
|
|
break
|
|
|
|
;;
|
|
|
|
esac
|
|
|
|
shift
|
|
|
|
done
|
|
|
|
|
2007-06-25 05:06:07 +08:00
|
|
|
repo=$1
|
|
|
|
path=$2
|
|
|
|
|
2009-09-22 23:10:12 +08:00
|
|
|
if test -z "$path"; then
|
|
|
|
path=$(echo "$repo" |
|
|
|
|
sed -e 's|/$||' -e 's|:*/*\.git$||' -e 's|.*[/:]||g')
|
|
|
|
fi
|
|
|
|
|
git-submodule - make "submodule add" more strict, and document it
This change makes "submodule add" much more strict in the arguments it
takes, and is intended to address confusion as recently noted on the
git-list. With this change, the required syntax is:
$ git submodule add URL path
Specifically, this eliminates the form
$ git submodule add URL
which was confused by more than one person as
$ git submodule add path
With this patch, the URL locating the submodule's origin repository can be
either an absolute URL, or (if it begins with ./ or ../) can express the
submodule's repository location relative to the superproject's origin.
This patch also eliminates a third form of URL, which was relative to the
superproject's top-level directory (not its repository). Any URL that was
neither absolute nor matched ./*|../* was assumed to point to a
subdirectory of the superproject as the location of the submodule's origin
repository. This URL form was confusing and does not seem to correspond
to an important use-case. Specifically, no-one has identified the need to
clone from a repository already in the superproject's tree, but if this is
needed it is easily done using an absolute URL: $(pwd)/relative-path. So,
no functionality is lost with this patch. (t6008-rev-list-submodule.sh did
rely upon this relative URL, fixed by using $(pwd).)
Following this change, there are exactly four variants of
submodule-add, as both arguments have two flavors:
URL can be absolute, or can begin with ./|../ and thus names the
submodule's origin relative to the superproject's origin.
Note: With this patch, "submodule add" discerns an absolute URL as
matching /*|*:*: e.g., URL begins with /, or it contains a :. This works
for all valid URLs, an absolute path in POSIX, as well as an absolute path
on Windows).
path can either already exist as a valid git repo, or will be cloned from
the given URL. The first form here eases creation of a new submodule in
an existing superproject as the submodule can be added and tested in-tree
before pushing to the public repository. However, the more usual form is
the second, where the repo is cloned from the given URL.
This specifically addresses the issue of
$ git submodule add a/b/c
attempting to clone from a repository at "a/b/c" to create a new module
in "c". This also simplifies description of "relative URL" as there is now
exactly *one* form: a URL relative to the parent's origin repo.
Signed-off-by: Mark Levedahl <mlevedahl@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2008-07-10 09:05:40 +08:00
|
|
|
if test -z "$repo" -o -z "$path"; then
|
2007-06-25 05:06:07 +08:00
|
|
|
usage
|
|
|
|
fi
|
|
|
|
|
git-submodule - make "submodule add" more strict, and document it
This change makes "submodule add" much more strict in the arguments it
takes, and is intended to address confusion as recently noted on the
git-list. With this change, the required syntax is:
$ git submodule add URL path
Specifically, this eliminates the form
$ git submodule add URL
which was confused by more than one person as
$ git submodule add path
With this patch, the URL locating the submodule's origin repository can be
either an absolute URL, or (if it begins with ./ or ../) can express the
submodule's repository location relative to the superproject's origin.
This patch also eliminates a third form of URL, which was relative to the
superproject's top-level directory (not its repository). Any URL that was
neither absolute nor matched ./*|../* was assumed to point to a
subdirectory of the superproject as the location of the submodule's origin
repository. This URL form was confusing and does not seem to correspond
to an important use-case. Specifically, no-one has identified the need to
clone from a repository already in the superproject's tree, but if this is
needed it is easily done using an absolute URL: $(pwd)/relative-path. So,
no functionality is lost with this patch. (t6008-rev-list-submodule.sh did
rely upon this relative URL, fixed by using $(pwd).)
Following this change, there are exactly four variants of
submodule-add, as both arguments have two flavors:
URL can be absolute, or can begin with ./|../ and thus names the
submodule's origin relative to the superproject's origin.
Note: With this patch, "submodule add" discerns an absolute URL as
matching /*|*:*: e.g., URL begins with /, or it contains a :. This works
for all valid URLs, an absolute path in POSIX, as well as an absolute path
on Windows).
path can either already exist as a valid git repo, or will be cloned from
the given URL. The first form here eases creation of a new submodule in
an existing superproject as the submodule can be added and tested in-tree
before pushing to the public repository. However, the more usual form is
the second, where the repo is cloned from the given URL.
This specifically addresses the issue of
$ git submodule add a/b/c
attempting to clone from a repository at "a/b/c" to create a new module
in "c". This also simplifies description of "relative URL" as there is now
exactly *one* form: a URL relative to the parent's origin repo.
Signed-off-by: Mark Levedahl <mlevedahl@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2008-07-10 09:05:40 +08:00
|
|
|
# assure repo is absolute or relative to parent
|
|
|
|
case "$repo" in
|
|
|
|
./*|../*)
|
|
|
|
# dereference source url relative to parent's url
|
|
|
|
realrepo=$(resolve_relative_url "$repo") || exit
|
|
|
|
;;
|
|
|
|
*:*|/*)
|
|
|
|
# absolute url
|
|
|
|
realrepo=$repo
|
|
|
|
;;
|
|
|
|
*)
|
|
|
|
die "repo URL: '$repo' must be absolute or begin with ./|../"
|
|
|
|
;;
|
|
|
|
esac
|
|
|
|
|
2009-03-03 23:08:21 +08:00
|
|
|
# normalize path:
|
|
|
|
# multiple //; leading ./; /./; /../; trailing /
|
|
|
|
path=$(printf '%s/\n' "$path" |
|
|
|
|
sed -e '
|
|
|
|
s|//*|/|g
|
|
|
|
s|^\(\./\)*||
|
|
|
|
s|/\./|/|g
|
|
|
|
:start
|
|
|
|
s|\([^/]*\)/\.\./||
|
|
|
|
tstart
|
|
|
|
s|/*$||
|
|
|
|
')
|
2007-07-03 13:52:14 +08:00
|
|
|
git ls-files --error-unmatch "$path" > /dev/null 2>&1 &&
|
2007-06-25 05:06:07 +08:00
|
|
|
die "'$path' already exists in the index"
|
|
|
|
|
2008-03-05 09:15:02 +08:00
|
|
|
# perhaps the path exists and is already a git repo, else clone it
|
|
|
|
if test -e "$path"
|
|
|
|
then
|
2008-07-08 10:36:40 +08:00
|
|
|
if test -d "$path"/.git -o -f "$path"/.git
|
2008-03-05 09:15:02 +08:00
|
|
|
then
|
|
|
|
echo "Adding existing repo at '$path' to the index"
|
|
|
|
else
|
|
|
|
die "'$path' already exists and is not a valid git repo"
|
|
|
|
fi
|
2008-07-10 09:05:41 +08:00
|
|
|
|
|
|
|
case "$repo" in
|
|
|
|
./*|../*)
|
|
|
|
url=$(resolve_relative_url "$repo") || exit
|
|
|
|
;;
|
|
|
|
*)
|
|
|
|
url="$repo"
|
|
|
|
;;
|
|
|
|
esac
|
|
|
|
git config submodule."$path".url "$url"
|
2008-03-05 09:15:02 +08:00
|
|
|
else
|
|
|
|
|
2009-05-05 03:30:01 +08:00
|
|
|
module_clone "$path" "$realrepo" "$reference" || exit
|
2009-04-19 11:42:07 +08:00
|
|
|
(
|
|
|
|
unset GIT_DIR
|
|
|
|
cd "$path" &&
|
|
|
|
# ash fails to wordsplit ${branch:+-b "$branch"...}
|
|
|
|
case "$branch" in
|
|
|
|
'') git checkout -f -q ;;
|
|
|
|
?*) git checkout -f -q -b "$branch" "origin/$branch" ;;
|
|
|
|
esac
|
|
|
|
) || die "Unable to checkout submodule '$path'"
|
2008-03-05 09:15:02 +08:00
|
|
|
fi
|
|
|
|
|
2007-06-25 05:06:07 +08:00
|
|
|
git add "$path" ||
|
|
|
|
die "Failed to add submodule '$path'"
|
|
|
|
|
2008-05-15 15:42:58 +08:00
|
|
|
git config -f .gitmodules submodule."$path".path "$path" &&
|
|
|
|
git config -f .gitmodules submodule."$path".url "$repo" &&
|
2007-06-25 05:06:07 +08:00
|
|
|
git add .gitmodules ||
|
|
|
|
die "Failed to register submodule '$path'"
|
|
|
|
}
|
|
|
|
|
2008-08-11 07:10:04 +08:00
|
|
|
#
|
|
|
|
# Execute an arbitrary command sequence in each checked out
|
|
|
|
# submodule
|
|
|
|
#
|
|
|
|
# $@ = command to execute
|
|
|
|
#
|
|
|
|
cmd_foreach()
|
|
|
|
{
|
2009-08-19 09:45:19 +08:00
|
|
|
# parse $args after "submodule ... foreach".
|
|
|
|
while test $# -ne 0
|
|
|
|
do
|
|
|
|
case "$1" in
|
|
|
|
-q|--quiet)
|
|
|
|
GIT_QUIET=1
|
|
|
|
;;
|
2009-08-19 09:45:22 +08:00
|
|
|
--recursive)
|
|
|
|
recursive=1
|
|
|
|
;;
|
2009-08-19 09:45:19 +08:00
|
|
|
-*)
|
|
|
|
usage
|
|
|
|
;;
|
|
|
|
*)
|
|
|
|
break
|
|
|
|
;;
|
|
|
|
esac
|
|
|
|
shift
|
|
|
|
done
|
|
|
|
|
2008-08-22 15:30:50 +08:00
|
|
|
module_list |
|
2008-08-11 07:10:04 +08:00
|
|
|
while read mode sha1 stage path
|
|
|
|
do
|
|
|
|
if test -e "$path"/.git
|
|
|
|
then
|
2009-08-19 09:45:22 +08:00
|
|
|
say "Entering '$prefix$path'"
|
2009-08-16 09:10:08 +08:00
|
|
|
name=$(module_name "$path")
|
2009-08-19 09:45:22 +08:00
|
|
|
(
|
|
|
|
prefix="$prefix$path/"
|
|
|
|
unset GIT_DIR
|
|
|
|
cd "$path" &&
|
|
|
|
eval "$@" &&
|
|
|
|
if test -n "$recursive"
|
|
|
|
then
|
|
|
|
cmd_foreach "--recursive" "$@"
|
|
|
|
fi
|
|
|
|
) ||
|
2008-08-11 07:10:04 +08:00
|
|
|
die "Stopping at '$path'; script returned non-zero status."
|
|
|
|
fi
|
|
|
|
done
|
|
|
|
}
|
|
|
|
|
2007-05-26 21:56:40 +08:00
|
|
|
#
|
2007-06-06 17:13:02 +08:00
|
|
|
# Register submodules in .git/config
|
2007-05-26 21:56:40 +08:00
|
|
|
#
|
|
|
|
# $@ = requested paths (default to all)
|
|
|
|
#
|
2008-01-15 18:35:49 +08:00
|
|
|
cmd_init()
|
2007-05-26 21:56:40 +08:00
|
|
|
{
|
2008-01-15 18:48:45 +08:00
|
|
|
# parse $args after "submodule ... init".
|
|
|
|
while test $# -ne 0
|
|
|
|
do
|
|
|
|
case "$1" in
|
|
|
|
-q|--quiet)
|
2009-06-17 06:33:00 +08:00
|
|
|
GIT_QUIET=1
|
2008-01-15 18:48:45 +08:00
|
|
|
;;
|
|
|
|
--)
|
|
|
|
shift
|
|
|
|
break
|
|
|
|
;;
|
|
|
|
-*)
|
|
|
|
usage
|
|
|
|
;;
|
|
|
|
*)
|
|
|
|
break
|
|
|
|
;;
|
|
|
|
esac
|
|
|
|
shift
|
|
|
|
done
|
|
|
|
|
2008-08-22 15:30:50 +08:00
|
|
|
module_list "$@" |
|
2007-05-26 21:56:40 +08:00
|
|
|
while read mode sha1 stage path
|
|
|
|
do
|
2007-06-06 17:13:02 +08:00
|
|
|
# Skip already registered paths
|
2007-06-12 03:12:24 +08:00
|
|
|
name=$(module_name "$path") || exit
|
2007-07-03 13:52:14 +08:00
|
|
|
url=$(git config submodule."$name".url)
|
2007-06-06 17:13:02 +08:00
|
|
|
test -z "$url" || continue
|
2007-05-26 21:56:40 +08:00
|
|
|
|
2008-05-15 15:42:58 +08:00
|
|
|
url=$(git config -f .gitmodules submodule."$name".url)
|
2007-05-26 21:56:40 +08:00
|
|
|
test -z "$url" &&
|
2007-06-12 03:12:24 +08:00
|
|
|
die "No url found for submodule path '$path' in .gitmodules"
|
2007-05-26 21:56:40 +08:00
|
|
|
|
2007-09-24 10:19:42 +08:00
|
|
|
# Possibly a url relative to parent
|
|
|
|
case "$url" in
|
|
|
|
./*|../*)
|
2008-06-15 01:09:41 +08:00
|
|
|
url=$(resolve_relative_url "$url") || exit
|
2007-09-24 10:19:42 +08:00
|
|
|
;;
|
|
|
|
esac
|
|
|
|
|
2007-07-03 13:52:14 +08:00
|
|
|
git config submodule."$name".url "$url" ||
|
2007-06-12 03:12:24 +08:00
|
|
|
die "Failed to register url for submodule path '$path'"
|
2007-05-26 21:56:40 +08:00
|
|
|
|
Rename submodule.<name>.rebase to submodule.<name>.update
The addition of "submodule.<name>.rebase" demonstrates the usefulness of
alternatives to the default behaviour of "git submodule update". However,
by naming the config variable "submodule.<name>.rebase", and making it a
boolean choice, we are artificially constraining future git versions that
may want to add _more_ alternatives than just "rebase".
Therefore, while "submodule.<name>.rebase" is not yet in a stable git
release, future-proof it, by changing it from
submodule.<name>.rebase = true/false
to
submodule.<name>.update = rebase/checkout
where "checkout" specifies the default behaviour of "git submodule update"
(checking out the new commit to a detached HEAD), and "rebase" specifies
the --rebase behaviour (where the current local branch in the submodule is
rebase onto the new commit). Thus .update == checkout is equivalent to
.rebase == false, and .update == rebase is equivalent to .rebase == true.
Finally, leaving .update unset is equivalent to leaving .rebase unset.
In future git versions, other alternatives to "git submodule update"
behaviour can be included by adding them to the list of allowable values
for the submodule.<name>.update variable.
Signed-off-by: Johan Herland <johan@herland.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-06-03 14:27:06 +08:00
|
|
|
upd="$(git config -f .gitmodules submodule."$name".update)"
|
|
|
|
test -z "$upd" ||
|
|
|
|
git config submodule."$name".update "$upd" ||
|
|
|
|
die "Failed to register update mode for submodule path '$path'"
|
2009-04-24 07:06:38 +08:00
|
|
|
|
2007-06-12 03:12:24 +08:00
|
|
|
say "Submodule '$name' ($url) registered for path '$path'"
|
2007-05-26 21:56:40 +08:00
|
|
|
done
|
|
|
|
}
|
|
|
|
|
|
|
|
#
|
2007-06-06 17:13:02 +08:00
|
|
|
# Update each submodule path to correct revision, using clone and checkout as needed
|
2007-05-26 21:56:40 +08:00
|
|
|
#
|
|
|
|
# $@ = requested paths (default to all)
|
|
|
|
#
|
2008-01-15 18:35:49 +08:00
|
|
|
cmd_update()
|
2007-05-26 21:56:40 +08:00
|
|
|
{
|
2008-01-15 18:48:45 +08:00
|
|
|
# parse $args after "submodule ... update".
|
2009-08-19 09:45:23 +08:00
|
|
|
orig_args="$@"
|
2008-01-15 18:48:45 +08:00
|
|
|
while test $# -ne 0
|
|
|
|
do
|
|
|
|
case "$1" in
|
|
|
|
-q|--quiet)
|
2008-07-22 02:15:59 +08:00
|
|
|
shift
|
2009-06-17 06:33:00 +08:00
|
|
|
GIT_QUIET=1
|
2008-01-15 18:48:45 +08:00
|
|
|
;;
|
2008-05-16 18:23:03 +08:00
|
|
|
-i|--init)
|
2009-05-05 03:30:01 +08:00
|
|
|
init=1
|
2008-05-16 18:23:03 +08:00
|
|
|
shift
|
|
|
|
;;
|
2009-02-06 06:18:32 +08:00
|
|
|
-N|--no-fetch)
|
|
|
|
shift
|
|
|
|
nofetch=1
|
|
|
|
;;
|
2009-04-24 07:06:38 +08:00
|
|
|
-r|--rebase)
|
|
|
|
shift
|
Rename submodule.<name>.rebase to submodule.<name>.update
The addition of "submodule.<name>.rebase" demonstrates the usefulness of
alternatives to the default behaviour of "git submodule update". However,
by naming the config variable "submodule.<name>.rebase", and making it a
boolean choice, we are artificially constraining future git versions that
may want to add _more_ alternatives than just "rebase".
Therefore, while "submodule.<name>.rebase" is not yet in a stable git
release, future-proof it, by changing it from
submodule.<name>.rebase = true/false
to
submodule.<name>.update = rebase/checkout
where "checkout" specifies the default behaviour of "git submodule update"
(checking out the new commit to a detached HEAD), and "rebase" specifies
the --rebase behaviour (where the current local branch in the submodule is
rebase onto the new commit). Thus .update == checkout is equivalent to
.rebase == false, and .update == rebase is equivalent to .rebase == true.
Finally, leaving .update unset is equivalent to leaving .rebase unset.
In future git versions, other alternatives to "git submodule update"
behaviour can be included by adding them to the list of allowable values
for the submodule.<name>.update variable.
Signed-off-by: Johan Herland <johan@herland.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-06-03 14:27:06 +08:00
|
|
|
update="rebase"
|
2009-04-24 07:06:38 +08:00
|
|
|
;;
|
2009-05-05 03:30:01 +08:00
|
|
|
--reference)
|
|
|
|
case "$2" in '') usage ;; esac
|
|
|
|
reference="--reference=$2"
|
|
|
|
shift 2
|
|
|
|
;;
|
|
|
|
--reference=*)
|
|
|
|
reference="$1"
|
|
|
|
shift
|
|
|
|
;;
|
2009-06-03 06:59:12 +08:00
|
|
|
-m|--merge)
|
|
|
|
shift
|
|
|
|
update="merge"
|
|
|
|
;;
|
2009-08-19 09:45:23 +08:00
|
|
|
--recursive)
|
|
|
|
shift
|
|
|
|
recursive=1
|
|
|
|
;;
|
2008-01-15 18:48:45 +08:00
|
|
|
--)
|
|
|
|
shift
|
|
|
|
break
|
|
|
|
;;
|
|
|
|
-*)
|
|
|
|
usage
|
|
|
|
;;
|
|
|
|
*)
|
|
|
|
break
|
|
|
|
;;
|
|
|
|
esac
|
|
|
|
done
|
|
|
|
|
2009-05-05 03:30:01 +08:00
|
|
|
if test -n "$init"
|
|
|
|
then
|
|
|
|
cmd_init "--" "$@" || return
|
|
|
|
fi
|
|
|
|
|
2008-08-22 15:30:50 +08:00
|
|
|
module_list "$@" |
|
2007-05-26 21:56:40 +08:00
|
|
|
while read mode sha1 stage path
|
|
|
|
do
|
2007-06-12 03:12:24 +08:00
|
|
|
name=$(module_name "$path") || exit
|
2007-07-03 13:52:14 +08:00
|
|
|
url=$(git config submodule."$name".url)
|
Rename submodule.<name>.rebase to submodule.<name>.update
The addition of "submodule.<name>.rebase" demonstrates the usefulness of
alternatives to the default behaviour of "git submodule update". However,
by naming the config variable "submodule.<name>.rebase", and making it a
boolean choice, we are artificially constraining future git versions that
may want to add _more_ alternatives than just "rebase".
Therefore, while "submodule.<name>.rebase" is not yet in a stable git
release, future-proof it, by changing it from
submodule.<name>.rebase = true/false
to
submodule.<name>.update = rebase/checkout
where "checkout" specifies the default behaviour of "git submodule update"
(checking out the new commit to a detached HEAD), and "rebase" specifies
the --rebase behaviour (where the current local branch in the submodule is
rebase onto the new commit). Thus .update == checkout is equivalent to
.rebase == false, and .update == rebase is equivalent to .rebase == true.
Finally, leaving .update unset is equivalent to leaving .rebase unset.
In future git versions, other alternatives to "git submodule update"
behaviour can be included by adding them to the list of allowable values
for the submodule.<name>.update variable.
Signed-off-by: Johan Herland <johan@herland.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-06-03 14:27:06 +08:00
|
|
|
update_module=$(git config submodule."$name".update)
|
2007-06-06 17:13:02 +08:00
|
|
|
if test -z "$url"
|
2007-05-26 21:56:40 +08:00
|
|
|
then
|
|
|
|
# Only mention uninitialized submodules when its
|
|
|
|
# path have been specified
|
|
|
|
test "$#" != "0" &&
|
2008-11-12 05:09:16 +08:00
|
|
|
say "Submodule path '$path' not initialized" &&
|
2008-05-16 18:23:03 +08:00
|
|
|
say "Maybe you want to use 'update --init'?"
|
2007-06-06 17:13:02 +08:00
|
|
|
continue
|
|
|
|
fi
|
|
|
|
|
2008-02-21 06:13:15 +08:00
|
|
|
if ! test -d "$path"/.git -o -f "$path"/.git
|
2007-06-06 17:13:02 +08:00
|
|
|
then
|
2009-05-05 03:30:01 +08:00
|
|
|
module_clone "$path" "$url" "$reference"|| exit
|
2007-06-12 03:12:22 +08:00
|
|
|
subsha1=
|
|
|
|
else
|
2007-12-05 06:45:16 +08:00
|
|
|
subsha1=$(unset GIT_DIR; cd "$path" &&
|
2007-07-03 13:52:14 +08:00
|
|
|
git rev-parse --verify HEAD) ||
|
2007-06-12 03:12:24 +08:00
|
|
|
die "Unable to find current revision in submodule path '$path'"
|
2007-05-26 21:56:40 +08:00
|
|
|
fi
|
2007-06-06 17:13:02 +08:00
|
|
|
|
Rename submodule.<name>.rebase to submodule.<name>.update
The addition of "submodule.<name>.rebase" demonstrates the usefulness of
alternatives to the default behaviour of "git submodule update". However,
by naming the config variable "submodule.<name>.rebase", and making it a
boolean choice, we are artificially constraining future git versions that
may want to add _more_ alternatives than just "rebase".
Therefore, while "submodule.<name>.rebase" is not yet in a stable git
release, future-proof it, by changing it from
submodule.<name>.rebase = true/false
to
submodule.<name>.update = rebase/checkout
where "checkout" specifies the default behaviour of "git submodule update"
(checking out the new commit to a detached HEAD), and "rebase" specifies
the --rebase behaviour (where the current local branch in the submodule is
rebase onto the new commit). Thus .update == checkout is equivalent to
.rebase == false, and .update == rebase is equivalent to .rebase == true.
Finally, leaving .update unset is equivalent to leaving .rebase unset.
In future git versions, other alternatives to "git submodule update"
behaviour can be included by adding them to the list of allowable values
for the submodule.<name>.update variable.
Signed-off-by: Johan Herland <johan@herland.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-06-03 14:27:06 +08:00
|
|
|
if ! test -z "$update"
|
2009-04-24 07:06:38 +08:00
|
|
|
then
|
Rename submodule.<name>.rebase to submodule.<name>.update
The addition of "submodule.<name>.rebase" demonstrates the usefulness of
alternatives to the default behaviour of "git submodule update". However,
by naming the config variable "submodule.<name>.rebase", and making it a
boolean choice, we are artificially constraining future git versions that
may want to add _more_ alternatives than just "rebase".
Therefore, while "submodule.<name>.rebase" is not yet in a stable git
release, future-proof it, by changing it from
submodule.<name>.rebase = true/false
to
submodule.<name>.update = rebase/checkout
where "checkout" specifies the default behaviour of "git submodule update"
(checking out the new commit to a detached HEAD), and "rebase" specifies
the --rebase behaviour (where the current local branch in the submodule is
rebase onto the new commit). Thus .update == checkout is equivalent to
.rebase == false, and .update == rebase is equivalent to .rebase == true.
Finally, leaving .update unset is equivalent to leaving .rebase unset.
In future git versions, other alternatives to "git submodule update"
behaviour can be included by adding them to the list of allowable values
for the submodule.<name>.update variable.
Signed-off-by: Johan Herland <johan@herland.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-06-03 14:27:06 +08:00
|
|
|
update_module=$update
|
2009-04-24 07:06:38 +08:00
|
|
|
fi
|
|
|
|
|
2007-05-26 21:56:40 +08:00
|
|
|
if test "$subsha1" != "$sha1"
|
|
|
|
then
|
2008-09-26 23:33:23 +08:00
|
|
|
force=
|
|
|
|
if test -z "$subsha1"
|
|
|
|
then
|
|
|
|
force="-f"
|
|
|
|
fi
|
2009-02-06 06:18:32 +08:00
|
|
|
|
|
|
|
if test -z "$nofetch"
|
|
|
|
then
|
|
|
|
(unset GIT_DIR; cd "$path" &&
|
|
|
|
git-fetch) ||
|
|
|
|
die "Unable to fetch in submodule path '$path'"
|
|
|
|
fi
|
|
|
|
|
Rename submodule.<name>.rebase to submodule.<name>.update
The addition of "submodule.<name>.rebase" demonstrates the usefulness of
alternatives to the default behaviour of "git submodule update". However,
by naming the config variable "submodule.<name>.rebase", and making it a
boolean choice, we are artificially constraining future git versions that
may want to add _more_ alternatives than just "rebase".
Therefore, while "submodule.<name>.rebase" is not yet in a stable git
release, future-proof it, by changing it from
submodule.<name>.rebase = true/false
to
submodule.<name>.update = rebase/checkout
where "checkout" specifies the default behaviour of "git submodule update"
(checking out the new commit to a detached HEAD), and "rebase" specifies
the --rebase behaviour (where the current local branch in the submodule is
rebase onto the new commit). Thus .update == checkout is equivalent to
.rebase == false, and .update == rebase is equivalent to .rebase == true.
Finally, leaving .update unset is equivalent to leaving .rebase unset.
In future git versions, other alternatives to "git submodule update"
behaviour can be included by adding them to the list of allowable values
for the submodule.<name>.update variable.
Signed-off-by: Johan Herland <johan@herland.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-06-03 14:27:06 +08:00
|
|
|
case "$update_module" in
|
|
|
|
rebase)
|
|
|
|
command="git rebase"
|
2009-04-24 07:06:38 +08:00
|
|
|
action="rebase"
|
|
|
|
msg="rebased onto"
|
Rename submodule.<name>.rebase to submodule.<name>.update
The addition of "submodule.<name>.rebase" demonstrates the usefulness of
alternatives to the default behaviour of "git submodule update". However,
by naming the config variable "submodule.<name>.rebase", and making it a
boolean choice, we are artificially constraining future git versions that
may want to add _more_ alternatives than just "rebase".
Therefore, while "submodule.<name>.rebase" is not yet in a stable git
release, future-proof it, by changing it from
submodule.<name>.rebase = true/false
to
submodule.<name>.update = rebase/checkout
where "checkout" specifies the default behaviour of "git submodule update"
(checking out the new commit to a detached HEAD), and "rebase" specifies
the --rebase behaviour (where the current local branch in the submodule is
rebase onto the new commit). Thus .update == checkout is equivalent to
.rebase == false, and .update == rebase is equivalent to .rebase == true.
Finally, leaving .update unset is equivalent to leaving .rebase unset.
In future git versions, other alternatives to "git submodule update"
behaviour can be included by adding them to the list of allowable values
for the submodule.<name>.update variable.
Signed-off-by: Johan Herland <johan@herland.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-06-03 14:27:06 +08:00
|
|
|
;;
|
2009-06-03 06:59:12 +08:00
|
|
|
merge)
|
|
|
|
command="git merge"
|
|
|
|
action="merge"
|
|
|
|
msg="merged in"
|
|
|
|
;;
|
Rename submodule.<name>.rebase to submodule.<name>.update
The addition of "submodule.<name>.rebase" demonstrates the usefulness of
alternatives to the default behaviour of "git submodule update". However,
by naming the config variable "submodule.<name>.rebase", and making it a
boolean choice, we are artificially constraining future git versions that
may want to add _more_ alternatives than just "rebase".
Therefore, while "submodule.<name>.rebase" is not yet in a stable git
release, future-proof it, by changing it from
submodule.<name>.rebase = true/false
to
submodule.<name>.update = rebase/checkout
where "checkout" specifies the default behaviour of "git submodule update"
(checking out the new commit to a detached HEAD), and "rebase" specifies
the --rebase behaviour (where the current local branch in the submodule is
rebase onto the new commit). Thus .update == checkout is equivalent to
.rebase == false, and .update == rebase is equivalent to .rebase == true.
Finally, leaving .update unset is equivalent to leaving .rebase unset.
In future git versions, other alternatives to "git submodule update"
behaviour can be included by adding them to the list of allowable values
for the submodule.<name>.update variable.
Signed-off-by: Johan Herland <johan@herland.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-06-03 14:27:06 +08:00
|
|
|
*)
|
|
|
|
command="git checkout $force -q"
|
2009-04-24 07:06:38 +08:00
|
|
|
action="checkout"
|
|
|
|
msg="checked out"
|
Rename submodule.<name>.rebase to submodule.<name>.update
The addition of "submodule.<name>.rebase" demonstrates the usefulness of
alternatives to the default behaviour of "git submodule update". However,
by naming the config variable "submodule.<name>.rebase", and making it a
boolean choice, we are artificially constraining future git versions that
may want to add _more_ alternatives than just "rebase".
Therefore, while "submodule.<name>.rebase" is not yet in a stable git
release, future-proof it, by changing it from
submodule.<name>.rebase = true/false
to
submodule.<name>.update = rebase/checkout
where "checkout" specifies the default behaviour of "git submodule update"
(checking out the new commit to a detached HEAD), and "rebase" specifies
the --rebase behaviour (where the current local branch in the submodule is
rebase onto the new commit). Thus .update == checkout is equivalent to
.rebase == false, and .update == rebase is equivalent to .rebase == true.
Finally, leaving .update unset is equivalent to leaving .rebase unset.
In future git versions, other alternatives to "git submodule update"
behaviour can be included by adding them to the list of allowable values
for the submodule.<name>.update variable.
Signed-off-by: Johan Herland <johan@herland.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-06-03 14:27:06 +08:00
|
|
|
;;
|
|
|
|
esac
|
2007-05-26 21:56:40 +08:00
|
|
|
|
2009-04-24 07:06:38 +08:00
|
|
|
(unset GIT_DIR; cd "$path" && $command "$sha1") ||
|
|
|
|
die "Unable to $action '$sha1' in submodule path '$path'"
|
|
|
|
say "Submodule path '$path': $msg '$sha1'"
|
2007-05-26 21:56:40 +08:00
|
|
|
fi
|
2009-08-19 09:45:23 +08:00
|
|
|
|
|
|
|
if test -n "$recursive"
|
|
|
|
then
|
|
|
|
(unset GIT_DIR; cd "$path" && cmd_update $orig_args) ||
|
|
|
|
die "Failed to recurse into submodule path '$path'"
|
|
|
|
fi
|
2007-05-26 21:56:40 +08:00
|
|
|
done
|
|
|
|
}
|
|
|
|
|
2007-06-27 07:40:58 +08:00
|
|
|
set_name_rev () {
|
|
|
|
revname=$( (
|
2007-12-05 06:45:16 +08:00
|
|
|
unset GIT_DIR
|
2007-06-27 07:40:58 +08:00
|
|
|
cd "$1" && {
|
2007-07-03 13:52:14 +08:00
|
|
|
git describe "$2" 2>/dev/null ||
|
|
|
|
git describe --tags "$2" 2>/dev/null ||
|
2008-04-15 10:48:06 +08:00
|
|
|
git describe --contains "$2" 2>/dev/null ||
|
|
|
|
git describe --all --always "$2"
|
2007-06-27 07:40:58 +08:00
|
|
|
}
|
|
|
|
) )
|
|
|
|
test -z "$revname" || revname=" ($revname)"
|
|
|
|
}
|
2008-03-11 21:52:15 +08:00
|
|
|
#
|
|
|
|
# Show commit summary for submodules in index or working tree
|
|
|
|
#
|
|
|
|
# If '--cached' is given, show summary between index and given commit,
|
|
|
|
# or between working tree and given commit
|
|
|
|
#
|
|
|
|
# $@ = [commit (default 'HEAD'),] requested paths (default all)
|
|
|
|
#
|
|
|
|
cmd_summary() {
|
2008-03-11 21:52:17 +08:00
|
|
|
summary_limit=-1
|
2008-04-12 23:05:31 +08:00
|
|
|
for_status=
|
2009-08-14 03:32:50 +08:00
|
|
|
diff_cmd=diff-index
|
2008-03-11 21:52:17 +08:00
|
|
|
|
2008-03-11 21:52:15 +08:00
|
|
|
# parse $args after "submodule ... summary".
|
|
|
|
while test $# -ne 0
|
|
|
|
do
|
|
|
|
case "$1" in
|
|
|
|
--cached)
|
|
|
|
cached="$1"
|
|
|
|
;;
|
2009-08-14 03:32:50 +08:00
|
|
|
--files)
|
|
|
|
files="$1"
|
|
|
|
;;
|
2008-04-12 23:05:31 +08:00
|
|
|
--for-status)
|
|
|
|
for_status="$1"
|
|
|
|
;;
|
2008-03-11 21:52:17 +08:00
|
|
|
-n|--summary-limit)
|
|
|
|
if summary_limit=$(($2 + 0)) 2>/dev/null && test "$summary_limit" = "$2"
|
|
|
|
then
|
|
|
|
:
|
|
|
|
else
|
|
|
|
usage
|
|
|
|
fi
|
|
|
|
shift
|
|
|
|
;;
|
2008-03-11 21:52:15 +08:00
|
|
|
--)
|
|
|
|
shift
|
|
|
|
break
|
|
|
|
;;
|
|
|
|
-*)
|
|
|
|
usage
|
|
|
|
;;
|
|
|
|
*)
|
|
|
|
break
|
|
|
|
;;
|
|
|
|
esac
|
|
|
|
shift
|
|
|
|
done
|
2007-06-27 07:40:58 +08:00
|
|
|
|
2008-03-11 21:52:17 +08:00
|
|
|
test $summary_limit = 0 && return
|
|
|
|
|
2008-12-03 21:26:52 +08:00
|
|
|
if rev=$(git rev-parse -q --verify "$1^0")
|
2008-03-11 21:52:15 +08:00
|
|
|
then
|
|
|
|
head=$rev
|
|
|
|
shift
|
|
|
|
else
|
|
|
|
head=HEAD
|
|
|
|
fi
|
|
|
|
|
2009-08-14 03:32:50 +08:00
|
|
|
if [ -n "$files" ]
|
|
|
|
then
|
|
|
|
test -n "$cached" &&
|
|
|
|
die "--cached cannot be used with --files"
|
|
|
|
diff_cmd=diff-files
|
|
|
|
head=
|
|
|
|
fi
|
|
|
|
|
2008-03-11 21:52:15 +08:00
|
|
|
cd_to_toplevel
|
|
|
|
# Get modified modules cared by user
|
2009-08-14 03:32:50 +08:00
|
|
|
modules=$(git $diff_cmd $cached --raw $head -- "$@" |
|
2009-11-24 07:56:32 +08:00
|
|
|
sane_egrep '^:([0-7]* )?160000' |
|
2008-03-11 21:52:15 +08:00
|
|
|
while read mod_src mod_dst sha1_src sha1_dst status name
|
|
|
|
do
|
|
|
|
# Always show modules deleted or type-changed (blob<->module)
|
|
|
|
test $status = D -o $status = T && echo "$name" && continue
|
|
|
|
# Also show added or modified modules which are checked out
|
|
|
|
GIT_DIR="$name/.git" git-rev-parse --git-dir >/dev/null 2>&1 &&
|
|
|
|
echo "$name"
|
|
|
|
done
|
|
|
|
)
|
2008-03-11 21:52:16 +08:00
|
|
|
|
2008-04-12 23:05:31 +08:00
|
|
|
test -z "$modules" && return
|
|
|
|
|
2009-08-14 03:32:50 +08:00
|
|
|
git $diff_cmd $cached --raw $head -- $modules |
|
2009-11-24 07:56:32 +08:00
|
|
|
sane_egrep '^:([0-7]* )?160000' |
|
2008-03-11 21:52:16 +08:00
|
|
|
cut -c2- |
|
|
|
|
while read mod_src mod_dst sha1_src sha1_dst status name
|
|
|
|
do
|
|
|
|
if test -z "$cached" &&
|
|
|
|
test $sha1_dst = 0000000000000000000000000000000000000000
|
|
|
|
then
|
|
|
|
case "$mod_dst" in
|
|
|
|
160000)
|
|
|
|
sha1_dst=$(GIT_DIR="$name/.git" git rev-parse HEAD)
|
|
|
|
;;
|
|
|
|
100644 | 100755 | 120000)
|
|
|
|
sha1_dst=$(git hash-object $name)
|
|
|
|
;;
|
|
|
|
000000)
|
|
|
|
;; # removed
|
|
|
|
*)
|
|
|
|
# unexpected type
|
|
|
|
echo >&2 "unexpected mode $mod_dst"
|
|
|
|
continue ;;
|
|
|
|
esac
|
|
|
|
fi
|
|
|
|
missing_src=
|
|
|
|
missing_dst=
|
|
|
|
|
|
|
|
test $mod_src = 160000 &&
|
2008-12-03 21:26:52 +08:00
|
|
|
! GIT_DIR="$name/.git" git-rev-parse -q --verify $sha1_src^0 >/dev/null &&
|
2008-03-11 21:52:16 +08:00
|
|
|
missing_src=t
|
|
|
|
|
|
|
|
test $mod_dst = 160000 &&
|
2008-12-03 21:26:52 +08:00
|
|
|
! GIT_DIR="$name/.git" git-rev-parse -q --verify $sha1_dst^0 >/dev/null &&
|
2008-03-11 21:52:16 +08:00
|
|
|
missing_dst=t
|
2007-06-27 07:40:58 +08:00
|
|
|
|
2008-03-11 21:52:16 +08:00
|
|
|
total_commits=
|
|
|
|
case "$missing_src,$missing_dst" in
|
|
|
|
t,)
|
|
|
|
errmsg=" Warn: $name doesn't contain commit $sha1_src"
|
|
|
|
;;
|
|
|
|
,t)
|
|
|
|
errmsg=" Warn: $name doesn't contain commit $sha1_dst"
|
|
|
|
;;
|
|
|
|
t,t)
|
|
|
|
errmsg=" Warn: $name doesn't contain commits $sha1_src and $sha1_dst"
|
|
|
|
;;
|
|
|
|
*)
|
|
|
|
errmsg=
|
|
|
|
total_commits=$(
|
|
|
|
if test $mod_src = 160000 -a $mod_dst = 160000
|
|
|
|
then
|
|
|
|
range="$sha1_src...$sha1_dst"
|
|
|
|
elif test $mod_src = 160000
|
|
|
|
then
|
|
|
|
range=$sha1_src
|
|
|
|
else
|
|
|
|
range=$sha1_dst
|
|
|
|
fi
|
|
|
|
GIT_DIR="$name/.git" \
|
|
|
|
git log --pretty=oneline --first-parent $range | wc -l
|
|
|
|
)
|
2008-03-12 16:30:01 +08:00
|
|
|
total_commits=" ($(($total_commits + 0)))"
|
2008-03-11 21:52:16 +08:00
|
|
|
;;
|
|
|
|
esac
|
|
|
|
|
|
|
|
sha1_abbr_src=$(echo $sha1_src | cut -c1-7)
|
|
|
|
sha1_abbr_dst=$(echo $sha1_dst | cut -c1-7)
|
|
|
|
if test $status = T
|
|
|
|
then
|
|
|
|
if test $mod_dst = 160000
|
|
|
|
then
|
|
|
|
echo "* $name $sha1_abbr_src(blob)->$sha1_abbr_dst(submodule)$total_commits:"
|
|
|
|
else
|
|
|
|
echo "* $name $sha1_abbr_src(submodule)->$sha1_abbr_dst(blob)$total_commits:"
|
|
|
|
fi
|
|
|
|
else
|
|
|
|
echo "* $name $sha1_abbr_src...$sha1_abbr_dst$total_commits:"
|
|
|
|
fi
|
|
|
|
if test -n "$errmsg"
|
|
|
|
then
|
|
|
|
# Don't give error msg for modification whose dst is not submodule
|
|
|
|
# i.e. deleted or changed to blob
|
|
|
|
test $mod_dst = 160000 && echo "$errmsg"
|
|
|
|
else
|
|
|
|
if test $mod_src = 160000 -a $mod_dst = 160000
|
|
|
|
then
|
2008-03-11 21:52:17 +08:00
|
|
|
limit=
|
|
|
|
test $summary_limit -gt 0 && limit="-$summary_limit"
|
2008-03-11 21:52:16 +08:00
|
|
|
GIT_DIR="$name/.git" \
|
2008-03-11 21:52:17 +08:00
|
|
|
git log $limit --pretty='format: %m %s' \
|
2008-03-11 21:52:16 +08:00
|
|
|
--first-parent $sha1_src...$sha1_dst
|
|
|
|
elif test $mod_dst = 160000
|
|
|
|
then
|
|
|
|
GIT_DIR="$name/.git" \
|
|
|
|
git log --pretty='format: > %s' -1 $sha1_dst
|
|
|
|
else
|
|
|
|
GIT_DIR="$name/.git" \
|
|
|
|
git log --pretty='format: < %s' -1 $sha1_src
|
|
|
|
fi
|
|
|
|
echo
|
|
|
|
fi
|
|
|
|
echo
|
2008-04-12 23:05:31 +08:00
|
|
|
done |
|
|
|
|
if test -n "$for_status"; then
|
2010-01-18 03:42:31 +08:00
|
|
|
if [ -n "$files" ]; then
|
|
|
|
echo "# Submodules changed but not updated:"
|
|
|
|
else
|
|
|
|
echo "# Submodule changes to be committed:"
|
|
|
|
fi
|
2008-04-12 23:05:31 +08:00
|
|
|
echo "#"
|
|
|
|
sed -e 's|^|# |' -e 's|^# $|#|'
|
|
|
|
else
|
|
|
|
cat
|
|
|
|
fi
|
2008-03-11 21:52:15 +08:00
|
|
|
}
|
2007-05-26 21:56:40 +08:00
|
|
|
#
|
2007-06-12 03:12:24 +08:00
|
|
|
# List all submodules, prefixed with:
|
2007-05-26 21:56:40 +08:00
|
|
|
# - submodule not initialized
|
|
|
|
# + different revision checked out
|
|
|
|
#
|
|
|
|
# If --cached was specified the revision in the index will be printed
|
|
|
|
# instead of the currently checked out revision.
|
|
|
|
#
|
|
|
|
# $@ = requested paths (default to all)
|
|
|
|
#
|
2008-01-15 18:35:49 +08:00
|
|
|
cmd_status()
|
2007-05-26 21:56:40 +08:00
|
|
|
{
|
2008-01-15 18:48:45 +08:00
|
|
|
# parse $args after "submodule ... status".
|
2009-08-19 09:45:24 +08:00
|
|
|
orig_args="$@"
|
2008-01-15 18:48:45 +08:00
|
|
|
while test $# -ne 0
|
|
|
|
do
|
|
|
|
case "$1" in
|
|
|
|
-q|--quiet)
|
2009-06-17 06:33:00 +08:00
|
|
|
GIT_QUIET=1
|
2008-01-15 18:48:45 +08:00
|
|
|
;;
|
|
|
|
--cached)
|
|
|
|
cached=1
|
|
|
|
;;
|
2009-08-19 09:45:24 +08:00
|
|
|
--recursive)
|
|
|
|
recursive=1
|
|
|
|
;;
|
2008-01-15 18:48:45 +08:00
|
|
|
--)
|
|
|
|
shift
|
|
|
|
break
|
|
|
|
;;
|
|
|
|
-*)
|
|
|
|
usage
|
|
|
|
;;
|
|
|
|
*)
|
|
|
|
break
|
|
|
|
;;
|
|
|
|
esac
|
|
|
|
shift
|
|
|
|
done
|
|
|
|
|
2008-08-22 15:30:50 +08:00
|
|
|
module_list "$@" |
|
2007-05-26 21:56:40 +08:00
|
|
|
while read mode sha1 stage path
|
|
|
|
do
|
2007-06-12 03:12:24 +08:00
|
|
|
name=$(module_name "$path") || exit
|
2007-07-03 13:52:14 +08:00
|
|
|
url=$(git config submodule."$name".url)
|
2009-08-19 09:45:24 +08:00
|
|
|
displaypath="$prefix$path"
|
2008-02-21 06:13:15 +08:00
|
|
|
if test -z "$url" || ! test -d "$path"/.git -o -f "$path"/.git
|
2007-05-26 21:56:40 +08:00
|
|
|
then
|
2009-08-19 09:45:24 +08:00
|
|
|
say "-$sha1 $displaypath"
|
2007-05-26 21:56:40 +08:00
|
|
|
continue;
|
|
|
|
fi
|
2007-07-05 00:22:14 +08:00
|
|
|
set_name_rev "$path" "$sha1"
|
2007-05-26 21:56:40 +08:00
|
|
|
if git diff-files --quiet -- "$path"
|
|
|
|
then
|
2009-08-19 09:45:24 +08:00
|
|
|
say " $sha1 $displaypath$revname"
|
2007-05-26 21:56:40 +08:00
|
|
|
else
|
|
|
|
if test -z "$cached"
|
|
|
|
then
|
2007-12-05 06:45:16 +08:00
|
|
|
sha1=$(unset GIT_DIR; cd "$path" && git rev-parse --verify HEAD)
|
2007-07-05 00:22:14 +08:00
|
|
|
set_name_rev "$path" "$sha1"
|
2007-05-26 21:56:40 +08:00
|
|
|
fi
|
2009-08-19 09:45:24 +08:00
|
|
|
say "+$sha1 $displaypath$revname"
|
|
|
|
fi
|
|
|
|
|
|
|
|
if test -n "$recursive"
|
|
|
|
then
|
|
|
|
(
|
|
|
|
prefix="$displaypath/"
|
|
|
|
unset GIT_DIR
|
|
|
|
cd "$path" &&
|
|
|
|
cmd_status $orig_args
|
|
|
|
) ||
|
|
|
|
die "Failed to recurse into submodule path '$path'"
|
2007-05-26 21:56:40 +08:00
|
|
|
fi
|
|
|
|
done
|
|
|
|
}
|
2008-08-25 03:43:37 +08:00
|
|
|
#
|
|
|
|
# Sync remote urls for submodules
|
|
|
|
# This makes the value for remote.$remote.url match the value
|
|
|
|
# specified in .gitmodules.
|
|
|
|
#
|
|
|
|
cmd_sync()
|
|
|
|
{
|
|
|
|
while test $# -ne 0
|
|
|
|
do
|
|
|
|
case "$1" in
|
|
|
|
-q|--quiet)
|
2009-06-17 06:33:00 +08:00
|
|
|
GIT_QUIET=1
|
2008-08-25 03:43:37 +08:00
|
|
|
shift
|
|
|
|
;;
|
|
|
|
--)
|
|
|
|
shift
|
|
|
|
break
|
|
|
|
;;
|
|
|
|
-*)
|
|
|
|
usage
|
|
|
|
;;
|
|
|
|
*)
|
|
|
|
break
|
|
|
|
;;
|
|
|
|
esac
|
|
|
|
done
|
|
|
|
cd_to_toplevel
|
|
|
|
module_list "$@" |
|
|
|
|
while read mode sha1 stage path
|
|
|
|
do
|
|
|
|
name=$(module_name "$path")
|
|
|
|
url=$(git config -f .gitmodules --get submodule."$name".url)
|
2008-09-23 00:08:31 +08:00
|
|
|
|
|
|
|
# Possibly a url relative to parent
|
|
|
|
case "$url" in
|
|
|
|
./*|../*)
|
|
|
|
url=$(resolve_relative_url "$url") || exit
|
|
|
|
;;
|
|
|
|
esac
|
|
|
|
|
2008-08-25 03:43:37 +08:00
|
|
|
if test -e "$path"/.git
|
|
|
|
then
|
|
|
|
(
|
|
|
|
unset GIT_DIR
|
|
|
|
cd "$path"
|
|
|
|
remote=$(get_default_remote)
|
|
|
|
say "Synchronizing submodule url for '$name'"
|
|
|
|
git config remote."$remote".url "$url"
|
|
|
|
)
|
|
|
|
fi
|
|
|
|
done
|
|
|
|
}
|
2007-05-26 21:56:40 +08:00
|
|
|
|
2008-01-15 18:48:45 +08:00
|
|
|
# This loop parses the command line arguments to find the
|
|
|
|
# subcommand name to dispatch. Parsing of the subcommand specific
|
|
|
|
# options are primarily done by the subcommand implementations.
|
|
|
|
# Subcommand specific options such as --branch and --cached are
|
|
|
|
# parsed here as well, for backward compatibility.
|
|
|
|
|
|
|
|
while test $# != 0 && test -z "$command"
|
2007-05-26 21:56:40 +08:00
|
|
|
do
|
|
|
|
case "$1" in
|
2008-08-25 03:43:37 +08:00
|
|
|
add | foreach | init | update | status | summary | sync)
|
2008-01-15 18:48:45 +08:00
|
|
|
command=$1
|
2007-05-26 21:56:40 +08:00
|
|
|
;;
|
|
|
|
-q|--quiet)
|
2009-06-17 06:33:00 +08:00
|
|
|
GIT_QUIET=1
|
2007-05-26 21:56:40 +08:00
|
|
|
;;
|
2007-06-25 05:06:07 +08:00
|
|
|
-b|--branch)
|
|
|
|
case "$2" in
|
|
|
|
'')
|
|
|
|
usage
|
|
|
|
;;
|
|
|
|
esac
|
|
|
|
branch="$2"; shift
|
|
|
|
;;
|
2007-05-26 21:56:40 +08:00
|
|
|
--cached)
|
2008-03-11 21:52:15 +08:00
|
|
|
cached="$1"
|
2007-05-26 21:56:40 +08:00
|
|
|
;;
|
|
|
|
--)
|
|
|
|
break
|
|
|
|
;;
|
|
|
|
-*)
|
|
|
|
usage
|
|
|
|
;;
|
|
|
|
*)
|
|
|
|
break
|
|
|
|
;;
|
|
|
|
esac
|
|
|
|
shift
|
|
|
|
done
|
|
|
|
|
2008-01-15 18:48:45 +08:00
|
|
|
# No command word defaults to "status"
|
|
|
|
test -n "$command" || command=status
|
|
|
|
|
|
|
|
# "-b branch" is accepted only by "add"
|
|
|
|
if test -n "$branch" && test "$command" != add
|
|
|
|
then
|
2007-06-25 05:06:07 +08:00
|
|
|
usage
|
2008-01-15 18:48:45 +08:00
|
|
|
fi
|
|
|
|
|
2008-03-11 21:52:15 +08:00
|
|
|
# "--cached" is accepted only by "status" and "summary"
|
|
|
|
if test -n "$cached" && test "$command" != status -a "$command" != summary
|
2008-01-15 18:48:45 +08:00
|
|
|
then
|
2007-05-26 21:56:40 +08:00
|
|
|
usage
|
2008-01-15 18:48:45 +08:00
|
|
|
fi
|
|
|
|
|
|
|
|
"cmd_$command" "$@"
|