Simple BASH version control

Coding Critique is the place to post source code for peer review by other members of DevNetwork. Any kind of code can be posted. Code posted does not have to be limited to PHP. All members are invited to contribute constructive criticism with the goal of improving the code. Posted code should include some background information about it and what areas you specifically would like help with.

Popular code excerpts may be moved to "Code Snippets" by the moderators.

Moderator: General Moderators

Post Reply
User avatar
pickle
Briney Mod
Posts: 6445
Joined: Mon Jan 19, 2004 6:11 pm
Location: 53.01N x 112.48W
Contact:

Simple BASH version control

Post by pickle »

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:
  1. 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.
  2. 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
When checking out a file, the vco command creates a lock file, changes the ownership of the file to you, and changes the mode to 644 - which means only you can write to it. When checking in the file, the vci command asks you to provide a log message. It then creates a timestamped copy of the file in the VC subdirectory (that is automatically created when vco is invoked) with your message at the top. It also copies the latest version into a "-latest.txt" file. Finally, it removes the lock file and changes the mode back to 444. The idea being that you can't edit the file unless you've checked it out.

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 $FILE
vci:

Code: 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
fi
The commands are invoked like this:

Code: Select all

vco myfile.php
vci myfile.php
Real programmers don't comment their code. If it was hard to write, it should be hard to understand.
alex.barylski
DevNet Evangelist
Posts: 6267
Joined: Tue Dec 21, 2004 5:00 pm
Location: Winnipeg

Re: Simple BASH version control

Post by alex.barylski »

So you can't install SVN under SuSE? Why, if you don't mind my asking, just out of curiosity?
User avatar
pickle
Briney Mod
Posts: 6445
Joined: Mon Jan 19, 2004 6:11 pm
Location: 53.01N x 112.48W
Contact:

Re: Simple BASH version control

Post by pickle »

We could install SVN, but there's no default package provided by Novell. In the interests of wanting to decrease maintenance efforts, we only install packages that are provided & supported by Novell.

Plus, as far as I know (which admittedly isn't very far), Subversion works like CVS in that it holds a central repository of code that you would download, compile, and run. I needed version control that would allow me to check out, edit, and check in files in-place on the server, as that's the development environment.
Last edited by pickle on Thu Oct 08, 2009 11:53 am, edited 1 time in total.
Reason: Changing "SuSE" to "SVN"
Real programmers don't comment their code. If it was hard to write, it should be hard to understand.
User avatar
Jenk
DevNet Master
Posts: 3587
Joined: Mon Sep 19, 2005 6:24 am
Location: London

Re: Simple BASH version control

Post by Jenk »

SVN allows you to check out and check in any directory from a repository. Infact, you must check out a directory (you can't checkout individual files) but sub-directories are fine. I do it all the time with a project we have that is ~1GB in size.

I'm also sure that Subversion is available on Suse, from Suse10 and on.
User avatar
pickle
Briney Mod
Posts: 6445
Joined: Mon Jan 19, 2004 6:11 pm
Location: 53.01N x 112.48W
Contact:

Re: Simple BASH version control

Post by pickle »

Yes Subversion lets you check out & check in, but when you check a file out, you download it to your local copy. I wanted something that didn't move the file - so I could edit it in place on the webserver until my changes were done, then check it back in.

Is Subversion available as an official package from Novell on SuSE 11? Are you sure it's not just an RPM from a third party, and that you're not referring to OpenSuSE?
Real programmers don't comment their code. If it was hard to write, it should be hard to understand.
User avatar
Jenk
DevNet Master
Posts: 3587
Joined: Mon Sep 19, 2005 6:24 am
Location: London

Re: Simple BASH version control

Post by Jenk »

I may be referring to opensuse, but didn't think it an issue to simply add the extra repo to yast.

I'm not sure I see the benefit of 'editing in place' over creating a working copy, then committing.
User avatar
pickle
Briney Mod
Posts: 6445
Joined: Mon Jan 19, 2004 6:11 pm
Location: 53.01N x 112.48W
Contact:

Re: Simple BASH version control

Post by pickle »

If we edit in place, then I don't have to worry about setting up a LAMP stack on my workstation, just so I can test my code, before committing it again. If it's in place, I can check it out, work on it in place until the code does what I want, then check it back in.

The issue with Subversion isn't that we can't figure out a way to install it - it's that Novell doesn't provide the package.
Real programmers don't comment their code. If it was hard to write, it should be hard to understand.
User avatar
Jenk
DevNet Master
Posts: 3587
Joined: Mon Sep 19, 2005 6:24 am
Location: London

Re: Simple BASH version control

Post by Jenk »

http://www.novell.com/products/linuxpac ... rsion.html

If you are editing in place, how are you going to perform a check-out, test, and check-in? You won't. And it'll also directly affect your live deployment whilst it is developed.

I don't see the issue of installing a LAMP stack on your workstation.. you are a developer after all. It takes 5 minutes to install Apache, MySQL and PHP on any workstation, Linux or other. :)
User avatar
pickle
Briney Mod
Posts: 6445
Joined: Mon Jan 19, 2004 6:11 pm
Location: 53.01N x 112.48W
Contact:

Re: Simple BASH version control

Post by pickle »

We're running SLES 11 :)

Testing will be done on the box. This application won't be in production while we're developing it.

We had an issue with another developer building a working copy of a feature for an application on his workstation - but when he uploaded it to the development server, it was configured slightly different so the whole feature had to be re-written. I want to avoid that.
Real programmers don't comment their code. If it was hard to write, it should be hard to understand.
User avatar
Weirdan
Moderator
Posts: 5978
Joined: Mon Nov 03, 2003 6:13 pm
Location: Odessa, Ukraine

Re: Simple BASH version control

Post by Weirdan »

Post Reply