@@ -14,10 +14,13 @@ USAGE="[--quiet] add [-b <branch>] [-f|--force] [--name <name>] [--reference <re
1414 or: $dashless [--quiet] foreach [--recursive] <command>
1515 or: $dashless [--quiet] sync [--recursive] [--] [<path>...]"
1616OPTIONS_SPEC=
17+ SUBDIRECTORY_OK=Yes
1718. git-sh-setup
1819. git-sh-i18n
1920. git-parse-remote
2021require_work_tree
22+ wt_prefix=$( git rev-parse --show-prefix)
23+ cd_to_toplevel
2124
2225command=
2326branch=
@@ -106,12 +109,48 @@ resolve_relative_url ()
106109 echo " ${is_relative: +${up_path} }${remoteurl# ./ } "
107110}
108111
112+ # Resolve a path to be relative to another path. This is intended for
113+ # converting submodule paths when git-submodule is run in a subdirectory
114+ # and only handles paths where the directory separator is '/'.
115+ #
116+ # The output is the first argument as a path relative to the second argument,
117+ # which defaults to $wt_prefix if it is omitted.
118+ relative_path ()
119+ {
120+ local target curdir result
121+ target=$1
122+ curdir=${2-$wt_prefix }
123+ curdir=${curdir%/ }
124+ result=
125+
126+ while test -n " $curdir "
127+ do
128+ case " $target " in
129+ " $curdir /" * )
130+ target=${target# " $curdir " / }
131+ break
132+ ;;
133+ esac
134+
135+ result=" ${result} ../"
136+ if test " $curdir " = " ${curdir%/* } "
137+ then
138+ curdir=
139+ else
140+ curdir=" ${curdir%/* } "
141+ fi
142+ done
143+
144+ echo " $result$target "
145+ }
146+
109147#
110148# Get submodule info for registered submodules
111149# $@ = path to limit submodule list
112150#
113151module_list ()
114152{
153+ eval " set $( git rev-parse --sq --prefix " $wt_prefix " -- " $@ " ) "
115154 (
116155 git ls-files --error-unmatch --stage -- " $@ " ||
117156 echo " unmatched pathspec exists"
@@ -282,6 +321,7 @@ isnumber()
282321cmd_add ()
283322{
284323 # parse $args after "submodule ... add".
324+ reference_path=
285325 while test $# -ne 0
286326 do
287327 case " $1 " in
@@ -298,11 +338,11 @@ cmd_add()
298338 ;;
299339 --reference)
300340 case " $2 " in ' ' ) usage ;; esac
301- reference= " --reference= $2 "
341+ reference_path= $2
302342 shift
303343 ;;
304344 --reference=* )
305- reference =" $1 "
345+ reference_path =" ${1 # --reference=} "
306346 ;;
307347 --name)
308348 case " $2 " in ' ' ) usage ;; esac
@@ -323,6 +363,14 @@ cmd_add()
323363 shift
324364 done
325365
366+ if test -n " $reference_path "
367+ then
368+ is_absolute_path " $reference_path " ||
369+ reference_path=" $wt_prefix$reference_path "
370+
371+ reference=" --reference=$reference_path "
372+ fi
373+
326374 repo=$1
327375 sm_path=$2
328376
@@ -335,9 +383,14 @@ cmd_add()
335383 usage
336384 fi
337385
386+ is_absolute_path " $sm_path " || sm_path=" $wt_prefix$sm_path "
387+
338388 # assure repo is absolute or relative to parent
339389 case " $repo " in
340390 ./* |../* )
391+ test -z " $wt_prefix " ||
392+ die " $( gettext " Relative path can only be used from the toplevel of the working tree" ) "
393+
341394 # dereference source url relative to parent's url
342395 realrepo=$( resolve_relative_url " $repo " ) || exit
343396 ;;
@@ -471,21 +524,23 @@ cmd_foreach()
471524 die_if_unmatched " $mode "
472525 if test -e " $sm_path " /.git
473526 then
474- say " $( eval_gettext " Entering '\$ prefix\$ sm_path'" ) "
527+ displaypath=$( relative_path " $sm_path " )
528+ say " $( eval_gettext " Entering '\$ prefix\$ displaypath'" ) "
475529 name=$( module_name " $sm_path " )
476530 (
477531 prefix=" $prefix$sm_path /"
478532 clear_local_git_env
479- # we make $path available to scripts ...
480- path=$sm_path
481533 cd " $sm_path " &&
534+ sm_path=$( relative_path " $sm_path " ) &&
535+ # we make $path available to scripts ...
536+ path=$sm_path &&
482537 eval " $@ " &&
483538 if test -n " $recursive "
484539 then
485540 cmd_foreach " --recursive" " $@ "
486541 fi
487542 ) < & 3 3< & - ||
488- die " $( eval_gettext " Stopping at '\$ prefix\$ sm_path '; script returned non-zero status." ) "
543+ die " $( eval_gettext " Stopping at '\$ prefix\$ displaypath '; script returned non-zero status." ) "
489544 fi
490545 done
491546}
@@ -524,12 +579,14 @@ cmd_init()
524579 die_if_unmatched " $mode "
525580 name=$( module_name " $sm_path " ) || exit
526581
582+ displaypath=$( relative_path " $sm_path " )
583+
527584 # Copy url setting when it is not set yet
528585 if test -z " $( git config " submodule.$name .url" ) "
529586 then
530587 url=$( git config -f .gitmodules submodule." $name " .url)
531588 test -z " $url " &&
532- die " $( eval_gettext " No url found for submodule path '\$ sm_path ' in .gitmodules" ) "
589+ die " $( eval_gettext " No url found for submodule path '\$ displaypath ' in .gitmodules" ) "
533590
534591 # Possibly a url relative to parent
535592 case " $url " in
@@ -538,17 +595,17 @@ cmd_init()
538595 ;;
539596 esac
540597 git config submodule." $name " .url " $url " ||
541- die " $( eval_gettext " Failed to register url for submodule path '\$ sm_path '" ) "
598+ die " $( eval_gettext " Failed to register url for submodule path '\$ displaypath '" ) "
542599
543- say " $( eval_gettext " Submodule '\$ name' (\$ url) registered for path '\$ sm_path '" ) "
600+ say " $( eval_gettext " Submodule '\$ name' (\$ url) registered for path '\$ displaypath '" ) "
544601 fi
545602
546603 # Copy "update" setting when it is not set yet
547604 upd=" $( git config -f .gitmodules submodule." $name " .update) "
548605 test -z " $upd " ||
549606 test -n " $( git config submodule." $name " .update) " ||
550607 git config submodule." $name " .update " $upd " ||
551- die " $( eval_gettext " Failed to register update mode for submodule path '\$ sm_path '" ) "
608+ die " $( eval_gettext " Failed to register update mode for submodule path '\$ displaypath '" ) "
552609 done
553610}
554611
@@ -594,27 +651,29 @@ cmd_deinit()
594651 die_if_unmatched " $mode "
595652 name=$( module_name " $sm_path " ) || exit
596653
654+ displaypath=$( relative_path " $sm_path " )
655+
597656 # Remove the submodule work tree (unless the user already did it)
598657 if test -d " $sm_path "
599658 then
600659 # Protect submodules containing a .git directory
601660 if test -d " $sm_path /.git"
602661 then
603- echo >&2 " $( eval_gettext " Submodule work tree '\$ sm_path ' contains a .git directory" ) "
662+ echo >&2 " $( eval_gettext " Submodule work tree '\$ displaypath ' contains a .git directory" ) "
604663 die " $( eval_gettext " (use 'rm -rf' if you really want to remove it including all of its history)" ) "
605664 fi
606665
607666 if test -z " $force "
608667 then
609668 git rm -qn " $sm_path " ||
610- die " $( eval_gettext " Submodule work tree '\$ sm_path ' contains local modifications; use '-f' to discard them" ) "
669+ die " $( eval_gettext " Submodule work tree '\$ displaypath ' contains local modifications; use '-f' to discard them" ) "
611670 fi
612671 rm -rf " $sm_path " &&
613- say " $( eval_gettext " Cleared directory '\$ sm_path '" ) " ||
614- say " $( eval_gettext " Could not remove submodule work tree '\$ sm_path '" ) "
672+ say " $( eval_gettext " Cleared directory '\$ displaypath '" ) " ||
673+ say " $( eval_gettext " Could not remove submodule work tree '\$ displaypath '" ) "
615674 fi
616675
617- mkdir " $sm_path " || say " $( eval_gettext " Could not create empty submodule directory '\$ sm_path '" ) "
676+ mkdir " $sm_path " || say " $( eval_gettext " Could not create empty submodule directory '\$ displaypath '" ) "
618677
619678 # Remove the .git/config entries (unless the user already did it)
620679 if test -n " $( git config --get-regexp submodule." $name \." ) "
@@ -623,7 +682,7 @@ cmd_deinit()
623682 # the user later decides to init this submodule again
624683 url=$( git config submodule." $name " .url)
625684 git config --remove-section submodule." $name " 2> /dev/null &&
626- say " $( eval_gettext " Submodule '\$ name' (\$ url) unregistered for path '\$ sm_path '" ) "
685+ say " $( eval_gettext " Submodule '\$ name' (\$ url) unregistered for path '\$ displaypath '" ) "
627686 fi
628687 done
629688}
@@ -717,9 +776,11 @@ cmd_update()
717776 update_module=$( git config submodule." $name " .update)
718777 fi
719778
779+ displaypath=$( relative_path " $prefix$sm_path " )
780+
720781 if test " $update_module " = " none"
721782 then
722- echo " Skipping submodule '$prefix$sm_path '"
783+ echo " Skipping submodule '$displaypath '"
723784 continue
724785 fi
725786
@@ -728,7 +789,7 @@ cmd_update()
728789 # Only mention uninitialized submodules when its
729790 # path have been specified
730791 test " $# " ! = " 0" &&
731- say " $( eval_gettext " Submodule path '\$ prefix \$ sm_path ' not initialized
792+ say " $( eval_gettext " Submodule path '\$ displaypath ' not initialized
732793Maybe you want to use 'update --init'?" ) "
733794 continue
734795 fi
@@ -741,7 +802,7 @@ Maybe you want to use 'update --init'?")"
741802 else
742803 subsha1=$( clear_local_git_env; cd " $sm_path " &&
743804 git rev-parse --verify HEAD) ||
744- die " $( eval_gettext " Unable to find current revision in submodule path '\$ prefix \$ sm_path '" ) "
805+ die " $( eval_gettext " Unable to find current revision in submodule path '\$ displaypath '" ) "
745806 fi
746807
747808 if test -n " $remote "
@@ -774,7 +835,7 @@ Maybe you want to use 'update --init'?")"
774835 (clear_local_git_env; cd " $sm_path " &&
775836 ( (rev=$( git rev-list -n 1 $sha1 --not --all 2> /dev/null) &&
776837 test -z " $rev " ) || git-fetch)) ||
777- die " $( eval_gettext " Unable to fetch in submodule path '\$ prefix \$ sm_path '" ) "
838+ die " $( eval_gettext " Unable to fetch in submodule path '\$ displaypath '" ) "
778839 fi
779840
780841 # Is this something we just cloned?
@@ -788,20 +849,20 @@ Maybe you want to use 'update --init'?")"
788849 case " $update_module " in
789850 rebase)
790851 command=" git rebase"
791- die_msg=" $( eval_gettext " Unable to rebase '\$ sha1' in submodule path '\$ prefix \$ sm_path '" ) "
792- say_msg=" $( eval_gettext " Submodule path '\$ prefix \$ sm_path ': rebased into '\$ sha1'" ) "
852+ die_msg=" $( eval_gettext " Unable to rebase '\$ sha1' in submodule path '\$ displaypath '" ) "
853+ say_msg=" $( eval_gettext " Submodule path '\$ displaypath ': rebased into '\$ sha1'" ) "
793854 must_die_on_failure=yes
794855 ;;
795856 merge)
796857 command=" git merge"
797- die_msg=" $( eval_gettext " Unable to merge '\$ sha1' in submodule path '\$ prefix \$ sm_path '" ) "
798- say_msg=" $( eval_gettext " Submodule path '\$ prefix \$ sm_path ': merged in '\$ sha1'" ) "
858+ die_msg=" $( eval_gettext " Unable to merge '\$ sha1' in submodule path '\$ displaypath '" ) "
859+ say_msg=" $( eval_gettext " Submodule path '\$ displaypath ': merged in '\$ sha1'" ) "
799860 must_die_on_failure=yes
800861 ;;
801862 * )
802863 command=" git checkout $subforce -q"
803- die_msg=" $( eval_gettext " Unable to checkout '\$ sha1' in submodule path '\$ prefix \$ sm_path '" ) "
804- say_msg=" $( eval_gettext " Submodule path '\$ prefix \$ sm_path ': checked out '\$ sha1'" ) "
864+ die_msg=" $( eval_gettext " Unable to checkout '\$ sha1' in submodule path '\$ displaypath '" ) "
865+ say_msg=" $( eval_gettext " Submodule path '\$ displaypath ': checked out '\$ sha1'" ) "
805866 ;;
806867 esac
807868
@@ -828,7 +889,7 @@ Maybe you want to use 'update --init'?")"
828889 res=$?
829890 if test $res -gt 0
830891 then
831- die_msg=" $( eval_gettext " Failed to recurse into submodule path '\$ prefix \$ sm_path '" ) "
892+ die_msg=" $( eval_gettext " Failed to recurse into submodule path '\$ displaypath '" ) "
832893 if test $res -eq 1
833894 then
834895 err=" ${err} ;$die_msg "
@@ -942,6 +1003,7 @@ cmd_summary() {
9421003 fi
9431004
9441005 cd_to_toplevel
1006+ eval " set $( git rev-parse --sq --prefix " $wt_prefix " -- " $@ " ) "
9451007 # Get modified modules cared by user
9461008 modules=$( git $diff_cmd $cached --ignore-submodules=dirty --raw $head -- " $@ " |
9471009 sane_egrep ' ^:([0-7]* )?160000' |
@@ -991,16 +1053,18 @@ cmd_summary() {
9911053 ! GIT_DIR=" $name /.git" git-rev-parse -q --verify $sha1_dst ^0 > /dev/null &&
9921054 missing_dst=t
9931055
1056+ display_name=$( relative_path " $name " )
1057+
9941058 total_commits=
9951059 case " $missing_src ,$missing_dst " in
9961060 t,)
997- errmsg=" $( eval_gettext " Warn: \$ name doesn't contain commit \$ sha1_src" ) "
1061+ errmsg=" $( eval_gettext " Warn: \$ display_name doesn't contain commit \$ sha1_src" ) "
9981062 ;;
9991063 ,t)
1000- errmsg=" $( eval_gettext " Warn: \$ name doesn't contain commit \$ sha1_dst" ) "
1064+ errmsg=" $( eval_gettext " Warn: \$ display_name doesn't contain commit \$ sha1_dst" ) "
10011065 ;;
10021066 t,t)
1003- errmsg=" $( eval_gettext " Warn: \$ name doesn't contain commits \$ sha1_src and \$ sha1_dst" ) "
1067+ errmsg=" $( eval_gettext " Warn: \$ display_name doesn't contain commits \$ sha1_src and \$ sha1_dst" ) "
10041068 ;;
10051069 * )
10061070 errmsg=
@@ -1029,12 +1093,12 @@ cmd_summary() {
10291093 submodule=" $( gettext " submodule" ) "
10301094 if test $mod_dst = 160000
10311095 then
1032- echo " * $name $sha1_abbr_src ($blob )->$sha1_abbr_dst ($submodule )$total_commits :"
1096+ echo " * $display_name $sha1_abbr_src ($blob )->$sha1_abbr_dst ($submodule )$total_commits :"
10331097 else
1034- echo " * $name $sha1_abbr_src ($submodule )->$sha1_abbr_dst ($blob )$total_commits :"
1098+ echo " * $display_name $sha1_abbr_src ($submodule )->$sha1_abbr_dst ($blob )$total_commits :"
10351099 fi
10361100 else
1037- echo " * $name $sha1_abbr_src ...$sha1_abbr_dst$total_commits :"
1101+ echo " * $display_name $sha1_abbr_src ...$sha1_abbr_dst$total_commits :"
10381102 fi
10391103 if test -n " $errmsg "
10401104 then
@@ -1118,7 +1182,7 @@ cmd_status()
11181182 die_if_unmatched " $mode "
11191183 name=$( module_name " $sm_path " ) || exit
11201184 url=$( git config submodule." $name " .url)
1121- displaypath=" $prefix$sm_path "
1185+ displaypath=$( relative_path " $prefix$sm_path " )
11221186 if test " $stage " = U
11231187 then
11241188 say " U$sha1 $displaypath "
@@ -1213,7 +1277,8 @@ cmd_sync()
12131277
12141278 if git config " submodule.$name .url" > /dev/null 2> /dev/null
12151279 then
1216- say " $( eval_gettext " Synchronizing submodule url for '\$ prefix\$ sm_path'" ) "
1280+ displaypath=$( relative_path " $prefix$sm_path " )
1281+ say " $( eval_gettext " Synchronizing submodule url for '\$ displaypath'" ) "
12171282 git config submodule." $name " .url " $super_config_url "
12181283
12191284 if test -e " $sm_path " /.git
0 commit comments