2011-12-24

Subversion Tutorial

I figured I'd put this tutorial together for those who are struggling to grasp the concept or commands in SVN. I have also had to reproduce this tutorial for more than one company, so I wanted to generalize it for anyone new to SVN.

Installing a command-line SVN client

Windows
Windows users can goto SlikSVN and install the client from there.


Linux
Linux/Mac users should first type

which svn

to see if they have subversion installed. If not, Debian-based users can type:

sudo apt-get install -y subversion

RHEL based users can use:
sudo yum install -y subversion


OSX
Mac OSX users can use MacPorts or Homebrew to install their cli-subversion client.

brew install subversion

or

sudo port install subversion


Configure Your Subversion Client

Windows
After you have run the installation package for both subversion and gnuDiff, make sure the binaries are added to your system path.

  1. Start -> Run -> sysdm.cpl
  2. Click the "Advanced" tab in the System Properties window.
  3. Click the "Environment Variables"
  4. Another dialog box will pop up.
  5. In the System Environment variables, search for the variable called "PATH".
  6. Edit this variable. If you must, copy the content of the path variable to a text editor.
    • HINT: To make things easier to read, replace all ";" with "\n" and each path will have it's own line for editing purposes. This of course only applies if your text editor has support for escape sequences.
  7. Ensure that this path variable contains the contents of where you installed SlikSVN. For example, if you installed to C:\Program Files\SlikSVN\, then make sure C:\Program Files\SlikSVN\bin is in the PATH variable.
  8. Copy the contents of this and replace it back into the system variable box.
  9. Click "ok" to set the new PATH variable.
SVN also uses another variable for the environment for when committing changes to a site. If the variable does not exist, create "SVN_EDITOR".

For Windows users, you can either set it to "EDIT" or "NOTEPAD" whichever is your preference.

WARNING: Notepad++ has a funny way of editing files that includes closing the file stream after the file has been opened. It is not recommended to use Notepad++ as your text editor in conjunction with SVN for this reason.
Click ok, ok, ok ^ 3000. If you had a CMD open, close it, then re-open it to get the new environment variables.

Linux/OSX
For linux/mac users, edit your ~/.bashrc file to set this variable when you start your console. You can set it to your favorite text editor such as kwrite, gedit, bluefish, quanta, leafpad, vi, vim, or even nano. Add this to the end of the file:

export EDITOR=[YOUR_EDITOR];
export PATH=$PATH:.:[SVN_PATH]
  • Replace [YOUR_EDITOR] with your editor of choice.
  • Replace [SVN_PATH] with the directory name to your SVN executable.
  • This applies only if that directory is not already in the path.
If you are still having issues with the text editor after trying out SVN, try setting the EDITOR variable to the absolute path to the text editor of your choice. If you don't know the absolute path, you can always use this:
export EDITOR=`which [YOUR_EDITOR]`;

Windows
EDIT is a command-line based editor and has no .exe, so you shouldn't have issues with this.

From here you should be able to run

svn
help

in the command line. Documentation is included in the package. This should be good enough to get you started, but I'm going to delve a little further into this SVN stuff for good reference ^_^


Linux/OSX
NOTE: If any of these commands do not work (e.g. You get a "svn: Can't open file '.svn/lock': Permission denied") Your best bet would be to ensure you have read/write access to the .svn directories in the project folder. Alternately, you can add "sudo" before every svn command. Sudo invokes root privilages for a user or command for a short period of time and is considered a much more secure alternative to su. For sudo to work, you must be in the /etc/sudoers file as defined by the configuration. For more information on sudo, please see the documentation:

man sudo



General Help

Please note that I have omitted a few things from this tutorial for simplicity. Please see the http://linux.die.net/man/1/svn or type:
svn [command] --help

for more information.



Checking out a Repository

Syntax:
svn checkout [URL] [Path] [-r [Revision]]


_OR_

svn co [URL] [Path] [-r [Revision]]

Parameters:

URL- Required. The URL of the location of the checkout (e.g. svn://example.com/myProject/trunk)
Path- Optional. The local path where the subversion is checked out. If this path is omitted, it will create a directory in your current working directory named after the base directory of the SVN checkout (e.g. will create ./trunk)
Revision- Optional. The number of the revision you wish to checkout. Defaults to the most recent revision.
Once you run this command and the directory is created your subversion is setup and you are ready to work on your project. Be warned, however, upon checking out your first copy, you will create a directory called ".svn" in each directory that is in the repository. These .svn folders keep metadata about your working copy. Alter one of these files, and you're likely to break your working copy. If this happens, you will have to re-checkout the most recent copy and re-do your changes. Also please note: if you break your current working copy with this method (either accidentally or other), try not to just copy directories in their entirety. Only copy files individually or open the files and edit them manually; for copying the directory in its entirety will only break the working copy again... (a lesson learned the hard way by your's sincerely, J).
To take a working copy out of subversion control, you can execute the following command on *nix-based systems:

