SVN Apache Subversion
Apache Subversion is a software versioning and revision control system distributed as open source under the Apache License. Software developers use Subversion to maintain current and historical versions of files such as source code, web pages, and documentation.
- https://subversion.apache.org/
- http://svnbook.red-bean.com/
- http://maverick.inria.fr/~Xavier.Decoret/resources/svn/
Common Commands
Checkout a remote repo
Checkout the my_repo
SVN repo starting from its html
directory, from the remote server at https://my.svn.server
into the webroot directory on a local machine.
sudo svn co https://my.svn.server/my_repo/html/ /path/to/webroot
Info about the local repo
# All iformation
svn info
# URL info
svn info | grep URL
Status of the local repo
svn st
svn stat
svn st -q # View locally modified items (does not list un-added items).
svn st -v # View full revision information on every item in the repo.
The first column from the output indicates that an item was added, deleted, or otherwise changed with the following codes:
Code | Description |
---|---|
`` | No modifications. |
A |
Item is scheduled for addition. |
D |
Item is scheduled for deletion. |
M |
Item has been modified. |
R |
Item has been replaced in your working copy. This means the file was scheduled for deletion, and then a new file with the same name was scheduled for addition in its place. |
C |
The contents (as opposed to the properties) of the item conflict with updates received from the repository. |
X |
Item is present because of an externals definition. |
I |
Item is being ignored (e.g., with the svn:ignore property). |
? |
Item is not under version control. |
! |
Item is missing (e.g., you moved or deleted it without using svn). This also indicates that a directory is incomplete (a checkout or update was interrupted). |
~ |
Item is versioned as one kind of object (file, directory, link), but has been replaced by a different kind of object. |
Update a local repo
This will update the local repo with any new information from the remote repo.
svn up
svn update
Add local files and directories
Files and directories with the status of ?
(not under version control) must be added to the repo before they are tracked.
Add a new file:
svn add file_name
Add all un-versioned files (except ignored) from a specified directory:
svn add --force path/to/dir
Delete local files and directories
NOTE: Do not remove files and directories unless you use the svn delete
command.
svn delete file_name
Rename local files and directories
NOTE: Do not rename or move files or directories unless you use the svn mv
command.
Commit local changes to the remote repo
Commit ALL changes to the repo:
svn commit -m "A descriptive message about what was accomplished."
Commit one or more specific files to the repo:
svn commit -m "A descriptive message about what was accomplished." my/first/file my/second/file
Ignore files and directories
- Ignored directories and files are defined in the
svn:ignore
property for a directory. - This property gets committed to the repo.
- The
svn:ignore
property is only defined on directories. - The definitions in the
svn:ignore
property only affect files and directories within it's directory. SVN does not ignore recursively (although there are methods to write thesvn:ignore
property recursively to a directory structure).
Example
This example shows how to ignore all .json
files in the root directory of a repo.
- Navigate to the root directory of the repo.
- Edit the
svn:ignore
property for the current directory by using thepropedit
command. Thesvn:ignore
property will open in your defined text editor:
svn propedit svn:ignore .
NOTE: Always use propedit
to edit properties in SVN. Never use propset
(example: svn propset svn:ignore 'my_file.txt' .
) because each use completely replaces the property definitions.
- Each
svn:ignore
property definition is on it's own line. - Each definition line is a "file pattern" or simply a file or directory name.
- Any number of definitions can appear in the property.
- The current ignore already contains:
*.DS_Store
*.project
*.sublime-project
*.sublime-workspace
- This is the complete list after adding the new file pattern line to ignore
.json
files:
*.DS_Store
*.project
*.sublime-project
*.sublime-workspace
*.json
- Save the
svn:ignore
property file after edits are complete to make the changes take affect. - Commit the ignored changes:
svn commit -m "Adding ignored files and directories to the app root."
- To see all properties set for the current directory and everything under it, run:
svn proplist -v -R
- Use SVN 'status' to see ignored items too:
# All files.
svn st --no-ignore
# Just ignored files.
svn status --no-ignore | grep "^I"
Repo History
Diff files
To see all changes currently not checked-in:
svn diff
To see all changes currently not checked-in to a specific file:
svn diff file_name
Compare two specific revisions:
svn diff -r 8979:11390
Compare the last committed state against the currently saved working files with convenience keywords:
svn diff -r PREV:HEAD
Using svn diff
without a specified file path will show all files with changes in the revision. Limit a diff to compare a specific file by adding the file path to the end of the command:
svn diff -r 8979:HEAD /path/to/my/file.php
View the last commit number
svn info --show-item last-changed-revision
View all the commits to a repo
svn log
View the complete history of a repo
svn log -v
Repo Structure
- See: https://jmfeurprier.com/2010/02/08/svn-trunk-branches-and-tags/
- See: https://stackoverflow.com/questions/16142/what-do-branch-tag-and-trunk-mean-in-subversion-repositories
The most common SVN repository structure is to have a trunk
, branches
and tags
directory for each project:
/project/trunk/...
/project/branches/...
/project/tags/...
Every time a new branch or tag is created, a directory named after the commit, containing the changes, is added to the repo:
/project/trunk/...
/project/branches/b1
/project/branches/b2
/project/branches/...
/project/tags/t1
/project/tags/t2
/project/tags/...
The underlying implementation as tags
, branches
, and trunk
directories is only conventional and not in any way enforced by the tools. However, violating these conventions leads to confusion as this breaks habits and expectations of others accessing the repository. Special care must be taken to avoid committing new changes into tags, which should be frozen.
Trunk
The trunk is the main-line of development in a SVN repository. It represents the current production code base which gets deployed to the production environment.
- There is only one
trunk
and it must always be kept bug-free and deployable.
Branch
A branch
is a copy of the trunk, or another branch which can be worked-on and then merged back to the trunk when it's ready (after review and testing).
Tag
A tag
is simply a snapshot (a copy) of the trunk, or a branch. It marks, or highlights notable revisions in the history of the repository, usually things like "this was released as 1.0".
- NEVER commit new changes into a tag.
NOTE: There is confusion with tags and branches because in SVN there really is no distinction between them, besides the name of the directory. In svn you are able to commit changes to a tag, and in fact it is difficult to prevent this. Using an SVN hook script, one can make SVN treat any path containing "/tag/" to be write-protected after creation; the net result is that tags, once created, are immutable (at least to "ordinary" users). As long as nobody ever commits to a directory, it remains a tag. If people start committing to it, it becomes a branch.
Fork
In open source projects, major branches that are not accepted into the trunk by the project stakeholders can become the bases for a fork, a totally separate project that share a common origin with other source code.
Add a Trunk to an Existing Repo
Make the trunk
dir in the root of your SVN repo:
svn mkdir https://mydomain.com/svn/my_repo/trunk -m "making trunk dir"
Move everything from the repos root dir to the new trunk
. You will need to move each root-level file and directory manually:
svn move https://mydomain.com/svn/my_repo/A_FOLDER https://mydomain.com/svn/my_repo/trunk/A_FOLDER -m "Moving the folder to the trunk."
svn move https://mydomain.com/svn/my_repo/A_FILE.TXT https://mydomain.com/svn/my_repo/trunk/A_FILE.TXT -m "Moving the file to the trunk."
After everything from the repo root has been moved, use svn switch
top point the local repo at the trunk
.
Go into the root folder of your local repo and run:
svn switch https://mydomain.com/svn/my_repo/trunk --ignore-ancestry
NOTE: Beginning with Subversion 1.7, the svn switch
command will demand by default that the URL to which you are switching your working copy shares a common ancestry with the item that the local copy currently reflects. Override this behavior by specifying the --ignore-ancestry
option.
Command | Syntax | Example |
---|---|---|
Checkout SVN Repo | svn co <repo URL> |
svn co http://svn.rap.ucar.edu/svn/snat/visitapp |
Checkout a repository
Use the co
or checkout
command to pull the repo directory from the remote SVN server.
Checkout the remote app_visit
repository to the local /opt
directory:
svn co https://svn.rap.ucar.edu/svn/app_visit/ /opt
Sometimes SVN login may default to your machine name. You can force the user with the --username
flag:
svn co --username your_username https://svn.rap.ucar.edu/svn/app_visit/ /opt
Get the status of a repo
svn status
Update local, get (pull) code from the server
svn update
svn up
Add new files and directories
With SVN, new files and directories must be added to the repo using add
.
Add a new file:
svn add file_name
Add all new (except ignored) files under a specified directory tree:
svn add --force path/to/dir
Delete files and directories
NOTE: Do not delete files and directories unless you use the svn delete
command.
svn delete myfile
Rename or move files and directories
NOTE: Do not rename or move files or directories unless you use the svn mv
command.
Commit local changes to the repo
From within the repo:
svn commit -m 'Your informative commit message.'
Commit a specific repo:
svn commit path/to/local/repo/dir -m 'Your informative commit message.'
Set an "ignored" directory:
To set the ignore property for the directory _local_assets
:
svn propset svn:ignore _local_assets .
To check what properties are set:
svn proplist
To see the value of svn:ignore:
svn propget svn:ignore
To undo ignore and delete properties previously set:
svn propdel svn:ignore
SVN Branching, Merging and Releasing
- https://articles.assembla.com/en/articles/960444-branching-and-tagging-in-svn
- http://svnbook.red-bean.com/en/1.7/svn.branchmerge.using.html
- https://stackoverflow.com/questions/345683/svn-creating-trunk-directory-on-existing-repository
Branches
Branches protect the source code from potentially destabilizing changes.
Subversion has no internal concept of a branch—it knows only how to make copies. When you copy a directory, the resultant directory is only a “branch” because you attach that meaning to it. You may think of the directory differently, or treat it differently, but to Subversion it's just an ordinary directory that happens to carry some extra historical information. Because of this copy mechanism, Subversion's branches exist as normal filesystem directories in the repository. This is different from other version control systems, where branches are typically defined by adding extra-dimensional “labels” to collections of files. The location of your branch directory doesn't matter to Subversion. Most teams follow a convention of putting all branches into a /branches directory, but you're free to invent any policy you wish.
-
Developers commit all new work to the trunk. Day-to-day changes are committed to /trunk: new features, bug fixes, and so on.
-
The trunk is copied to a “release” branch. When the team thinks the software is ready for release (say, a 1.0 release), /trunk might be copied to /branches/1.0.
-
Teams continue to work in parallel. One team begins rigorous testing of the release branch, while another team continues new work (say, for version 2.0) on /trunk. If bugs are discovered in either location, fixes are ported back and forth as necessary. At some point, however, even that process stops. The branch is “frozen” for final testing right before a release.
-
The branch is tagged and released. When testing is complete, /branches/1.0 is copied to /tags/1.0.0 as a reference snapshot. The tag is packaged and released to customers.
-
The branch is maintained over time. While work continues on /trunk for version 2.0, bug fixes continue to be ported from /trunk to /branches/1.0. When enough bug fixes have accumulated, management may decide to do a 1.0.1 release: /branches/1.0 is copied to /tags/1.0.1, and the tag is packaged and released.
-
This entire process repeats as the software matures: when the 2.0 work is complete, a new 2.0 release branch is created, tested, tagged, and eventually released. After some years, the repository ends up with a number of release branches in “maintenance” mode, and a number of tags representing final shipped versions.
Creating a branch is simple. All you need to do is make a copy of your project using "svn copy".
svn copy <https://mysvnrepo.com/svn/path/to/trunk> \ <https://mysvnrepo.com/svn/path/to/branch_name> \ -m "commit message"
Tags
There is no difference between branches and tags in Subversion. The only difference is in what the user then does with the directory. Branches are typically created, edited, and then merged back into the trunk. Alternatively, tags are created as a snapshot of the project at a point in time and then never changed.
Typically, tags are used to create a snapshot of your project at a certain stage. They are not used for development and working on a tag revision is not a good idea.
If you need to make changes to a release which has already been tagged, create a new branch from the tag and then commit the branch. Do all of your work on the branch, and then create a new tag from that branch.
Creating a tag is exactly the same as creating a branch. The only difference is that the tag will be located inside of the tags directory instead of the previous branches directory.
SVN Ignore
- http://blog.bogojoker.com/2008/07/command-line-svnignore-a-file/
- http://superchlorine.com/2013/08/getting-svn-to-ignore-files-and-directories/
You don’t svn:ignore a file.
You put an svn:ignore property on the directory to ignore that filename pattern!
# Go to the repo trunk directory:
cd trunk/
# Add just the single file to the current directories ignore list (like above)
# Note the dot at the end of the command is important
svn propset svn:ignore secret.txt .
Ignore an Existing File
If the file is already under version control or shows up as ‘M’ instead of ‘I’, then you’ll first have to svn delete the file from the repository (make a backup of it somewhere first), then svn ignore the file using the steps above and copy the file back into the repository.
List ignored files
svn propget svn:ignore .
Status including ignored files
svn status --no-ignore