Skip to content

Commit

Permalink
Merge branch 'py/submodule'
Browse files Browse the repository at this point in the history
* py/submodule:
  git-submodule summary: fix that some "wc" flavors produce leading spaces
  git-submodule summary: test
  git-submodule summary: documentation
  git-submodule summary: limit summary size
  git-submodule summary: show commit summary
  git-submodule summary: code framework
  • Loading branch information
Junio C Hamano committed Mar 15, 2008
2 parents 1f1e125 + eed3559 commit 37bd6c5
Show file tree
Hide file tree
Showing 3 changed files with 386 additions and 8 deletions.
19 changes: 16 additions & 3 deletions Documentation/git-submodule.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ SYNOPSIS
'git-submodule' [--quiet] add [-b branch] [--] <repository> [<path>]
'git-submodule' [--quiet] status [--cached] [--] [<path>...]
'git-submodule' [--quiet] [init|update] [--] [<path>...]
'git-submodule' [--quiet] summary [--summary-limit <n>] [commit] [--] [<path>...]


COMMANDS
Expand Down Expand Up @@ -47,6 +48,11 @@ update::
checkout the commit specified in the index of the containing repository.
This will make the submodules HEAD be detached.

summary::
Show commit summary between the given commit (defaults to HEAD) and
working tree/index. For a submodule in question, a series of commits
in the submodule between the given super project commit and the
index or working tree (switched by --cached) are shown.

OPTIONS
-------
Expand All @@ -57,9 +63,16 @@ OPTIONS
Branch of repository to add as submodule.

--cached::
Display the SHA-1 stored in the index, not the SHA-1 of the currently
checked out submodule commit. This option is only valid for the
status command.
This option is only valid for status and summary commands. These
commands typically use the commit found in the submodule HEAD, but
with this option, the commit stored in the index is used instead.

-n, --summary-limit::
This option is only valid for the summary command.
Limit the summary size (number of commits shown in total).
Giving 0 will disable the summary; a negative number means unlimted
(the default). This limit only applies to modified submodules. The
size is always limited to 1 for added/deleted/typechanged submodules.

<path>::
Path to submodule(s). When specified this will restrict the command
Expand Down
180 changes: 175 additions & 5 deletions git-submodule.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
#
# Copyright (c) 2007 Lars Hjemli

USAGE='[--quiet] [--cached] [add <repo> [-b branch]|status|init|update] [--] [<path>...]'
USAGE="[--quiet] [--cached] \
[add <repo> [-b branch]|status|init|update|summary [-n|--summary-limit <n>] [<commit>]] \
[--] [<path>...]"
OPTIONS_SPEC=
. git-sh-setup
require_work_tree
Expand Down Expand Up @@ -330,7 +332,175 @@ set_name_rev () {
) )
test -z "$revname" || revname=" ($revname)"
}
#
# 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() {
summary_limit=-1

# parse $args after "submodule ... summary".
while test $# -ne 0
do
case "$1" in
--cached)
cached="$1"
;;
-n|--summary-limit)
if summary_limit=$(($2 + 0)) 2>/dev/null && test "$summary_limit" = "$2"
then
:
else
usage
fi
shift
;;
--)
shift
break
;;
-*)
usage
;;
*)
break
;;
esac
shift
done

test $summary_limit = 0 && return

if rev=$(git rev-parse --verify "$1^0" 2>/dev/null)
then
head=$rev
shift
else
head=HEAD
fi

cd_to_toplevel
# Get modified modules cared by user
modules=$(git diff-index $cached --raw $head -- "$@" |
grep -e '^:160000' -e '^:[0-7]* 160000' |
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
)

test -n "$modules" &&
git diff-index $cached --raw $head -- $modules |
grep -e '^:160000' -e '^:[0-7]* 160000' |
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 &&
! GIT_DIR="$name/.git" git-rev-parse --verify $sha1_src^0 >/dev/null 2>&1 &&
missing_src=t

test $mod_dst = 160000 &&
! GIT_DIR="$name/.git" git-rev-parse --verify $sha1_dst^0 >/dev/null 2>&1 &&
missing_dst=t

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
)
total_commits=" ($(($total_commits + 0)))"
;;
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
limit=
test $summary_limit -gt 0 && limit="-$summary_limit"
GIT_DIR="$name/.git" \
git log $limit --pretty='format: %m %s' \
--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
done
}
#
# List all submodules, prefixed with:
# - submodule not initialized
Expand Down Expand Up @@ -401,7 +571,7 @@ cmd_status()
while test $# != 0 && test -z "$command"
do
case "$1" in
add | init | update | status)
add | init | update | status | summary)
command=$1
;;
-q|--quiet)
Expand All @@ -416,7 +586,7 @@ do
branch="$2"; shift
;;
--cached)
cached=1
cached="$1"
;;
--)
break
Expand All @@ -440,8 +610,8 @@ then
usage
fi

# "--cached" is accepted only by "status"
if test -n "$cached" && test "$command" != status
# "--cached" is accepted only by "status" and "summary"
if test -n "$cached" && test "$command" != status -a "$command" != summary
then
usage
fi
Expand Down
Loading

0 comments on commit 37bd6c5

Please sign in to comment.