2010-10-11

Subversion - How to use svn to manage source files

The "svn" command stands for Subversion. Subversion is commonly use to manage revisions of source files, e.g. configuration files & program source code. Subversion keeps revision what of have been change or committed into the repository. This is good when we accidentally change the source code and needs to roll back to the previous changes. It is also good for managing configuration files (e.g. /etc, /usr/local/etc) on servers as it provides revision control. We can roll back to the last working condition if we screw something up. :p

Here's how to start using svn to manage source files, for the first time :

Installation

In FreeBSD, this is how to install Subversion :
  • portmanager devel/subversion -l
In a mac, use macports to install Subversion :
  • port -v install subversion

svn repository creation

svn organize different project or sets of source files into repository. The repository store the changes of the source files into a directory. To start using svn, we'll need to create a svn repository :
svnadmin create [new repository path]
e.g.
svnadmin create ~/svn_repository/myfirst

Importing source files into the repository

Now that we have create a svn repository, we should store some files or directory into it. After all, we want to use svn to track changes of the existing source files we have.
To store directory into the svn directory, we "import" it :
svn import [source files directory] [URL] -m "message to include for this action"
e.g.
svn import public_html file:///home/user/svn_repository/myfirst \
-m "my first imported source files directory"
svn repository can be access using various method (known as URL). Since we're using this on a local file system, we should use file:/// URL schema. The file:/// schema is actually the path to the repository directory that we've created in the previous step. You should always use absolute path to avoid confusion.

Another example, to import just a file :
svn import [single source file] [URL/source_file_name] -m "message to include for this action"
e.g.
svn import index.html file:///home/user/svn_repository/myfirst/index.html \
-m "my first imported source files directory"

After adding files into the repository, we check what's in the repository. Here's 2 way of listing the contents of the repository :
  • using the "list" command:
    svn list [URL]
    e.g.
    svn list file:///home/user/svn_repository/myfirst
  • Better, a "tree" view of the repository :
    svnlook tree [repository path]
    e.g.
    svnlook tree ~/svn_repository/myfirst

Draw a working copy out of repository

Now, we have a repository that stores the source files. Is time to check does svn really work. If you're concern of this testing, feel free to backup a copy of the source file directory. Then, delete the original source file directory so that we can proceed to test how to "check out" a revision of a copy of source files from the svn repository.
To "check out" a copy of source files out of the repository :
(at the home directory)
svn checkout [URL] [destination name]
e.g.
svn checkout file:///home/user/svn_repository/myfirst public_html

