Simple BASH version control
Posted: Fri Oct 02, 2009 6:09 pm
Hi all,
These last few days have had me ripping my hair out because of version control. The only supported version control package for my OS (SuSE 11) is CVS. That won't work for me because I don't want to have to check out the file, edit it, save it, and commit it for every change I want to make.
What I wanted was a version control system that would leave the files right where I put them, lock other users out from editing the file, allow me to see my changes when I loaded the page up in my browser, and keep track of the revisions. So, I took a few hours today and wrote my own. I'm sharing the commands here in the hope someone else can use them, or see a way to improve on it.
I had to make a few system tweaks to get this to work flawlessly. Namely:
There's no diff or rollback functionality. I figured you can manually call diff if necessary, and copy one of the revisions into the working copy if you need to.
I am very interested to see what other people think. Did I re-invent the wheel? Is this version control system all but useless? Am I a genius?
Here are the files:
vco:
vci:
The commands are invoked like this:
These last few days have had me ripping my hair out because of version control. The only supported version control package for my OS (SuSE 11) is CVS. That won't work for me because I don't want to have to check out the file, edit it, save it, and commit it for every change I want to make.
What I wanted was a version control system that would leave the files right where I put them, lock other users out from editing the file, allow me to see my changes when I loaded the page up in my browser, and keep track of the revisions. So, I took a few hours today and wrote my own. I'm sharing the commands here in the hope someone else can use them, or see a way to improve on it.
I had to make a few system tweaks to get this to work flawlessly. Namely:
- I had to give all the users who will be using these commands the ability to use `sudo` to `chown` the file they check out. This was the only way to obtain a write lock on the checked out files.
- I had to move both the checking out and checking in scripts to /usr/local/bin so the commands would be in the user's path - so they can be called without needing to provide the full path
There's no diff or rollback functionality. I figured you can manually call diff if necessary, and copy one of the revisions into the working copy if you need to.
I am very interested to see what other people think. Did I re-invent the wheel? Is this version control system all but useless? Am I a genius?
Here are the files:
vco:
Code: Select all
#!/bin/bash
# Only continue if a file was specified
if [ $# = 0 ]; then
echo 'No file specified'
exit 0
fi
FILE=$1
LOCKFILE="VC/"$FILE".lock"
CURRUSER=`whoami`
# Make VC subdirectory if necessary
if [ ! -d VC ]; then
echo "Making 'VC' directory"
mkdir VC
fi
# check if the user has obtained the lock
if [ -f $LOCKFILE ]; then
CONTENTS=`cat ${LOCKFILE}`
if [ "$CONTENTS" = "$CURRUSER" ]; then
echo 'You already have the file checked out'
exit 0
else
echo "The file is already checked out by $CONTENTS"
exit 0
fi
fi
# obtain the lock
sudo chown $CURRUSER $FILE
# create lock file
echo $CURRUSER > $LOCKFILE
# allow writing by owner
sudo chmod 644 $FILECode: Select all
!/bin/bash
# Only continue if a file was specified
if [ $# = 0 ]
then
echo 'No file specified'
exit 0
fi
FILE=$1
NEWDATE=$(date +"%Y-%m-%d_%T");
NEWFILE=$FILE"_"$NEWDATE".txt"
MESSAGE='VC Log Message:'
##
# Function: getMessage
# Purpose: To retrieve the log message from the user
##
function getMessage
{
LINE=''
echo "Log message:"
echo "End with a single period '.'"
while [ "$LINE" != "." ]
do
read -p ">>" LINE
MESSAGE=${MESSAGE}"\n"${LINE}
done
# trim newline from beginning of string
MESSAGE=${MESSAGE#"\n"}
# trim newline and period from end of string
MESSAGE=${MESSAGE%"\n."}
MESSAGE=${MESSAGE}"\n##############################";
}
# Make VC subdirectory if necessary
if [ ! -d VC ]
then
echo "Making 'VC' directory"
mkdir VC
fi
# check if file is writable (so one can't check in a file one hasn't checked out)
if [ -w $FILE ]
then
# retrieve log message
getMessage
# prepend the message to the beginning of the version file
echo -e $MESSAGE >> VC/$NEWFILE
# copy the contents of the file into the version file
cat $FILE >> VC/$NEWFILE
# copy the contents into the latest version file
cp VC/$NEWFILE VC/$FILE"-latest.txt"
# unlock the file
# don't change ownership because
# a) who would you change it back to?
# b) checking out the file is done via sudo, so it doesn't matter
#
chmod 444 $FILE
rm -f VC/$FILE".lock"
else
echo "You haven't checked out this file"
exit
fiCode: Select all
vco myfile.php
vci myfile.php