git-remote-mediawiki: get rid of O(N^2) loop
[git] / git-sh-setup.sh
1 #!/bin/sh
2 #
3 # This is included in commands that either have to be run from the toplevel
4 # of the repository, or with GIT_DIR environment variable properly.
5 # If the GIT_DIR does not look like the right correct git-repository,
6 # it dies.
7
8 # Having this variable in your environment would break scripts because
9 # you would cause "cd" to be taken to unexpected places.  If you
10 # like CDPATH, define it for your interactive shell sessions without
11 # exporting it.
12 unset CDPATH
13
14 git_broken_path_fix () {
15         case ":$PATH:" in
16         *:$1:*) : ok ;;
17         *)
18                 PATH=$(
19                         SANE_TOOL_PATH="$1"
20                         IFS=: path= sep=
21                         set x $PATH
22                         shift
23                         for elem
24                         do
25                                 case "$SANE_TOOL_PATH:$elem" in
26                                 (?*:/bin | ?*:/usr/bin)
27                                         path="$path$sep$SANE_TOOL_PATH"
28                                         sep=:
29                                         SANE_TOOL_PATH=
30                                 esac
31                                 path="$path$sep$elem"
32                                 sep=:
33                         done
34                         echo "$path"
35                 )
36                 ;;
37         esac
38 }
39
40 # @@BROKEN_PATH_FIX@@
41
42 die () {
43         die_with_status 1 "$@"
44 }
45
46 die_with_status () {
47         status=$1
48         shift
49         echo >&2 "$*"
50         exit "$status"
51 }
52
53 GIT_QUIET=
54
55 say () {
56         if test -z "$GIT_QUIET"
57         then
58                 printf '%s\n' "$*"
59         fi
60 }
61
62 if test -n "$OPTIONS_SPEC"; then
63         usage() {
64                 "$0" -h
65                 exit 1
66         }
67
68         parseopt_extra=
69         [ -n "$OPTIONS_KEEPDASHDASH" ] &&
70                 parseopt_extra="--keep-dashdash"
71
72         eval "$(
73                 echo "$OPTIONS_SPEC" |
74                         git rev-parse --parseopt $parseopt_extra -- "$@" ||
75                 echo exit $?
76         )"
77 else
78         dashless=$(basename "$0" | sed -e 's/-/ /')
79         usage() {
80                 die "Usage: $dashless $USAGE"
81         }
82
83         if [ -z "$LONG_USAGE" ]
84         then
85                 LONG_USAGE="Usage: $dashless $USAGE"
86         else
87                 LONG_USAGE="Usage: $dashless $USAGE
88
89 $LONG_USAGE"
90         fi
91
92         case "$1" in
93                 -h)
94                 echo "$LONG_USAGE"
95                 exit
96         esac
97 fi
98
99 set_reflog_action() {
100         if [ -z "${GIT_REFLOG_ACTION:+set}" ]
101         then
102                 GIT_REFLOG_ACTION="$*"
103                 export GIT_REFLOG_ACTION
104         fi
105 }
106
107 git_editor() {
108         if test -z "${GIT_EDITOR:+set}"
109         then
110                 GIT_EDITOR="$(git var GIT_EDITOR)" || return $?
111         fi
112
113         eval "$GIT_EDITOR" '"$@"'
114 }
115
116 git_pager() {
117         if test -t 1
118         then
119                 GIT_PAGER=$(git var GIT_PAGER)
120         else
121                 GIT_PAGER=cat
122         fi
123         : ${LESS=-FRSX}
124         export LESS
125
126         eval "$GIT_PAGER" '"$@"'
127 }
128
129 sane_grep () {
130         GREP_OPTIONS= LC_ALL=C grep "$@"
131 }
132
133 sane_egrep () {
134         GREP_OPTIONS= LC_ALL=C egrep "$@"
135 }
136
137 is_bare_repository () {
138         git rev-parse --is-bare-repository
139 }
140
141 cd_to_toplevel () {
142         cdup=$(git rev-parse --show-toplevel) &&
143         cd "$cdup" || {
144                 echo >&2 "Cannot chdir to $cdup, the toplevel of the working tree"
145                 exit 1
146         }
147 }
148
149 require_work_tree_exists () {
150         if test "z$(git rev-parse --is-bare-repository)" != zfalse
151         then
152                 die "fatal: $0 cannot be used without a working tree."
153         fi
154 }
155
156 require_work_tree () {
157         test "$(git rev-parse --is-inside-work-tree 2>/dev/null)" = true ||
158         die "fatal: $0 cannot be used without a working tree."
159 }
160
161 require_clean_work_tree () {
162         git rev-parse --verify HEAD >/dev/null || exit 1
163         git update-index -q --ignore-submodules --refresh
164         err=0
165
166         if ! git diff-files --quiet --ignore-submodules
167         then
168                 echo >&2 "Cannot $1: You have unstaged changes."
169                 err=1
170         fi
171
172         if ! git diff-index --cached --quiet --ignore-submodules HEAD --
173         then
174                 if [ $err = 0 ]
175                 then
176                     echo >&2 "Cannot $1: Your index contains uncommitted changes."
177                 else
178                     echo >&2 "Additionally, your index contains uncommitted changes."
179                 fi
180                 err=1
181         fi
182
183         if [ $err = 1 ]
184         then
185                 test -n "$2" && echo >&2 "$2"
186                 exit 1
187         fi
188 }
189
190 get_author_ident_from_commit () {
191         pick_author_script='
192         /^author /{
193                 s/'\''/'\''\\'\'\''/g
194                 h
195                 s/^author \([^<]*\) <[^>]*> .*$/\1/
196                 s/.*/GIT_AUTHOR_NAME='\''&'\''/p
197
198                 g
199                 s/^author [^<]* <\([^>]*\)> .*$/\1/
200                 s/.*/GIT_AUTHOR_EMAIL='\''&'\''/p
201
202                 g
203                 s/^author [^<]* <[^>]*> \(.*\)$/@\1/
204                 s/.*/GIT_AUTHOR_DATE='\''&'\''/p
205
206                 q
207         }
208         '
209         encoding=$(git config i18n.commitencoding || echo UTF-8)
210         git show -s --pretty=raw --encoding="$encoding" "$1" -- |
211         LANG=C LC_ALL=C sed -ne "$pick_author_script"
212 }
213
214 # Clear repo-local GIT_* environment variables. Useful when switching to
215 # another repository (e.g. when entering a submodule). See also the env
216 # list in git_connect()
217 clear_local_git_env() {
218         unset $(git rev-parse --local-env-vars)
219 }
220
221
222 # Platform specific tweaks to work around some commands
223 case $(uname -s) in
224 *MINGW*)
225         # Windows has its own (incompatible) sort and find
226         sort () {
227                 /usr/bin/sort "$@"
228         }
229         find () {
230                 /usr/bin/find "$@"
231         }
232         # git sees Windows-style pwd
233         pwd () {
234                 builtin pwd -W
235         }
236         is_absolute_path () {
237                 case "$1" in
238                 [/\\]* | [A-Za-z]:*)
239                         return 0 ;;
240                 esac
241                 return 1
242         }
243         ;;
244 *)
245         is_absolute_path () {
246                 case "$1" in
247                 /*)
248                         return 0 ;;
249                 esac
250                 return 1
251         }
252 esac
253
254 # Make sure we are in a valid repository of a vintage we understand,
255 # if we require to be in a git repository.
256 if test -z "$NONGIT_OK"
257 then
258         GIT_DIR=$(git rev-parse --git-dir) || exit
259         if [ -z "$SUBDIRECTORY_OK" ]
260         then
261                 test -z "$(git rev-parse --show-cdup)" || {
262                         exit=$?
263                         echo >&2 "You need to run this command from the toplevel of the working tree."
264                         exit $exit
265                 }
266         fi
267         test -n "$GIT_DIR" && GIT_DIR=$(cd "$GIT_DIR" && pwd) || {
268                 echo >&2 "Unable to determine absolute path of git directory"
269                 exit 1
270         }
271         : ${GIT_OBJECT_DIRECTORY="$GIT_DIR/objects"}
272 fi