3 # This script called in a CVS directory compares local files with
4 # the repository, and prepares an update package containing all
5 # changes and new files for submission to a CVS maintainer. If there
6 # are only changes in text files, then a compressed unified diff is
7 # made (foo.diff.bz2). If there are also changed binary or new files,
8 # then an archive is made instead (foo.tar.bz2). The base name ("foo")
9 # can be given as command line argument. Otherwise the directory name
10 # is used. The script also leaves a diff in uncompressed/unpackaged
11 # form. This is only for developer convenience -- for a quick check
12 # of the diff correctness. It is not to be submitted. The script will
13 # not overwrite any file, but rather rename conflicting files.
15 # Usage: fg-submit [<basename>]
18 # $ cd $FG_ROOT/Aircraft/bo105
19 # $ fg-submit # -> bo105.diff.bz2 or bo105.tar.bz2
21 # $ fg-submit update # -> update.diff.bz2 or update.tar.bz2
24 # Spaces in the basename are replaced with "%20". People who prefer
25 # to have the date in the archive name can conveniently achieve this
26 # by defining a shell alias in ~/.bashrc:
28 # alias submit='fg-submit "${PWD/#*\/}-$(date +%Y-%m-%d)"'
31 # If the script finds an application named "fg-upload", then it calls
32 # this at the end with three arguments:
34 # $1 ... working directory ($PWD)
35 # $2 ... archive or compressed diff for submission
36 # $3 ... accessory diff, *NOT* for submission!
38 # $2 and $3 are guaranteed not to contain spaces, only $1 is guaranteed
39 # to actually exist. Such as script can be used to upload the file to an
40 # ftp-/webserver, and/or to remove one or both files. Example using
41 # KDE's kfmclient for upload (alternatives: ncftpput, gnomevfs-copy, ...):
43 # $ cat ~/bin/fg-upload
46 # if kfmclient copy $2 ftp://user:password@server.com; then
47 # echo "deleting $2 $3"
50 # echo "Done. URL: ftp://server.com/$2"
52 # echo "arghh ... HELP! HELP!"
61 CVS=/usr/bin/cvs # avoid colorcvs wrapper from
62 [ -x $CVS ] || CVS=cvs # http://www.hakubi.us/colorcvs/
63 UPLOAD=$(which fg-upload 2>/dev/null)
70 function ERROR { echo -e "\e[31;1m$*\e[m"; }
71 function LOG { echo -e "\e[35m$*\e[m"; }
72 function NEW { echo -e "\e[32m\t+ $*\e[m"; }
73 function CHANGED { echo -e "\e[36m\t+ $*\e[m"; }
74 function REJECT { echo -e "\e[31m\t- $*\e[m"; }
77 # output diff statistics, similar to the "diffstat" utility
79 function line(a, r, c, f) {
80 print "\t\033[32m"a"\033[m\t\033[31m"r"\033[m\t\033[34m"c"\033[m\t"f
87 print "\t. . . . binary . . . . \033[36m"file"\033[m"
90 at += a; rt += r; ct += c
95 print "\tadded---removed-changed----------------------------------------"
96 a = r = c = at = rt = ct = n = bin = 0
98 /^Index: / { dofile(); scan = bin = 0; file = $2; n++; next }
99 /^@@/ { scan = 1; next }
100 /^Binary/ { if (!scan) bin = 1; next }
101 /^+/ { if (scan) a++; next }
102 /^-/ { if (scan) r++; next }
103 /^!/ { if (scan) c++; next }
106 print "\t----------------------------------------total------------------"
107 line(at, rt, ct, "\033[min "n" files")
113 # create temporary dir that's automatcally removed on exit
114 TMP=$(mktemp -d -t $SELF.$BASE.XXX) || (echo "$0: can't create temporary dir"; exit 1)
115 trap "rm -rf $TMP" 0 1 2 3 13 15
118 # move old files out of the way
119 for i in $DIFF $CDIFF $ARCHIVE; do
120 [ -f $i ] && mv $i $(mktemp $i.X)
124 LOG "updating and checking for new files ..."
125 $CVS -q up -dP >$TMP/up
128 if grep "^C " $TMP/up &>/dev/null; then
129 ERROR "there are conflicts with the following files:"
135 LOG "making diff ..."
136 if ! $CVS -q diff -up >$DIFF; then
137 LOG "diff statistics:"
141 # add diff file itself
142 echo $DIFF >>$TMP/files
144 # add changed binary files
146 /^Index: / { scan = 1; file = $2; next }
147 /^@@/ { scan = 0; next }
148 /^Binary/ { if (scan) { print file } }
149 ' <$DIFF >>$TMP/files
155 LOG "checking for files to submit ..."
156 if [ -f $TMP/files ]; then
157 cat $TMP/files|while read i; do
162 grep "^? " $TMP/up|while read i; do
163 find ${i#? } -type f >>$TMP/check
167 # classify and filter files
168 if [ -f $TMP/check ]; then
169 for i in $(cat $TMP/check); do
171 $ARCHIVE*|$DIFF*) # don't add files generated by the script
173 */.*|.*) # silently drop hidden files
176 REJECT "$i\t\t(backup file)"
179 REJECT "$i\t\t(CVS file)"
181 *.blend|*.blend[0-9]|*.blend[0-9][0-9])
182 REJECT "$i\t\t(blender file)"
184 *.xcf|*.tga|*.bmp|*.BMP|*.png)
185 REJECT "$i\t\t(graphics file)"
189 echo "$i" >>$TMP/files
196 if ! [ -f $TMP/files ]; then
197 LOG "no changed or new files found"
202 numfiles=$(awk '//{n++}END{print n}' <$TMP/files)
203 if [ -f $DIFF -a $numfiles == 1 ]; then
204 LOG "only changed non-binary files found"
205 LOG "creating compressed diff \e[1;37;40m$CDIFF\e[m\e[35m ..."
209 LOG "changed and/or new files found"
210 LOG "creating archive \e[1;37;40m$ARCHIVE\e[m\e[35m ..."
211 tar -cjf $ARCHIVE --files-from $TMP/files
215 [ -x "$UPLOAD" -a -f $RESULT ] && $UPLOAD "$PWD" $RESULT $DIFF