]> gitweb.ps.run Git - ps-cgit/blob - submodules.sh
Use standard tree-diff function when showing diffstat for single commit
[ps-cgit] / submodules.sh
1 #!/bin/sh
2 #
3 # submodules.sh: init, update or list git submodules
4 #
5 # Copyright (C) 2006 Lars Hjemli
6 #
7 # Licensed under GNU General Public License v2
8 #   (see COPYING for full license text)
9 #
10
11
12 usage="submodules.sh [-i | -u] [-q] [--cached] [path...]"
13 init=
14 update=
15 quiet=
16 cached=
17
18
19 say()
20 {
21         if test -z "$quiet"
22         then
23                 echo -e "$@"
24         fi
25 }
26
27
28 die()
29 {
30         echo >&2 -e "$@"
31         exit 1
32 }
33
34
35
36 #
37 # Silently checkout specified submodule revision, return exit status of git-checkout
38 #
39 # $1 = local path
40 # $2 = requested sha1
41 #
42 module_checkout()
43 {
44         $(cd "$1" && git checkout "$2" 1>/dev/null 2>/dev/null)
45 }
46
47
48 #
49 # Find all (requested) submodules, run clone + checkout on missing paths
50 #
51 # $@ = requested paths (default to all)
52 #
53 modules_init()
54 {
55         git ls-files --stage -- $@ | grep -e '^160000 ' |
56         while read mode sha1 stage path
57         do
58                 test -d "$path/.git" && continue
59
60                 if test -d "$path"
61                 then
62                         rmdir "$path" 2>/dev/null ||
63                         die "Directory '$path' exist, but not as a submodule"
64                 fi
65
66                 test -e "$path" && die "A file already exist at path '$path'"
67
68                 url=$(sed -nre "s/^$path[ \t]+//p" .gitmodules)
69                 test -z "$url" && die "No url found for $path in .gitmodules"
70
71                 git clone "$url" "$path" || die "Clone of submodule '$path' failed"
72                 module_checkout "$path" "$sha1" || die "Checkout of submodule '$path' failed"
73                 say "Submodule '$path' initialized"
74         done
75 }
76
77 #
78 # Checkout correct revision of each initialized submodule
79 #
80 # $@ = requested paths (default to all)
81 #
82 modules_update()
83 {
84         git ls-files --stage -- $@ | grep -e '^160000 ' |
85         while read mode sha1 stage path
86         do
87                 if ! test -d "$path/.git"
88                 then
89                         say "Submodule '$path' not initialized"
90                         continue;
91                 fi
92                 subsha1=$(cd "$path" && git rev-parse --verify HEAD) ||
93                 die "Unable to find current revision of submodule '$path'"
94                 if test "$subsha1" != "$sha1"
95                 then
96                         module_checkout "$path" "$sha1" ||
97                         die "Unable to checkout revision $sha1 of submodule '$path'"
98                         say "Submodule '$path' reset to revision $sha1"
99                 fi
100         done
101 }
102
103 #
104 # List all registered submodules, prefixed with:
105 #  - submodule not initialized
106 #  + different version checked out
107 #
108 # If --cached was specified the revision in the index will be printed
109 # instead of the currently checked out revision.
110 #
111 # $@ = requested paths (default to all)
112 #
113 modules_list()
114 {
115         git ls-files --stage -- $@ | grep -e '^160000 ' |
116         while read mode sha1 stage path
117         do
118                 if ! test -d "$path/.git"
119                 then
120                         say "-$sha1 $path"
121                         continue;
122                 fi
123                 revname=$(cd "$path" && git describe $sha1)
124                 if git diff-files --quiet -- "$path"
125                 then
126                         say " $sha1 $path\t($revname)"
127                 else
128                         if test -z "$cached"
129                         then
130                                 sha1=$(cd "$path" && git rev-parse HEAD)
131                                 revname=$(cd "$path" && git describe HEAD)
132                         fi
133                         say "+$sha1 $path\t($revname)"
134                 fi
135         done
136 }
137
138
139 while case "$#" in 0) break ;; esac
140 do
141         case "$1" in
142         -i)
143                 init=1
144                 ;;
145         -u)
146                 update=1
147                 ;;
148         -q)
149                 quiet=1
150                 ;;
151         --cached)
152                 cached=1
153                 ;;
154         --)
155                 break
156                 ;;
157         -*)
158                 echo "Usage: $usage"
159                 exit 1
160                 ;;
161         --*)
162                 echo "Usage: $usage"
163                 exit 1
164                 ;;
165         *)
166                 break
167                 ;;
168         esac
169         shift
170 done
171
172
173 if test "$init" = "1"
174 then
175         modules_init $@
176 elif test "$update" = "1"
177 then
178         modules_update $@
179 else
180         modules_list $@
181 fi