Using Revision Control Software: GIT, Subversion, CVS, RCS

git, svn, cvs, and rcs are revision control software that is available on our system. rcs is often sufficient for managing your private projects, and git, svn and cvs are useful for managing group projects.

git, svn, and cvs allows you and your group members to create a repository for your project source, to each check out your own working copies of your project's source, to commit changes to the repository, to checkout previous committed versions of your code from the repository, to automatically merge in changes made by your project partner(s) into your working version, to create labeled versions of your code, which is useful when using a stable, labeled, previous version as a starting point for other code (you can check out this labeled "starting point" version of your repository code even after more changes have been committed to the repository), to create distinct code branches, ....

Which one is right for you? For most group projects it really doesn't matter.

There are links to more references at the end of each section.

git Basics

Below is some information about using git for CS course projects with partners. The first step is to set up a master repository for your shared project, then you and your partner can check out working versions in your own private subdirectories, and push/pull changes to/from the master copy.

Setting up a master repository to share a project

one of you or your partner should do the following:
  1. Create a new personal repository:
    1. cd into your private subdirectory containingstarting point project code
    2. git init: place existing stuff under git revision control. this creates a .git directory with all git stuff
    3. git add: add everything in project directory to git
    4. git commit: commit everything to your repository
      $ cd project	# create a project directory and cd into it
      $ git init
      $ git add .   # add all files from top-level project directory
      $ git commit
      
  2. Next, create a public repository in /local of some machine using git clone --bare. This will be the master repository from which you and your partner will clone, push, pull etc.
    # create a directory into which the master repository will go:
    $ ssh lemon               # I'm going to use lemon's /local			
    $ cd /local	
    $ mkdir tiajeffcs75       # create a directory in /local and make sure it is private  
    $ chmod 700 tiajeffcs75
    
    # now create the master copy of this project using clone --bare   
    $ cd /local/tiajeffcs75
    $ git clone --bare ~/project/.git project.git
    $ ls
    project.git/
    
  3. Next, run easyfacl.py to set acls on the master repository so that all the members of your group can access it
    # on lemon:
    $ cd /local
    $ esayfacl.py
    
    note: any time you add a new git repository in you /local directory, you need to run easyfacl.py to re-set acls on it.
At this point, you now have a master repository for your project, that only you and your partners can access. All changes, additions, deletions, to this project can be done with git commands on this master copy.

Using a shared repository

After creating the master copy of the repository, both you and your partners should checkout a working copy from the master repository in your own private subdirectory of your home directories (you can remove the private copy that you used to create the master copy in step 1, as you should work in a copy checked out from the master):
$ cd
$ mkdir cs75
$ cd cs75
$ git clone your_user_name@lemon/local/tiajeffcs75/projecct.git
From your working copy, you can then add files, commit your changes, and push and pull changes to the master. Here a a few common commands:
# add a new file to the next commit:
$ git add foo.c

# add your changes to an existing file to the next commit:  
$ vi blah.c       # edit a file in    
$ git add blah.c  # add your changes to the next commit

# commit your changes (adds and deletes) to the repository:
$ git commit

# push the changes to the master
$ git push

# pull changes to the master by someone else into your working copy:
$ git pull

some useful commands:

git help      # list common git commands  git help --all lists all commands
git add       # add changes or new files to the next commit 
git rm        # remove a file at the next commit
git commit    # commit your changes to your local repository
git push      # push your committed changes to the master repository
git pull      # pull changes pushed to master into your local copy (git will try to merge changes into your copy)
git mv
git diff      # see a diff between your copy of a file(s) and the master repository's version
git status    # see what has changed between your copy and the master version

See the git user's manual and/or git man pages (man git-clone, e.g.) for more commands.

References

git homepage
git documentation
git user's manual
converting cvs repository to git


Subversion Basics

If you haven't used any revision control software before, svn is probably the one I'd recommend for group projects (RCS is likely fine for individual projects).

The first step is to send a request to local-staff for a svn repository to be made for your project. Send local-staff the user names of you and your partner(s) who will be sharing the repository. See the following link for more information about how to make this request, and more information about using svn: svn on our system

svn keeps a history of all changes to files in the repository. Each time a change to a file is committed to the repository, the global revision number is incremented. The log command will let you see the revision numbers associated with committed changes to a file, and the messages that were included as part of the commit. You can use the revision number with most svn commands to grab older versions of a file from the repository or to list diffs between versions.

Briefly, here are some svn commands that may be useful:



 svn checkout: checkout a working copy of a repository
*  After your repository is created, you will need to check out a working copy
   into one of your subdirectories to begin editing it. You do this 
   with the svn checkout command: 
	 
	 # from within ~/cs75/project/ for example, do this: 
	 o svn checkout http://svn.cs.swarthmore.edu/svn/nameofrepos 

* All svn commands will prompt you for your username and password. This will
  default to your cs username. If your cs and svn usernames differ, hit enter
  once, and it will prompt you to enter a username. You can then enter your
	password.  You can configure svn to store passwords and then it will not
	ask for your password every time.  See the config notes below for how
	to do this.
svn add: add new files/directories to a repository
* To add files to the repository, which you must do every time you create a new
  file, use the add command (while in the working copy): 
	
	o svn add filename

  The file will not be added to the repository until you do a svn commit 
	
	o svn commit filename 
svn remove: remove a file from a repository
* Removing is the same as adding, except with the command remove instead of add.

       o svn remove filename
svn commit: commit changes to the repository
* To commit changes, file adds, and file removes, use the command:

       o svn commit

   This command will automatically bring up your favorite text editor asking
   you to input a message (if you don't like the editor it thinks is your
   favorite, then set your VISUAL environment variable in your .bashrc file
   to point to the editor you want (add the line: export VISUAL=/usr/bin/vi). 

   If you want to include the message on the command line, use:

       o svn commit -m "message in quotes"
svn status: to see what has changed in the repository
* To see if there are any changes to the repository (someone else committed file adds, removes, or changes): 

	# lists status of files that differ from repository version 
	#  M means you have modified your version, 
	#  * means that the is a newer version in the repository (someone committed change) 
	#  C means that there are conflicts to this file that occurred during 
	#    a merged update 
	# repository has a newer version than you do 
	
	o svn status -u 
	   M              15   foo.c 
	            *     16   blah.c
svn diff: to see diffs between your file and repository version
* To see the diff between your file and the version you checked out:

       o svn diff filename

* To see the diff between your file and the version in the repository: 

	# first get the revision number of the current version in the repository 
	o svn status -u 
	
	...  output about status of files  ...  
	
	Status against revision:     16 
	
	# then do a diff between that revision number an your version: 
	o svn diff -r 16 foo.c 
svn update: to grab new versions of files from repository
* To grab changes that someone else committed to the repository (svn will
  try to merge changes into files in your checked out version): 
	
	# update just file foo.c
	o svn update foo.c

	# update the contents of current directory 
	o svn update 
svn resolved: if there are conflicts during update

If there are conflicts that occur during update (say of foo.c), svn creates two files:

  1. foo.mine contains the contents of your copy from before update
  2. foo.r16 (if foo's current revision number is 16) contains the contents of the current version of the file in the repository.
  3. and foo.c contains svn's failed attempt at merging the two files together
When there is a conflict, the file's status is marked as C, and you cannot commit changes to it until you first resolve the conflict.

The most common way to resolve the conflict is is to hand merge what svn couldn't in the foo.c file. Errors in merging appear like the following in the file:

 
	<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< 
	
	code from your foo.c  at the lines where merge failed 
	
	============================ 
	
	code from the repository version of foo.c at the lines where merge failed 

	>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 
You can fix up the code by hand using the two versions of the code as your guide.

Another option may be to just wipe-out foo.c and replace it with either foo.mine or foo.r16 (often, this is not the right approach).

However you resolve the conflict, you need to run svn resolved to tell svn that you have resolved it.

	o svn resolved foo.c
To revert to a previous version of a file

svn help

* Find out more about svn commands

       o svn help

* Find out more about a particular command (update here)

       o svn help update
svn config options: If svn asks you for your password every time you run it, you can change this behavior by having svn store passwords. To do this:
in /home/username/.subversion/config,
 
there is a line:
 
  store-passwords = no
 
if the line is commented out or reads store-passwords = yes, then passwords will be stored
If you do not like the editor that svn pops up when you commit a change to the repository, you can change this by setting your VISUAL environment variable. In bash:
in /home/username/.bashrc

# to set it to use vim 
export VISUAL=/usr/bin/vim

# to set it to use emacs 
export VISUAL=/usr/bin/emacs

References

Using subversion on our system
Version Control with Subversion, by Ben Collins-Sussman, Brian W. Fitzpatrick, C. Michael Pilato


RCS Basics

Create a subdirectory named RCS in your private working directory:
% mkdir RCS
Check in files you want to add to the repository (this moves them into the RCS repository):
% ci foo.c
% ci blah.c
Check out file you want to work on (-l locks the file so only you can check it out to modify it):
% co -l foo.c
% co -l blah.c
Subsequent check-ins create a new version of the file, and you can revert to older versions by using the -r flag with co (see the man pages for co and ci for more details).

Some other commands (and see man page for rcsintro):

$ rcsdiff foo.c    # diff between foo.c and latest version in repository
$ rlog  foo.c      # see the log messages associated with commits to foo.c

References

RCS Mini-HowTo

CVS Basics

(see the on-line reference for a more complete explanation)

To use cvs you first need to (this is actually quite easy even though it looks like a lot of instructions):

  1. Create a repository for your shared code

    1. you will need to request from local-staff a unix group for you and your project partners so that you can set permissions for your repository
    2. One of you will have to store the repository in his/her home directory. From his/her homedirectory run the cvs init command to create your repository (here I'm calling it CVS):
        % cd 
        % cvs -d /home/yourusername/CVS
      
      Next, set permissions on your CVS repository so that only you and your partner(s) can access it:
       % chgrp yourgroupname CVS
       % chmod 770 CVS
      
    3. You can import files into your cvs directory using the import command, but first you need to set some environment variables:
      # for bash (you can put these in your .bashrc file):
      CVSROOT=/home/yourusername/CVS
      export CVSROOT
      CVS_RSH=/usr/local/bin/ssh
      export CVSROOT
      
      # for tcsh (you can put these in your .cshrc file):
      setenv CVSROOT /home/yourusername/CVS
      setenv CVS_RSH /usr/local/bin/ssh
      
      To import existing files into your repository:
      # from the subdirectory containing the files and directories you want to import:
      % cvs import -m "Imported sources" csproject tia_and_jeff start
      
      # -m is the message written to the log
      # tia_and_jeff is the vender name (you can choose your vender name)
      # start is the release number
      
      This will import all files and subdirectories from your current directory into the repository as a directory tree named csproject (csproject will be a directory you can checkout from your CVS repository). At this point you can remove the your local copies of the files you just imported into the repository, and then checkout new copies from the repository (this way they are under CVS control).

    4. Later, you can use cvs add (followed by cvs commit) to add new directories and files to your csproject directory tree, or you can use cvs import to add a new directory trees to your repository.

  2. Check out your own copy of the shared code to your private working directory, from which you can make changes without interfering with your partners' simultaneous changes.

    1. set your CVSROOT and CVS_RSH environment variables. In bash, for example (you can add this to your .bashrc file):
      CVSROOT=/home/partner_w_repository/CVS
      CVS_RSH=/usr/local/bin/ssh
      
    2. then from your private subdirectory into which you will put your checked-out version:
      % cd ~/private/csX/project
      % cvs co csproject
      

Once the repository is set up and you have checked-out your private copy, here are some common cvs operations:

# (1) from your working subdirector(ies) to see if any changes have been 
#     committed to the repository
% cvs -n update
M foo.c	      # your copy of this file differs from the repository version
U blah.c      # a change has been committed to this file, and your version is out of date 
C grr.c	      # you have change your copy of this file & a change was committed

# (2) to have cvs merge the committed changes into your working versions 
#     (its a good idea to make a copy of any files that you have changed
#      and have been committed so that if cvs's auto-merging fails you can
#      more easily fix the file by hand)
#     
% cvs update
C grr.c	        # this may indicate that cvs's auto-merge couldn't completely
                # merge the committed changes into this file and you may
                # need to fix this by hand

# (3) to commit your changes to the repository
#
% cvs commit filename.c   # commit just this file
% cvs commit              # commit all your changes to files in the current directory

References

CVS wiki
CVS Manual