Fix configure dirname. Also streamline dirname usage.
[sxemacs] / contrib / git-for-steve.sh
1 #!/bin/sh
2 #
3 # A script to setup your git area to contribute back to SXEmacs
4 #
5 # Copyright (C) 2008 Nelson Ferreira
6 # Copyright (C) 2015 Steve Youngs
7 #
8 # This program is free software; you can redistribute it and/or modify it
9 # under a BSD-like licence.
10 #
11 # Redistribution and use in source and binary forms, with or without
12 # modification, are permitted provided that the following conditions are met:
13 # Redistributions of source code must retain the above copyright notice, this
14 # list of conditions and the following disclaimer.
15 # Redistributions in binary form must reproduce the above copyright notice,
16 # this list of conditions and the following disclaimer in the documentation
17 # and/or other materials provided with the distribution.
18 # Neither the name of the Technical University of Berlin nor the names of its
19 # contributors may be used to endorse or promote products derived from this
20 # software without specific prior written permission.
21 #
22 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23 # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
26 # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27 # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29 # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31 # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32 # POSSIBILITY OF SUCH DAMAGE.
33 #
34
35 ### Commentary:
36 ##
37 ##    This script sets up your SXEmacs git WD so that contributing
38 ##    back to the SXEmacs project is as easy as possible, in the way
39 ##    that the maintainers like best. :-)
40 ##
41 ##    Much care has been taken to NOT overwrite your current settings.
42 ##    Most times, a setting will only be set if it is not already set,
43 ##    and you will be prompted before any changes are made, giving you
44 ##    the option to bail out.
45 ##
46 ##    Before the script does anything it checks to make sure you are
47 ##    running it in a SXEmacs source tree (bails out, if not).
48 ##    And if you have a dirty WD (uncommitted changes) the script will
49 ##    stash them first, just to be safe (they're restored at the end).
50 ##
51 ##    The stuff this script looks at and might sets/changes:
52 ##
53 ##      user.name, user.email, user.signingKey, commit.gpgSign,
54 ##      format.numbered, format.to, format.subjectprefix,
55 ##      format.headers, sendmail.to, sendmail.from
56 ##
57 ##    It also ensures that origin points to the right place
58 ##    (http://git.sxemacs.org/sxemacs), optionally makes sure your
59 ##    remote is set up correctly, that you have a "for-steve" tracking
60 ##    branch, and adds a devkey.$INITIALS tag containing your public
61 ##    GnuPG key if available, which can be pushed to your remote.
62 ##
63 ##    Oh, and it adds a swag of nice aliases.
64 ##
65 LETSPOP=0
66 cat<<EOF
67 **********************************************************************
68 |               Hello, and welcome to the SXEmacs Team               |
69 |                                                                    |
70 | This script will help guide you through setting up your personal   |
71 | SXEmacs git repo in a way that will make your life as a developer, |
72 | and contributor, as easy as possible.                              |
73 |                                                                    |
74 | We just make sure a few basics are set like name, email, the right |
75 | tracking branch, remotes, etc, and add a few nice aliases and      |
76 | config options.  You will be prompted if we need to make any       |
77 | changes to your config, and you can bail out at any time with C-c. |
78 |--------------------------------------------------------------------|
79 | I hope you get immense fun and satisfaction from hacking SXEmacs   |
80 |      Steve Youngs <steve@sxemacs.org> "SteveYoungs" on IRC         |
81 **********************************************************************
82                             Hit [RETURN] to continue, or C-c to abort.
83 EOF
84 read junk
85
86 # Work in the toplevel dir just to be on the safe side
87 pushd $(git rev-parse --show-toplevel) 2>/dev/null || 
88     ( echo 1>&2 "Please run this script from _inside_ your SXEmacs repo."
89         exit 1 )
90
91 # Lets not mess about in anything that isn't a SXEmacs repo
92 if [ ! -f "sxemacs.pc.in" ]; then
93     echo 1>&2 "This is NOT a SXEmacs repo, bailing out!"
94     exit 1
95 fi
96
97 ## Clean WD
98 clear_wd()
99 {
100     cat<<EOF
101
102 **********************************************************************
103 Your working directory contains changes that have not been committed
104 yet.  Under certain conditions this script may do a couple of branch
105 jumps, so we will play it safe and store your changes out of the way
106 with 'git stash'.  We will 'pop' them back again when we are all done
107 here.
108 **********************************************************************
109                             Hit [RETURN] to continue, or C-c to abort.
110 EOF
111     read junk
112     git stash save --all --quiet "git-for-steve.sh safety stash"
113     LETSPOP=1
114     echo
115 }
116 DIRTY=$(git status -u --ignored --porcelain -z)
117 [ -n "${DIRTY}" ] && clear_wd
118
119 ## Name
120 have_noname()
121 {
122     echo
123     echo "Please enter your name as you would like it to appear in the logs"
124     echo -n "Take care to guard against shell expansion (\"John Doe\"): "
125     read NAME
126 }
127
128 set_name()
129 {
130     [ $USER ] && NAMEGUESS=$(getent passwd $USER|cut -d: -f5)
131
132     if [ -n "${NAMEGUESS}" ]; then
133         echo
134         echo "Git needs to know your name (for commit logs, etc)."
135         echo -n "Can we use \"${NAMEGUESS}\"? [Y/n]: "
136         read RESP
137         if [ "${RESP}" = "Y" -o "${RESP}" = "y" -o "${RESP}" = "" ]; then
138             NAME=${NAMEGUESS}
139         else
140             have_noname
141         fi
142     else
143         have_noname
144     fi
145
146     git config user.name "${NAME}"
147 }
148 [ -n "$(git config user.name)" ] || set_name
149
150 ## Email
151 set_email()
152 {
153     echo
154     echo "Git needs to know your email address (for commit logs, etc)."
155     echo -n "Please enter your email address (eg john@doe.com): "
156     read EMAIL
157     git config user.email ${EMAIL}
158 }
159 [ -n "$(git config user.email)" ] || set_email
160
161 ## Tracking branch "for-steve"
162 # Make sure origin points to http://git.sxemacs.org/sxemacs
163 ORIGIN_URL=$(git config remote.origin.url)
164 if [ "${ORIGIN_URL}" != "http://git.sxemacs.org/sxemacs" ]; then
165     echo
166     echo "Uh-Oh! origin URL is wrong.  Currently set to: ${ORIGIN_URL}"
167     echo -n "Hit [RETURN] to reset to: http://git.sxemacs.org/sxemacs or C-c to abort: "
168     read junk
169     git remote set-url origin http://git.sxemacs.org/sxemacs
170 fi
171
172 set_branch()
173 {
174     echo
175     echo "**********************************************************************"
176     echo "Setting up a \"for-steve\" branch to track origin/master."
177     echo
178     echo "This is the branch that you will merge your work into once it is"
179     echo "ready for Steve to pull into his repo."
180     echo "**********************************************************************"
181     echo -n "                            Hit [RETURN] to continue, or C-c to abort."
182     read junk
183     # Does it make a difference from where we do this from?  Lets
184     # jump into master just to be on the safe side.
185     git checkout --quiet master
186     git branch --track for-steve origin/master
187 }
188 git branch | grep -q for-steve || set_branch
189 git checkout --quiet for-steve
190
191 ## Remotes
192 # myremote
193 set_myremote()
194 {
195     cat<<EOF
196
197 **********************************************************************
198 You need to have a remote repository set up for you to push your
199 changes to.  Steve will need read-only access so he can fetch your
200 changes into his repo.  You can name this repo anything you like,
201 just as long as it is a single word, and that word is not \"origin\".
202
203 A remote repo can have a "Fetch URL", and a "Push URL".  The
204 former (Fetch URL) is the URL from which people would clone, pull,
205 fetch from.  And the latter (Push URL) is the URL you would use to
206 push (or write) to.
207
208 The Push URL to your remote needs to be writable for you, here are a
209 couple of examples...
210
211     ssh://user@example.com/~/path/to/repo       (using ssh)
212     https://user:pass@example.com/path/to/repo  (using \"smart http\")
213
214 You _could_ use a git protocol URL (git://), but because the git
215 protocol has no authentication if you allow write access you are
216 allowing write access for anyone who has an internet connection.  So
217 PLEASE DO NOT write to your remote via the git protocol.
218
219 Before we go ahead and add a remote to your repo, lets see if you have
220 one already.
221 **********************************************************************
222                             Hit [RETURN] to continue, or C-c to abort.
223 EOF
224     read junk
225     REMOTES=($(git remote | grep -v origin))
226     echo
227     echo "**********************************************************************"
228     echo "          Currently configured remotes (possibly empty list)"
229     echo
230     for (( i = 1; i <= ${#REMOTES}; i++ )); do
231         echo -n "\t"${i} -- ${REMOTES[${i}]}" at: "
232         echo $(git config remote.${REMOTES[${i}]}.url)
233     done
234     echo
235     echo "**********************************************************************"
236     echo -n " Enter the number that corresponds to your remote, or \"x\" for none: "
237     read index
238
239     if [ "${index}" = "x" -o "${index}" = "" ]; then
240         echo
241         echo -n "Enter the \"Fetch URL\" (read-only access) to your remote: "
242         read MYREMOTE_FETCH
243         echo -n "Enter the \"Push URL\" (write-access for you) to your remote: "
244         read MYREMOTE_PUSH
245         echo "And what would you like to call this remote?  It MUST be a single "
246         echo -n "word, and CANNOT be \"origin\": "
247         read MYREMOTE_NAME
248         git remote add ${MYREMOTE_NAME} ${MYREMOTE_FETCH}
249         git remote set-url --push ${MYREMOTE_NAME} ${MYREMOTE_PUSH}
250         git config sxemacs.remote ${MYREMOTE_NAME}
251     else
252         TYPE="X"
253         URL=$(git config remote.${REMOTES[${index}]}.url)
254         while [ "${TYPE}" != "F" -a "${TYPE}" != "P" -a "${TYPE}" != "B" ]; do
255             echo  "Is \"${URL}\""
256             echo -n "  used for Fetch, Push, or Both? [F/P/B]: "
257             read TYPE
258             TYPE=$(echo ${TYPE}|tr 'fpb' 'FPB')
259         done
260         case ${TYPE} in
261             F)
262                 echo -n "${REMOTES[${index}]} \"Push URL\" (write-access for you): "
263                 read TYPEURL
264                 git remote set-url --push ${REMOTES[${index}]} ${TYPEURL}
265                 ;;
266             P)
267                 echo -n "${REMOTES[${index}]} \"Fetch URL\" (read-only access): "
268                 read TYPEURL
269                 git remote set-url ${REMOTES[${index}]} ${TYPEURL}
270                 git remote set-url --push ${REMOTES[${index}]} ${URL}
271                 ;;
272             B)  ;; # do nothing
273         esac
274         git config sxemacs.remote ${REMOTES[${index}]}
275     fi
276 }
277 if [ -z "$(git config sxemacs.remote)" ]; then
278     cat<<EOF
279
280 **********************************************************************
281 The easiest, and quickest way to get your work and changes into the
282 main SXEmacs repository is if you have a publicly accessible remote
283 repo.  Well, technically, it does not need to be publicly accessible,
284 it just needs to allow Steve read-only access.  Nobody, except you,
285 will ever need to write to this repo.
286 **********************************************************************
287 EOF
288     echo -n "                    Do you have a remote repo like this set up? [Y/n]:"
289     read RESP
290     if [ "${RESP}" = "Y" -o "${RESP}" = "y" -o "${RESP}" = "" ]; then
291         set_myremote
292     else
293         echo "If you ever do set up a remote repo, please re-run this script."
294     fi
295 fi
296
297 ## GnuPG
298 set_tagblob()
299 {
300     for word in $(git config user.name); do
301         SXEINITIALS="${SXEINITIALS}$(echo ${word}|cut -c1)"
302     done
303     INTLS=${INITIALS:-${SXEINITIALS}}
304     TAGNAME=devkey.${INTLS}
305
306     git tag|grep -q ${TAGNAME} && TAGEXISTS=yes
307     if [ "${TAGEXISTS}" = "yes" ]; then
308         echo "There is already a developer key tag using your initials..."
309         echo
310         git show ${TAGNAME}|sed -n 2,5p
311         echo
312         echo -n "Is it yours? [Y/n]: "
313         read RESP
314         if [ "${RESP}" = "Y" -o "${RESP}" = "y" -o "${RESP}" = "" ]; then
315             git config sxemacs.devkey $(git show-ref ${TAGNAME}|awk '{print $1;}')
316         else
317             echo -n "Setting developer key tagname to: "
318             echo "${TAGNAME}.$(git config user.signingKey)"
319             TAGNAME=${TAGNAME}.$(git config user.signingKey)
320         fi
321     fi
322
323     if [ -z "$(git config sxemacs.devkey)" ]; then
324         TAGMSG=$(cat<<EOF
325 Developer Key -- $(git config user.name)
326
327 This is the GnuPG key used by $(git config user.name) <$(git config user.email)>
328 to sign commits, merges, and tags in this repository.
329
330 You may import this key into your GnuPG keyring with...
331
332   'git show ${TAGNAME} | gpg --import'
333
334 To verify signed objects in the repo, use the '--show-signature'
335 option with the git-log and git-show commands.
336
337 EOF
338 )
339         git tag -s ${TAGNAME} -m "${TAGMSG}" \
340             $(gpg --armor --export $(git config user.signingKey) |
341             git hash-object -w --stdin)
342         git config sxemacs.devkey $(git show-ref ${TAGNAME} | 
343             awk '{print $1;}')
344
345         echo
346         echo "Your devkey tag has been created successfully."
347         echo -n "Can we now push ${TAGNAME} to $(git config sxemacs.remote)? [Y/n]: "
348         read RESP
349         if [ "${RESP}" = "Y" -o "${RESP}" = "y" -o "${RESP}" = "" ]; then
350             git push $(git config sxemacs.remote) ${TAGNAME}
351             cat<<EOF
352
353 **********************************************************************
354 Please let Steve know that your devkey is ready to be fetched into the
355 main SXEmacs repo.
356
357 You can email Steve at steve@sxemacs.org, be sure to also include the
358 output from 'git config sxemacs.devkey', it will give Steve a way to
359 verify that the tag has not been tampered with.
360 **********************************************************************
361                             Hit [RETURN] to continue, or C-c to abort.
362 EOF
363             read junk
364         fi
365     fi
366 }
367
368 set_keys()
369 {
370     # Make sure they've got Steve's key in their keyring.  Safe to
371     # call even if the key exists in the keyring.
372     git tag|grep -q maintainer-pgp &&
373         git show maintainer-pgp|gpg --import --quiet
374
375     DEFKEY=$(grep default-key ~/.gnupg/gpg.conf 2>/dev/null |
376         awk '{print $2;}')
377     if [ -z "${DEFKEY}" ]; then
378         GUESS=$(gpg --list-keys $(git config user.email) |
379             awk '/^pub/ { split($2,k,"/"); print k[2] }')
380         SIGNKEY=${GUESS:-NOTSET}
381     else
382         SIGNKEY=${DEFKEY}
383     fi
384
385     if [ "${SIGNKEY}" = "NOTSET" ]; then
386         echo
387         echo -n "Please enter the Key-ID of your default GnuPG key: "
388         read RESP
389         [ -n "${RESP}" ] && git config user.signingKey ${RESP}
390     else
391         git config user.signingKey ${SIGNKEY}
392     fi
393
394     git config --bool commit.gpgSign true
395     [ -n "$(git config sxemacs.devkey)" ] || set_tagblob
396 }
397
398 if ! type gpg 1>/dev/null ; then
399     cat<<EOF
400
401 **********************************************************************
402 WARNING:  We could not find a gpg executable!
403           The GnuPG related setup in this script will be skipped.
404
405 We highly recommend that you have and use GnuPG (gpg) so that you can
406 both, verify the signed objects in the repository, and sign your own
407 commits.
408
409 Once you have GnuPG installed and set up please come back and re-run
410 this script.
411 **********************************************************************
412                             Hit [RETURN] to continue, or C-c to abort.
413 EOF
414     read junk
415 elif [ -z "$(git config user.signingKey)" ]; then
416     set_keys
417 fi
418
419 # set_tagblog is called from set_keys but we may need to call it
420 # explicitly if user.signingKey was set prior to running this script.
421 [ -n "$(git config sxemacs.devkey)" ] || set_tagblob
422
423 ## Misc config (format, sendemail, etc)
424 set_formats()
425 {
426     [ -n "$(git config format.numbered)" ] ||
427         git config format.numbered auto
428     [ -n "$(git config format.to)" ] || git config format.to \
429         "SXEmacs Patches <sxemacs-patches@sxemacs.org>"
430     [ -n "$(git config format.subjecprefix)" ] ||
431         git config format.subjectprefix Patch
432     git config format.headers || git config format.headers \
433         "X-Git-Repo: $(git config remote.$(git config sxemacs.remote).url)
434 X-Git-Branch: for-steve"
435     [ -n "$(git config sendemail.to)" ] || git config sendemail.to \
436         "SXEmacs Patches <sxemacs-patches@sxemacs.org>"
437     [ -n "$(git config sendemail.from)" ] || git config sendemail.from \
438         "$(git config user.name) <$(git config user.email)>"
439
440     echo
441     echo "**********************************************************************"
442     echo "        Here are the format and sendemail configs we just set."
443     echo
444     echo "      format.numbered --" $(git config format.numbered)
445     echo "            format.to --" $(git config format.to)
446     echo " format.subjectprefix --" $(git config format.subjectprefix)
447     echo "       format.headers --" $(git config format.headers)
448     echo "         sendemail.to --" $(git config sendemail.to)
449     echo "       sendemail.from --" $(git config sendemail.from)
450     echo
451     echo "**********************************************************************"
452     echo -n "                            Hit [RETURN] to continue, or C-c to abort."
453     read junk
454     git config --bool sxemacs.formats true
455 }
456 BOOL=$(git config sxemacs.formats)
457 if [ "${BOOL}" != "true" ]; then
458     echo
459     echo "We're going to set some format config values, but only if they aren't"
460     echo "already set, so your existing ones are safe."
461     set_formats
462 fi
463
464 ## Hooks
465 set_hook()
466 {
467     # post-commit hook
468     if [ -f ".git/hooks/post-commit" ]; then
469         cat>>.git/hooks/post-commit<<EOF
470
471 ### Begin - lines added by git-for-steve.sh
472 LOG=\$(git rev-parse --show-toplevel)/++log
473 [ -f \${LOG} ] && rm -f \${LOG}
474 ### End -- lines added by git-for-steve.sh
475 EOF
476     elif [ -f ".git/hooks/post-commit.sample" ]; then
477         cat>>.git/hooks/post-commit.sample<<EOF
478
479 ### Begin - lines added by git-for-steve.sh
480 LOG=\$(git rev-parse --show-toplevel)/++log
481 [ -f \${LOG} ] && rm -f \${LOG}
482 ### End -- lines added by git-for-steve.sh
483 EOF
484         sed -i /Nothing/d .git/hooks/post-commit.sample
485         mv .git/hooks/post-commit{.sample,}
486     else
487         cat>.git/hooks/post-commit<<EOF
488 #!/bin/sh
489 ### Begin - lines added by git-for-steve.sh
490 LOG=\$(git rev-parse --show-toplevel)/++log
491 [ -f \${LOG} ] && rm -f \${LOG}
492 ### End -- lines added by git-for-steve.sh
493 EOF
494         chmod 755 .git/hooks/post-commit
495     fi
496 }
497
498 HAVEHOOK=$(git config sxemacs.commithook)
499 if [ "${HAVEHOOK}" != "true" ]; then
500     cat<<EOF
501
502 **********************************************************************
503 Some of the SXEmacs developers use a variation of the
504 #'add-change-log-entry defun (C-x 4 a) for logging their changes
505 It creates a log file in the toplevel directory (called '++log') which
506 you can use with the '-F' switch of 'git commit'.
507
508 If you think that is something you would use (we hope you do), then we
509 can add a post-commit hook to your repo that automatically deletes
510 that log file after a successful commit.
511 **********************************************************************
512 EOF
513     echo -n "                                       Shall we add the hook? [Y/n]: "
514     read HOOKME
515     if [ "${HOOKME}" = "Y" -o "${HOOKME}" = "y" -o "${HOOKME}" = "" ]; then
516         set_hook
517         git config --bool sxemacs.commithook true
518     fi
519 fi
520
521 ## Aliases
522 set_aliases()
523 {
524     echo
525     echo "Which directory would you like to use as the output dir for"
526     echo -n "git format-patch, and send-email? [${TMP:-/tmp}]: "
527     read GITTMP
528     GITTMP=${GITTMP:-${TMP:-/tmp}}
529
530     [ -n "$(git config alias.alias)" ] ||
531         git config alias.alias "config --get-regexp alias"
532     [ -n "$(git config alias.bi)" ] || git config alias.bi bisect
533     [ -n "$(git config alias.co)" ] || git config alias.co checkout
534     [ -n "$(git config alias.ci)" ] || git config alias.ci commit
535     [ -n "$(git config alias.cam)" ] || git config alias.cam "commit -sam"
536
537     BOOL=$(git config sxemacs.commithook)
538     if [ "${BOOL}" = "true" ]; then
539         [ -n "$(git config alias.cwl)" ] ||
540             git config alias.cwl \
541             '!git commit -sF $(git rev-parse --show-toplevel)/++log'
542         [ -n "$(git config alias.cawl)" ] ||
543             git config alias.cawl \
544             '!git commit -saF $(git rev-parse --show-toplevel)/++log'
545     fi
546
547     [ -n "$(git config alias.rbi)" ] || git config alias.rbi "rebase -i"
548     [ -n "$(git config alias.pfs)" ] ||
549         git config alias.pfs "push $(git config sxemacs.remote) for-steve"
550     [ -n "$(git config alias.fp)" ] || git config alias.fp \
551         "format-patch --minimal -o ${GITTMP} origin/master"
552     [ -n "$(git config alias.fpc)" ] || git config alias.fpc \
553         "format-patch --minimal --cover-letter -o ${GITTMP} origin/master"
554     [ -n "$(git config alias.sp)" ] || git config alias.sp \
555         "send-email ${GITTMP}"
556     [ -n "$(git config alias.spc)" ] || git config alias.spc \
557         "send-email --compose ${GITTMP}"
558
559     echo
560     echo "**********************************************************************"
561     echo "         The following aliases are now available for use..."
562     echo
563     git alias
564     echo
565     echo "**********************************************************************"
566     echo -n "                            Hit [RETURN] to continue, or C-c to abort."
567     read junk
568     git config --bool sxemacs.aliases true
569 }
570
571 BOOL=$(git config sxemacs.aliases)
572 if [ "${BOOL}" != "true" ]; then
573     cat<<EOF
574
575 **********************************************************************
576 And finally, lets set a few aliases.  We will only set them if they
577 have not already been set so all of your pre-existing aliases are
578 safe.
579 **********************************************************************
580                             Hit [RETURN] to continue, or C-c to abort.
581 EOF
582     read junk
583     set_aliases
584 fi
585
586 cat<<EOF
587
588 **********************************************************************
589 | Thank you for taking the time to setup your repo so that you can   |
590 | contribute back to the SXEmacs Project.  We really appreciate all  |
591 | that you do, no matter how small or insignificant you may think it |
592 | is, it all counts.                                                 |
593 |                                                                    |
594 | If you have not already done so, please take a few minutes now to  |
595 | read through our policies and procedures manual,  We call it the   |
596 | "SPPM".  From inside SXEmacs you can get to it via 'C-h C-i sppm', |
597 | or from the command line via 'info sppm'.                          |
598 |                                                                    |
599 | Also, now would be a good time for you to head over to             |
600 | http://www.sxemacs.org/lists.html and subscribe to our mailing     |
601 | lists.                                                             |
602 |--------------------------------------------------------------------|
603 | Thank you, and do drop into #sxemacs on freenode IRC for a chat    |
604 | any time, especially if you need a hand with anything.             |
605 **********************************************************************
606 EOF
607
608 # If we stashed at the start, pop them back
609 [ ${LETSPOP} -eq 1 ] && git stash pop --quiet
610
611 popd
612
613 exit 0
614 ### git-for-steve.sh ends here.