This will check out a revision of a copy from the repository and name it "public_html" (like the previous name when we "import"). This copy of directory is commonly known as "working copy". If you look at every sub directory of "public_html", there will be a .svn directory. This shows that this is revision copy. From now on, we can make changes to any of the files in it and commit it (which we'll talk about it later) to the repository.

Status of "working copy"

After making changes (or not), we can check the "status" of the working directory to see what have been change, added or remove :
(within the working copy)
svn status

The first column symbol of the output means :
' ' no modifications
      'A' Added
      'C' Conflicted
      'D' Deleted
      'I' Ignored (possibly file is being exclude from svn)
      'M' Modified
      'R' Replaced
      'X' an unversioned directory created by an externals definition
      '?' item is not under version control
      '!' item is missing (removed by non-svn command) or incomplete
      '~' versioned item obstructed by some item of a different kind
Before we commit the changes, we should resolve the "?" & "!" indicated files.
  • "?" indicated files is mostly likely to cause by a newly created file in the "working copy". If the files need to be added to the repository, "svn add" the files.
  • "!" indicated that the file is missing or deleted from the "working copy". This is bad, as you're NOT suppose to delete the file directly. Instead, you should use the "svn delete" to delete it. So that svn will delete the repository copy and the "working copy". A resolution for this, is to restore the files from repository using :
    svn update [missing file indicated by "!"]
    Then, delete it through "svn delete".
    *** both "svn add" & "svn delete" will be discuss in the following section.

Common operation on "working copy"

After checking the "status" of the "working copy", you might need to add or delete from the repository in order to commit the changes with all the pending status. The are the common operations :
  • adding file into the repository using "svn add" :
    (in the working copy directory)
    svn add [file name]
    e.g.
    cd ~/public_html;
    svn add just_created.html
  • delete files from repository :
    (in the working copy directory)
    svn delete [file to be delete]
    e.g.
    svn delete redundant.html
  • to recover back missing file(s) of the "working copy" directory from the repository :
    svn update [missing copy file name]
  • view the log changes
    svn log
    optionally, specify parameter "-r" follow by a revision number to only view the logs of that particular revision.
    e.g.
    svn log -r 10
    This will show the logs for revision "10" only.

Commit the changes

Commit will sync the changes back to repository copy and add 1 to the current revision control.
e.g.
svn commit

Then, the screen will pass to your preferred editor (indicated by the EDITOR environment variable) to input some log messages. Save & exit the editor to proceed the commit operation. After the "commit" process has finish, it'll be a good idea to update the "working copy" from the repository by issuing :
svn update

Additionally, these are some svn operation that I find it useful :
  • Draw a single file or directory (without revision information) from the repository :
    (any directory other then the "working copy")
    svn export [URL of the single file or directory]
    e.g.
    svn export file:///home/user/svn_repository/myfirst/foo.html
    or
    svn export file:///home/user/svn_repository/myfirst
    One might use tab to construct the URL path but you might see some weird files when it start listing the files in "myfirst/" directory. Those are the internal working files of the svn repository we've created. You should use "svn list" to check the contents of the directory & file name then type the file name by hand, and NOT using tab.

    Note : an exported single file or directory will have no revision information and thus you can export it to anywhere. But a "check out" copy is different. It is a "working copy" that contains revision information so that we can "work" on it and sync the changes back to svn repository.
  • Check the current version of the working copy
    (in the "working copy" directory)
    svnversion
    • if it display digits only, this means the working copy revision is committed and no changes to the current working copy.
    • if there's a "M" character follow the digits, the working copy is modified and waiting to be committed.
    • if the digits are separated with ":" (colon), usually this happens after "commit" and needs a "svn update" to update the current "working copy" to match the repository
    • check the difference of two revision files :
      (in the "working copy" directory)
      svn diff [file name]
      e.g.
      svn diff index.html
This sums up on how to use svn to manage source files.

Tips

  • How to ignore/prevent/exclude file from svn?
    Use the "propset" command with the "svn:ignore" value to set the property of a file.
    Syntax :
    svn propset svn:ignore [glob] [directory]
    E.g. :
    • svn propset svn:ignore '*.tmp' .
      This will prevent all files with .tmp extension (of the current directory) from svn versioning.
    • svn propset svn:ignore '*.log' logs/
      This will prevent all files with .log extension in the "logs" directory from svn versioning.
    • How to ignore/prevent/exclude multiple files from svn?
      Use the parameter "-F" on command "propset".
      Syntax :
      svn propset svn:ignore -F [exclusion text file] .
      E.g. :
      svn propset svn:ignore -F exclusion.txt .
      where "exclusion.txt" is a file containing glob on each line.
      For exclusion.txt file containing :
      *.log
      *.tmp
      would exclude files with extension .log & .tmp .
  • Below are some scenarios that I've bump into and how to solve them.
    • Revert the entire revision of the current working copy to an older (or other) revision (EXTREMELY DANGEROUS !!!)
      For some reason, you find it faster to rollback the changes by reverting to an older revision. This is how to do it :
      svn merge -r 4:1 file:///home/user/svn_repository/myfirst
      This will revert the current version (4) to oldest version (1). Do take note that after performing this operation, all current changes will be lost and the working copy will revert to version 1 state.
    • How to change current repository name to a new name
      1. Create the new repository (the new name) :
        svnadmin create new_repo
      2. Dump the current repository to a file :
        svnadmin dump ~/svn_repository/old_repo > old_repo.dump
      3. Load the dump file from the previous step to the new repository :
        svnadmin load ~/svn_repository/new_repo < old_repo.dump
      4. Optional : Delete the old repository by :
        rm -rf ~/svn_repository/old_repo
        This will completely wipe the whole repository.

Caveat

  • After excluding some files, the below error message appears :
    svn: Commit failed (details follow):
    svn: File '/just_created.html' is out of date
    Solution :
    Issue "svn update" and fix the conflicts then try again.
This post only covers some of the common operation. Subversion offers other powerful features for more complex use. Do refer to the Subversion book, a free book from O'Reilly. That's all for now, Ciao !!!

No comments: