3 # A script to setup your git area to contribute back to SXEmacs
5 # Copyright (C) 2008 Nelson Ferreira
6 # Copyright (C) 2015 Steve Youngs
8 # This program is free software; you can redistribute it and/or modify it
9 # under a BSD-like licence.
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.
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.
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. :-)
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.
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).
51 ## The stuff this script looks at and might sets/changes:
53 ## user.name, user.email, user.signingKey, commit.gpgSign,
54 ## format.numbered, format.to, format.subjectprefix,
55 ## format.headers, sendmail.to, sendmail.from
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.
63 ## Oh, and it adds a swag of nice aliases.
67 **********************************************************************
68 | Hello, and welcome to the SXEmacs Team |
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. |
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.
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."
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!"
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
108 **********************************************************************
109 Hit [RETURN] to continue, or C-c to abort.
112 git stash save --all --quiet "git-for-steve.sh safety stash"
116 DIRTY=$(git status -u --ignored --porcelain -z)
117 [ -n "${DIRTY}" ] && clear_wd
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\"): "
130 [ $USER ] && NAMEGUESS=$(getent passwd $USER|cut -d: -f5)
132 if [ -n "${NAMEGUESS}" ]; then
134 echo "Git needs to know your name (for commit logs, etc)."
135 echo -n "Can we use \"${NAMEGUESS}\"? [Y/n]: "
137 if [ "${RESP}" = "Y" -o "${RESP}" = "y" -o "${RESP}" = "" ]; then
146 git config user.name "${NAME}"
148 [ -n "$(git config user.name)" ] || set_name
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): "
157 git config user.email ${EMAIL}
159 [ -n "$(git config user.email)" ] || set_email
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
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: "
169 git remote set-url origin http://git.sxemacs.org/sxemacs
175 echo "**********************************************************************"
176 echo "Setting up a \"for-steve\" branch to track origin/master."
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."
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
188 git branch | grep -q for-steve || set_branch
189 git checkout --quiet for-steve
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\".
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
208 The Push URL to your remote needs to be writable for you, here are a
209 couple of examples...
211 ssh://user@example.com/~/path/to/repo (using ssh)
212 https://user:pass@example.com/path/to/repo (using \"smart http\")
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.
219 Before we go ahead and add a remote to your repo, lets see if you have
221 **********************************************************************
222 Hit [RETURN] to continue, or C-c to abort.
225 REMOTES=($(git remote | grep -v origin))
227 echo "**********************************************************************"
228 echo " Currently configured remotes (possibly empty list)"
230 for (( i = 1; i <= ${#REMOTES}; i++ )); do
231 echo -n "\t"${i} -- ${REMOTES[${i}]}" at: "
232 echo $(git config remote.${REMOTES[${i}]}.url)
235 echo "**********************************************************************"
236 echo -n " Enter the number that corresponds to your remote, or \"x\" for none: "
239 if [ "${index}" = "x" -o "${index}" = "" ]; then
241 echo -n "Enter the \"Fetch URL\" (read-only access) to your remote: "
243 echo -n "Enter the \"Push URL\" (write-access for you) to your remote: "
245 echo "And what would you like to call this remote? It MUST be a single "
246 echo -n "word, and CANNOT be \"origin\": "
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}
253 URL=$(git config remote.${REMOTES[${index}]}.url)
254 while [ "${TYPE}" != "F" -a "${TYPE}" != "P" -a "${TYPE}" != "B" ]; do
256 echo -n " used for Fetch, Push, or Both? [F/P/B]: "
258 TYPE=$(echo ${TYPE}|tr 'fpb' 'FPB')
262 echo -n "${REMOTES[${index}]} \"Push URL\" (write-access for you): "
264 git remote set-url --push ${REMOTES[${index}]} ${TYPEURL}
267 echo -n "${REMOTES[${index}]} \"Fetch URL\" (read-only access): "
269 git remote set-url ${REMOTES[${index}]} ${TYPEURL}
270 git remote set-url --push ${REMOTES[${index}]} ${URL}
274 git config sxemacs.remote ${REMOTES[${index}]}
277 if [ -z "$(git config sxemacs.remote)" ]; then
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 **********************************************************************
288 echo -n " Do you have a remote repo like this set up? [Y/n]:"
290 if [ "${RESP}" = "Y" -o "${RESP}" = "y" -o "${RESP}" = "" ]; then
293 echo "If you ever do set up a remote repo, please re-run this script."
300 for word in $(git config user.name); do
301 SXEINITIALS="${SXEINITIALS}$(echo ${word}|cut -c1)"
303 INTLS=${INITIALS:-${SXEINITIALS}}
304 TAGNAME=devkey.${INTLS}
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..."
310 git show ${TAGNAME}|sed -n 2,5p
312 echo -n "Is it yours? [Y/n]: "
314 if [ "${RESP}" = "Y" -o "${RESP}" = "y" -o "${RESP}" = "" ]; then
315 git config sxemacs.devkey $(git show-ref ${TAGNAME}|awk '{print $1;}')
317 echo -n "Setting developer key tagname to: "
318 echo "${TAGNAME}.$(git config user.signingKey)"
319 TAGNAME=${TAGNAME}.$(git config user.signingKey)
323 if [ -z "$(git config sxemacs.devkey)" ]; then
325 Developer Key -- $(git config user.name)
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.
330 You may import this key into your GnuPG keyring with...
332 'git show ${TAGNAME} | gpg --import'
334 To verify signed objects in the repo, use the '--show-signature'
335 option with the git-log and git-show commands.
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} |
346 echo "Your devkey tag has been created successfully."
347 echo -n "Can we now push ${TAGNAME} to $(git config sxemacs.remote)? [Y/n]: "
349 if [ "${RESP}" = "Y" -o "${RESP}" = "y" -o "${RESP}" = "" ]; then
350 git push $(git config sxemacs.remote) ${TAGNAME}
353 **********************************************************************
354 Please let Steve know that your devkey is ready to be fetched into the
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.
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
375 DEFKEY=$(grep default-key ~/.gnupg/gpg.conf 2>/dev/null |
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}
385 if [ "${SIGNKEY}" = "NOTSET" ]; then
387 echo -n "Please enter the Key-ID of your default GnuPG key: "
389 [ -n "${RESP}" ] && git config user.signingKey ${RESP}
391 git config user.signingKey ${SIGNKEY}
394 git config --bool commit.gpgSign true
395 [ -n "$(git config sxemacs.devkey)" ] || set_tagblob
398 if ! type gpg 1>/dev/null ; then
401 **********************************************************************
402 WARNING: We could not find a gpg executable!
403 The GnuPG related setup in this script will be skipped.
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
409 Once you have GnuPG installed and set up please come back and re-run
411 **********************************************************************
412 Hit [RETURN] to continue, or C-c to abort.
415 elif [ -z "$(git config user.signingKey)" ]; then
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
423 ## Misc config (format, sendemail, etc)
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)>"
441 echo "**********************************************************************"
442 echo " Here are the format and sendemail configs we just set."
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)
451 echo "**********************************************************************"
452 echo -n " Hit [RETURN] to continue, or C-c to abort."
454 git config --bool sxemacs.formats true
456 BOOL=$(git config sxemacs.formats)
457 if [ "${BOOL}" != "true" ]; then
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."
468 if [ -f ".git/hooks/post-commit" ]; then
469 cat>>.git/hooks/post-commit<<EOF
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
476 elif [ -f ".git/hooks/post-commit.sample" ]; then
477 cat>>.git/hooks/post-commit.sample<<EOF
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
484 sed -i /Nothing/d .git/hooks/post-commit.sample
485 mv .git/hooks/post-commit{.sample,}
487 cat>.git/hooks/post-commit<<EOF
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
494 chmod 755 .git/hooks/post-commit
498 HAVEHOOK=$(git config sxemacs.commithook)
499 if [ "${HAVEHOOK}" != "true" ]; then
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'.
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 **********************************************************************
513 echo -n " Shall we add the hook? [Y/n]: "
515 if [ "${HOOKME}" = "Y" -o "${HOOKME}" = "y" -o "${HOOKME}" = "" ]; then
517 git config --bool sxemacs.commithook true
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}]: "
528 GITTMP=${GITTMP:-${TMP:-/tmp}}
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"
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'
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}"
560 echo "**********************************************************************"
561 echo " The following aliases are now available for use..."
565 echo "**********************************************************************"
566 echo -n " Hit [RETURN] to continue, or C-c to abort."
568 git config --bool sxemacs.aliases true
571 BOOL=$(git config sxemacs.aliases)
572 if [ "${BOOL}" != "true" ]; then
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
579 **********************************************************************
580 Hit [RETURN] to continue, or C-c to abort.
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. |
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'. |
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 |
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 **********************************************************************
608 # If we stashed at the start, pop them back
609 [ ${LETSPOP} -eq 1 ] && git stash pop --quiet
614 ### git-for-steve.sh ends here.