find [dir] -type d -name .svn -prune -exec rm -Rf {} \;

Where "[dir]" is the location you want to remove from version control.


See
svn co --help
for more info.


Committing a Project

Syntax:
svn commit [-F [File] --log-file -m [message] ]

_OR_

svn ci [-F [File] --log-file -m [message] ]


Optional Parameters:
-F- Optional. Attach a log file.
File- The location of the log message
--force-log- Optional. Forces SVN to recognize the parameter for -F to be a log file
-m- Optional. Attach a message.
message- The message to be sent
NOTES:
If -F and -m are omitted, SVN will launch the environment variable "SVN_EDITOR" as the text editor to create a log file to attach to this update. Therefore, if you keep a local CHANGELOG file on your development server, you can easily track changes you've made to the site in addition to skipping this tedious task of remembering what changes you might've made to the site.

Running this command will commit your latest changes to the repository.
See
svn ci --help
for more info.

Viewing A Revision's Log

Syntax:
svn log

This is a handy tool that allows you to see all your changes over the course of the updating of the project. This is the entire log file for all the changes that have been made on the project and is the reason why is is strongly recommended that you remove the contents of your CHANGELOG after every commit.
See
svn log --help
for more info.

Updating A Revision

Syntax:
svn update

_OR_

svn up

This will bring your current working copy to the most recent revision. If any conflicts are discovered during this update, (e.g. you have a file more recent than the repository) SVN will prompt you as to what you want to do.
Options for reference are as follows:
e(E)dit- Edit the current file to resolve conflicts. Launches %SVN_EDITOR% or $SVN_EDITOR
r(R)esolved- Available after selecting the "e" option. After you've edited and saved changes, you can classify them as "resolved" meaning your saved temp file will become your local copy of the file in question.
df(D)iff-(F)ull- Runs "diff" on the local working copy and the repository's
mf(M)ine-(F)ull- Drops the current repository's changes and keeps your local copy of this file in question.
tf(T)heirs-(F)ull- Drops all your local changes and overwrites the file with the repository's copy of the file in question.
h(H)elp- Get some more info on available commands.
See
svn up --help
for more info.

Resolving Conflicts

When you find conflicts, you will have the option to edit the files, find the differences, and resolve them. You will find globs of text that follow a format similar to this:

--- old 2011-04-25 13:39:37.000000000 -0400
+++ new 2011-04-25 13:40:01.000000000 -0400
@@ -3,8 +3,8 @@
auctor, dui in hendrerit ultricies, est enim faucibus dui, sit amet lobortis orci ligula sed orci.
Maecenas dictum bibendum nisl, vel mattis nulla pretium id. Praesent dignissim convallis tellus, vel
bibendum tellus euismod a. Mauris tincidunt ipsum magna. Quisque sodales convallis dictum. Etiam eu

-ante velit. Donec sed magna nisi, in tincidunt ipsum. Class aptent taciti sociosqu ad litora
-torquent per conubia nostra, per inceptos himenaeos. Ut lectus arcu, feugiat at laoreet ac,

+ante latin. Donec sed magna nisi, in tincidunt ipsum. Class aptent taciti sociosqu ad litora
+torquent per conubia ora nostra, per inceptos himenaeos. Ut lectus arcu, feugiat at laoreet ac,

dignissim vel elit. In posuere massa vel metus suscipit euismod. Sed eget purus lacus, vel accumsan
dui. Sed ut nisl eget dui blandit molestie nec gravida ligula. Duis et pulvinar justo. In eu enim
sit amet nulla accumsan vestibulum non at sapien. Integer viverra cursus odio. Suspendisse placerat

This has been color-coded to help determine the general syntax of this diff command.


Reverting Changes

Syntax:
svn revert

If you update and you have issues, this command may come in handy in a pinch. This command will revert all changes since the last update.
See
svn revert --help
for more info.

Adding Files

Syntax:
svn add [File]
_OR_
svn add [File1] [File2] [File3] ...
This command will add files to the subversion repository.
See
svn add --help
for more info.

Removing Files

Syntax:
svn remove [File] [--keep-local]
_OR_
svn delete [File]
_OR_
svn rm [File]

If --keep-local is used, svn will keep the local copy of the file in question and will only remove the subversion's copy and also remove it from svn control. Otherwise, delete local copy + repository's copy.
See
svn rm --help
for more info.

File Status

Syntax:
svn status

If you make changes to the local working copy and you loose track of what files were changed, this handy little command will tell you what files have what status in the local working copy. The prefix before the files determines their current status.
See
svn status --help
for more info.


SVN Properties

We're gonna throw a curve into the mix because it has been requested so many times, and I find this feature of SVN to be so darn useful. There are these things you can use called properties which can be set on directories and files. Some of these properties are set automatically, while others must be set manually. Each property has its own features and rules, however I'll only explain the two most frequently used here. This should be enough to get the general concept of it so you can reference the documentation and easily pickup the syntax for the other properties.

SVN:Ignore

Syntax:
svn propset svn:ignore [-F file] [Directory]
This will tell SVN to ignore files and folders in the specified directory based on the rules defined in the contents of the file. Explinations are best with an example...
Let's assume you have the following directory structure (a Zend Project):

zf-project
├── application
│   ├── Bootstrap.php
│   ├── controllers
│   ├── models
│   ├── modules
│   ├── setup.php
│   └── views
│   └── scripts
├── cache
├── library
│   ├── App
│   └── Zend
├── public
│   └── assets
│   ├── css
│   ├── images
│   └── js
├── run
├── saveState
└── tests
└── bootstrap.php
All of these except for `run' and `saveState' are in the repository, but you're getting annoyed by the constant reminder in SVN that those files aren't under version control. You can tell SVN to ignore those files that aren't under version control by setting the svn:ignore property on the current working directory. To do this, it's best for self-documentation purposes if you add a .ignore file in the current directory and add it to version control. That way other people working on the project can see what files/directories aren't under SVN control and want to be ignored. The .ignore file will have a newline-delimited list of files and folders to ignore based on a shell pattern. This particular project would have the following .ignore file:
run
saveState
Next, you specify this file on the command to set the ignore property:
svn propset svn:ignore -F .ignore .
This will tell SVN to ignore files and directories in the current working directory based on the rules defined by the file. Since `run' and `saveState' are specified in the file, all files and folders with those names will be ignored, and you won't see them with the question mark in `svn stat'
NOTE: svn:ignore does not work recursively. If you try to specify files inside of directories, you will find those files are not ignored. If you want to exclude files within directories, you'll have to set the property on that directory according to the rules of files you want ignored. A prime example of this would be if you wanted to ignore everything in the `cache' directory. To ignore all files in said directory create `cache/.ignore' and add that to version control. Next, add this to cache/.ignore:
Another Note: The .ignore files are not required. It's a semantic I include in this tutorial to make things easier for other developers. It would be just as possible to simply deal with the properties directly, but having a file under version control that helps make these properties easier to manage.
*
That's it! Next, run this command to set the property:
svn propset svn:ignore -F cache/.ignore cache/
Next thing you know, if you run `svn stat' on cache, you find that everything that wasn't under version control is removed from the listing! This same philosophy can be used to wildcard filenames as well. For example, to ignore all .old files, add "*.old" to your .ignore file, and set the property.
See
svn propset --help
for more info.


SVN:Externals

Sometimes you're working on a project and you have a library of code that is maintained by someone else who also uses SVN. You want to include their library in your project, and so you checkout a copy of their work into your SVN repository. However, you want everyone else who checks out a copy of your project to follow this same checkout so the library can be used. This can be accomplished with the SVN:Externals property. The syntax of the SVN:Externals property is a bit different from SVN:Ignore in that you must specify the URL to the repository that will be used in the external checkout. To better track where externals occur, it's best to keep a single file in the root of your project called `.externals'. The syntax of the .externals file is as follows:
[Directory] [Repo-URL]
Where [Directory] is the target local directory that will contain the checkout, and [Repo-URL] is the URL to the checkout. Lets say in our Zend project described in the SVN:Ignore section needs to have the Zend library checked out in the `library' directory. Place this in your .externals file:
library/Zend    http://framework.zend.com/svn/framework/standard/trunk/library/Zend/
You can run this command to set the property:
svn propset svn:externals . -F .externals
Now when you run `svn up' in the root of the project, you will see it extract from the external repository. This is a very handy method to include externals and link your project to other repositories.
<====================================================>

Conclusion

That's all I can think of for now that will prepare you for what you may encounter. If you need any further help hit me up and I'll do the best I can to help. Should I find that this could use some more detail in some places, I'll make changes accordingly.
-Kizano

No comments:

Post a Comment