This is not intended to be an exhaustive discussion of SVN.
For that, you should go to
http://subversion.tigris.org/
If you are interested in an on-line book ... http://svnbook.red-bean.com/ is the
place for you.
If you are interested in creating a tar file/ ...
Anything like this is a comment.
Here is the definition of some terms I will use:
A repository is the master collection [of projects] and is actually a database.
A project is a collection of related files.
A sandbox is a project being edited.
working copy a two-word way of saying "sandbox".
The subversion client is the machine that will receive the
files from the repository. Fundamentally, the machine that
will have the sandbox.
The subversion server is the machine that has the repository.
You will not be able to log in to the machine, nor should you be able to.
This www-page is almost exclusively from the perspective of
someone who is using svn to READ from a repository someone
else maintains. There is a section titled
"For Those Who Can Write"
that only applies to those who can write to the repository.
If you are getting checksum errors, you have probably modified one of the 'hidden' .svn
files (the local backup copy), which you should not do. The following
instructions on how to update your local backup copy are apparently simpler than the
top hits on google - which involved recomputing the MD5 checksum and/or editing server files.
At the end of 2016 the DART subversion repository was moved to a new machine, which necessitated a new subversion URL. What was hoped to be a simple svn switch is not possible because of the new Repository UUID. Bummer. The old repository is no longer available and attempts to access it will result in something like:
svn: E170013: Unable to connect to a repository at URL 'https://subversion.ucar.edu/DAReS/DART/releases/Lanai' svn: E000061: Error running context: Connection refusedTo facilitate the transition to the new subversion repository, I have written a script, duplicate_svn_working_directory.csh, that attempts to make an exact duplicate of an existing sandbox - but with the new subversion URL. The script is intended to be run from the parent directory of the existing DART sandbox and will create a directory that has the same name as the existing DART sandbox as well as the current revision number of the sandbox and a unique string based on the PID. The original directory is untouched.
Hopefully, this should pertain to just about everybody.
Minimally, you will need to have the subversion command-line client
application svn installed on your machine. For the most
part, the miracle of http takes care of the details of
communicating with the server.
creates a working copy of the project for you to modify.
Example:
cd someplacenew; svn checkout -r HEAD https://svn-dares-dart.cgd.ucar.edu/DART/trunk DART
As far as I can tell, the -r HEAD
part is the default -OR- I get the same thing with or without it.
Note there are multiple ways of specifying the option.
-r HEAD and
--revision HEAD are the same.
Example 2: checking out a tagged version --
The easiest way to figure out what tagged versions are available is via
the www-based interface, just point your browser to the 'tags' portion
of the repository -
https://svn-dares-dart.cgd.ucar.edu/DART/tags .
The www-page will have a list of all the tagged versions of the code.
Let's say you want to check out the post_iceland version,
which we'll put in a directory called
post_iceland_DART.
svn checkout https://svn-dares-dart.cgd.ucar.edu/DART/tags/post_iceland post_iceland_DART
The same is true for Releases. https://svn-dares-dart.cgd.ucar.edu/DART/releases .
reports the changes to your working copy WITHOUT making
any changes to your working copy.
With no args, print only locally modified items (no network access).
With -u, add working revision and server out-of-date information.
With -v, print full revision information on every item.
Example:
In this example, the working copies are unmodified. The repository has
been updated, and some little bird told me to update. Here's what you could
do ... commands I typed look like this.
[shad:~/svn/DART/mpi_utilities] thoar > svn status [shad:~/svn/DART/mpi_utilities] thoar > svn status -v 2528 2387 nancy . 2528 2387 nancy mpi_utilities_mod.html 2528 1974 nancy mpi_utilities_mod.nml 2528 2385 nancy null_mpi_utilities_mod.f90 2528 2302 nancy mpi_utilities_mod.f90 [shad:~/svn/DART/mpi_utilities] thoar > svn status -u * 2528 mpi_utilities_mod.html * 2528 mpi_utilities_mod.nml * 2528 null_mpi_utilities_mod.f90 * 2528 mpi_utilities_mod.f90 Status against revision: 2570 [shad:~/svn/DART/mpi_utilities] thoar > svn diff mpi_utilities_mod.f90 [shad:~/svn/DART/mpi_utilities] thoar > svn diff -r HEAD mpi_utilities_mod.f90 Index: mpi_utilities_mod.f90 =================================================================== --- mpi_utilities_mod.f90 (revision 2570) +++ mpi_utilities_mod.f90 (working copy) @@ -145,11 +145,9 @@ set_output use time_manager_mod, only : time_type, get_time, set_time -! BUILD TIP +! ! Some MPI installations have an MPI module; if one is present, use that. -! (i.e. 'use mpi') ! If not, there will be an MPI include file which defines the parameters. -! (i.e. 'include mpif.h') ! Use one but not both. For help on compiling a module which uses MPI ! see the $DART/doc/mpi directory. Property changes on: mpi_utilities_mod.f90 ___________________________________________________________________ Name: svn:keywords - Date Author Revision HeadURL Id + Author Date Id Revision
FLAG | meaning |
---|---|
M | Modified ... file is locally modified. |
U | Updated ... received changes from the server. |
A | Added ... file/directroy was added (from the server). |
D | Deleted ... file/directory was deleted from your sandbox. This means the file is no longer needed. Never fear, it is still recoverable if you need to look at it for some reason. |
R | Replaced ... file/directory was deleted from the repository but replaced with something by the same name. Subversion considers them to be distinct. |
G | merGed ... received changes from the server, but your local copy was modified (by you). The changes were either non-intersecting or exactly the same as the changes you made. "Good to Go" |
C | Conflict ... received changes from the server, but your local copy was modified (by you). The changes overlap and are not identical. This will require human intervention to resolve. |
? | subversion doesn't know anything about this file. File not under svn control. |
shows log message for the latest repository commit.
Example:
0[123] dart:~/SVN/DART/perfect_model_obs > svn log --revision 2510 perfect_model_obs.f90 ------------------------------------------------------------------------ r2510 | jla | 2006-12-14 10:54:09 -0700 (Thu, 14 Dec 2006) | 3 lines Changed time_index so that first time is always output for any diagnostic output period. ------------------------------------------------------------------------ 0[124] dart:~/SVN/DART/perfect_model_obs > svn log --revision 2510:2600 perfect_model_obs.f90 ------------------------------------------------------------------------ r2510 | jla | 2006-12-14 10:54:09 -0700 (Thu, 14 Dec 2006) | 3 lines Changed time_index so that first time is always output for any diagnostic output period. ------------------------------------------------------------------------ r2565 | thoar | 2007-01-23 21:38:37 -0700 (Tue, 23 Jan 2007) | 2 lines Turning on the svn propset svn:keywords "Date Author Revision HeadURL Id" ------------------------------------------------------------------------
Example: A particularly useful syntax is to subsitute a (possibly unknown) revision number with a date:
0[125] dart:~/SVN/DART/perfect_model_obs > svn log --revision "{2007-04-13}":HEAD perfect_model_obs.f90 ...you get the picture ...
Example: If you want to see the log and changed files for ALL repository changes (starts at the head and goes back as far as you're willing to read - this is helpful when determining "what's changed - lately"):
0[123] thunderbolt > svn log --v https://svn-dares-dart.cgd.ucar.edu/DART | less
Example: If you want to see what the log or the source of a deleted file, you need to get a version number from before the deletion. To figure out what rev a file was deleted, go to the most likely directory:
0[321] thunderbolt > svn log -v . > full_loggrep for your file of your choice and you'll eventually find the 'D' lines in the revision history. Once you know a version number, you can:
0[abc] thunderbolt > svn log https://blah.blah/repository_file.f90@1234
The @REV syntax can be used in a lot of places - not just on dead files. However, the '-r 1234' argument doesn't work with dead files, so you have to use the @REV syntax here.
The "svn diff" command produces output by comparing your working files agains the cached "pristine" copies within the .svn area. Fies scheduled for addition are displayed as added text, and files scheduled for deletion are displayed as deleted text. Output is displayed in "unified diff format". That is, removed lines are prefaced with - and added lines are prefaced with a +. svn diff also prints filename and offset information useful to the patch program, so you can generate patches by redirecting the diff output to a file:
svn diff > patchfileYou could, for example, email the patchfile to another developer for review or testing prior to commit.
cd DART/obs_def svn diff DEFAULT_obs_def_mod.F90 > patchfile scp -p patchfile my.other.machine.edu:DART/obs_def log on to other machine cd DART/obs_def patch -p0 < patchfile
If you want diff output in a different format, specify an external diff
program using --diff-cmd and pass any flags using the --extensions switch.
[footnote pp. 31 of svn-book.pdf]
If you use the default, your modifications are prefixed with a '+',
the 'other' lines are prefixed with a '-'. Be aware that 'other' could be HEAD
(svn diff -r HEAD ...) and could be NEWER than your modifications!
Example: comparing your modifications to the same version you started with.
In this example, there are a couple lines that are just to get you oriented,
they start with neither a '-' nor a '+'. The lines starting with '+' are your modifications.
0[119] cr0122en:/<4>SVN/DART/obs_def > svn diff DEFAULT_obs_def_mod.F90 Index: DEFAULT_obs_def_mod.F90 =================================================================== --- DEFAULT_obs_def_mod.F90 (revision 2884) +++ DEFAULT_obs_def_mod.F90 (working copy) @@ -30,8 +30,16 @@ KIND_TEMPERATURE, KIND_SPECIFIC_HUMIDITY, KIND_PRESSURE, & KIND_VERTICAL_VELOCITY, KIND_RAINWATER_MIXING_RATIO, & KIND_DEW_POINT_TEMPERATURE, KIND_DENSITY, KIND_VELOCITY, & - KIND_1D_INTEGRAL, KIND_RADAR_REFLECTIVITY, & - KIND_POTENTIAL_TEMPERATURE + KIND_RADAR_REFLECTIVITY, KIND_1D_INTEGRAL, & + KIND_GRAUPEL_MIXING_RATIO, KIND_SNOW_MIXING_RATIO, & + KIND_GPSRO, KIND_CLOUD_LIQUID_WATER, KIND_CLOUD_ICE, & + KIND_CONDENSATIONAL_HEATING, KIND_VAPOR_MIXING_RATIO, & + KIND_ICE_NUMBER_CONCENTRATION, KIND_GEOPOTENTIAL_HEIGHT, & + KIND_POTENTIAL_TEMPERATURE, KIND_SOIL_MOISTURE, & + KIND_GRAV_WAVE_DRAG_EFFIC, KIND_GRAV_WAVE_STRESS_FRACTION, & + KIND_TRACER_SOURCE, KIND_TRACER_CONCENTRATION, & + KIND_VORTEX_LON, KIND_VORTEX_LAT, & +
Another very useful variation is the ability to see what is different from one release or branch to another. The next example will show precisely which files are different - in the repository. Your working copies (if any) are immaterial.
svn diff --summarize https://svn-dares-dart.cgd.ucar.edu/DART/releases/Kodiak \ https://svn-dares-dart.cgd.ucar.edu/DART/trunk
bring your working copy "up-to-date" with the repository.
NOTE: if you have local modifications to the file,
they are preserved (if possible) during the update.
As long as the modifications do not conflict with changes
in the repository,
your changes will last through the update.
Example:
0[508] dart:~/SVN/DART > svn update U location/threed_sphere/location_mod.f90 U models/lorenz_96/model_mod.f90 U models/wrf/work/runme_filter U models/wrf/shell_scripts/advance_model.csh U ensemble_manager/ensemble_manager_mod.html U filter/filter.f90 A filter/filter.dopplerfold.f90 U obs_kind/DEFAULT_obs_kind_mod.F90 A mkmf/mkmf.template.intel.osx U utilities/utilities_mod.f90 Updated to revision 2681. 0[509] dart:~/SVN/DART >
If there is a conflict - fear not. Subversion makes copies of
if you want to get version 4567 of a deleted file back, you can either:
svn cat https://blah.blah/bob.f90@4567 > oldbob.f90
or
svn update https://blah.blah/bob.f90@4567
svn revert is your best friend. Makes you bold and invincible.
Gives you courage to try new things without the fear of royally screwing things up.
Example:
0[331] yslogin3:~/<2>trunk/models/bgrid_solo $ svn status -qu Status against revision: 7544 OK, so you're at the HEAD revision 0[332] yslogin3:~/<2>trunk/models/bgrid_solo $ vi model_mod.f90 edit the model_mod.f90, screw things up, test, realize horrible result ... 0[333] yslogin3:~/<2>trunk/models/bgrid_solo $ svn status -q M model_mod.f90 confirmed - model_mod.f90 has changed. 0[334] yslogin3:~/<2>trunk/models/bgrid_solo $ svn revert model_mod.f90 Reverted 'model_mod.f90' 0[335] yslogin3:~/<2>trunk/models/bgrid_solo $ svn status -q 0[336] yslogin3:~/<2>trunk/models/bgrid_solo $ svn diff -r HEAD model_mod.f90 0[337] yslogin3:~/<2>trunk/models/bgrid_solo $ Yes!
Subversion 'remembers' that a file is in conflict and will not
allow a file that is in conflict to be committed to the repository. You must
first clear the 'conflicted' status with resolved.
Example:
0[675] dart:~/DART/shell_scripts > svn status ? bob.r2657 ? bob.r2658 ? bob.mine C bob 0[676] dart:~/DART/shell_scripts > (a miracle happens) 0[677] dart:~/DART/shell_scripts > svn commit -m "now slices bread" svn: Commit failed (details follow): svn: Aborting commit: '/fs/image/home/thoar/SVN/DART/shell_scripts/bob' remains in conflict doh! 1[678] dart:~/DART/shell_scripts > svn resolved bob Resolved conflicted state of 'bob' 0[679] dart:~/DART/shell_scripts > svn commit -m "now slices bread" Sending shell_scripts/bob Transmitting file data . Committed revision 2659. 0[680] dart:~/DART/shell_scripts >
Here's the command for changing from one branch to another.
The files will be updated to match the new branch, while leaving the local
modifications alone if possible.
Example: Lets' say you've been updating from the trunk (the development branch) and
you want to move to the Kodiak release without losing any local modifications you've made to
your project - which I'll call ~/SVN/DART
0[577] dart:~/SVN/DART > svn switch https://svn-dares-dart.cgd.ucar.edu/DART/releases/Kodiak
Here's the command for changing the server address of the svn tree
when the content isn't changing, just the urls:
Example:
0[577] dart:~/SVN/DART > svn switch --relocate http://proxy.subversion.ucar.edu/DAReS/DART/trunk https://svn-dares-dart.cgd.ucar.edu/DART/trunk .
If you ever see an S in the 5th column of the 'svn status' command, that means that directory is switched relative to the rest of the dirs. I don't recommend doing this -- seems like it just leads to massive confusion -- but i just ran into one last week where i'd been experimenting and had apparently done this. would have caused a lot of confusion about why it wasn't updating with the rest of the trunk.
The safety provided by having backups of files allows you to delete files to
keep the project tidy. However, every now and again it is nice to be able to
go back and look at those deleted files. The annoying part is that you have to
know the revision number of the deleted file before you can 'svn cat' or whatever.
To figure out what rev a file was deleted, go to the most likely directory:
Example:
0[321] thunderbolt > svn log -v . > full_loggrep for your file of your choice and you'll eventually find the 'D' lines in the revision history. Once you know a version number, you can:
0[abc] thunderbolt > svn log https://blah.blah/repository_file.f90@1234
or
0[abc] thunderbolt > svn cat https://blah.blah/repository_file.f90@1234 > deleted_file.txt
[tarpon:~] thoar% svn list http://proxy.subversion.ucar.edu/DAReS/DART [tarpon:~] thoar% svn checkout --revision 2188 http://proxy.subversion.ucar.edu/DAReS/DART/trunk DART_post_iceland [tarpon:~] thoar% svn checkout --revision 2884 http://proxy.subversion.ucar.edu/DAReS/DART/trunk DART_Jamaica
Description | command |
---|---|
svn | The command-line client program. |
svnversion | A program for reporting the state (in terms of revisions of the items present) of a working copy. |
svnlook | A tool for inspecting a Subversion repository. |
svnadmin | A tool for creating, tweaking, or repairing a Subversion repository. |
svndumpfilter | A program for filtering Subversion repository dump streams. |
The ~/.subversion/config file has some fantastic power to facilitate things, in particular svn properties and keywords etc. An example of how to turn on the automatic properties and specicif properties for specific filenames/extension may be found here. You should augment your ~/.subversion/config (normally at the end) with whatever you like.
Example: Not sure I want to give people that kind of power.
This one is nice because you can use wildcards to remove sets of files -
OR DIRECTORIES! Whooohooo! No more 'pruning empty directories'.
excellent ...
Example:
0[578] dart:~/SVN/DART/shell_scripts > svn rm bob D bob 0[579] dart:~/SVN/DART/shell_scripts >
Example: (where the target file already exists) Note the log entries move with the
file! Whooohoooo!!!!
0[528] dart:~/<2>models/PBL_1d/src > svn rename driver.F driver.F90 svn: File 'driver.F90' already exists 1[529] dart:~/<2>models/PBL_1d/src > rm driver.F90 0[530] dart:~/<2>models/PBL_1d/src > svn rename driver.F driver.F90 A driver.F90 D driver.F 0[531] dart:~/<2>models/PBL_1d/src > svn commit -m "renamed driver.F to driver.F90 because it really uses the f90 syntax and the .F extension usually causes compilers to assume f77 syntax" driver.F90 Adding driver.F90 Committed revision 2715. 0[532] dart:~/<2>models/PBL_1d/src > svn log driver.F90 ------------------------------------------------------------------------ r2715 | thoar | 2007-03-26 13:40:16 -0600 (Mon, 26 Mar 2007) | 1 line renamed driver.F to driver.F90 because it really uses the f90 syntax and the .F extension usually causes compilers to assume f77 syntax ------------------------------------------------------------------------ r2713 | thoar | 2007-03-25 22:09:04 -0600 (Sun, 25 Mar 2007) | 3 lines New copyright tag (up-to-date for 2007) New URL keyword instead of (unsupported) 'Source'. ...
The biggie. I recommend not using the -m "commit message" strategy because once you hit ENTER, it happens. It is much safer to simply use svn commit and let svn invoke your $EDITOR. IFF you leave your editor without adding a message, the commit is aborted. This can be VERY HANDY if you forget that svn will commit recursively. When your editor is invoked, a list of files that are part of the commit will be appended to the message in your editor. If these don't look right to you, you have a chance to back out by entering an empty log message.
Example:
0[577] dart:~/SVN/DART/shell_scripts > svn propset svn:keywords "Date Rev Author HeadURL Id" bob 0[578] dart:~/SVN/DART/shell_scripts > svn commit -m "added properties" bob
svn propset svn:mime-type text/html `find . -name "*.html" -print | grep -v .svn` svn propset svn:eol-style native *.m svn propset svn:executable runme_filter
Note that the quotes around the propset string are OK ... but if you do a propget and get quotes, they're wrong. Your .subversion/config file should NOT have quotes in it.
Example:
0[577] dart:~/DART/models/POP > svn proplist -v test_dipole_interp.f90
Example:
0[577] dart:~/DART/models/POP > svn propdel svn:executable test_dipole_interp.f90
Example 1: (assumes you can find the exact revision you like)
svn log --verbose | & tee my.log (grub through log to find version number you want ...) svn copy --revision 2527 http://proxy.subversion.ucar.edu/DAReS/DART/trunk/system_simulation ./system_simulation
or
svn cat https://blah.blah/bob.f90@2527 > bob_2527.f90
I found an incantation which is supposed to let you edit svn log messages.
Since log messages aren't versioned, you have to be careful.
But if there are obnoxious typos or outright errors, it is fixable.
I haven't quite zero'd in on how to fix multiline messages
(it doesn't invoke vi, it's a command line argument)
but at least it's possible.
Here's an example command - the key is the --revprop
argument at the end.
The book says you can use propset instead of propget to update, but I haven't tried it yet.
Example 1: (assumes you can find the exact revision you like)
svn propget svn:log -r HEAD model_mod.f90 --revprop
In the course of human events, there are tree conflicts.
Here is how (I think) I have gotten into this predicament:
and here is how (I think) I have gotten out of these predicaments:
Keep in mind the actual release/branch/trunk and/or Revision will differ. This is just an example.
dart:~/svn/readonly_lanai > pwd ~/svn/readonly_lanai dart:~/svn/readonly_lanai > svn info Path: . Working Copy Root Path: /Users/thoar/svn/readonly_lanai URL: https://subversion.ucar.edu/DAReS/DART/releases/Lanai Relative URL: ^/DART/releases/Lanai Repository Root: https://subversion.ucar.edu/DAReS Repository UUID: acad1b26-7d42-44b9-9cec-aac8293558f5 Revision: 10700 Node Kind: directory Schedule: normal Last Changed Author: nancy Last Changed Rev: 10610 Last Changed Date: 2016-08-05 17:59:29 -0600 (Fri, 05 Aug 2016) dart:~/svn/DART/readonly_lanai > duplicate_svn_working_directory.csh usage: duplicate_svn_working_directory.csh Directory1 The Directory1 subversion attributes are used to check out a matching working directory from the new DART subversion server. Any and all unversioned files or directories or soft links in Directory1 are copied identically to the new working directory. The new working directory is created with a unique name that uses the name of Directory1 as well as some things to make it unique. After the new working directory is created and populated, this script will iterate over every file in the original working directory and report if there are any meaningful differences between the original and new versions of the file. A file containing the filenames of the files that are different is created. This file also contains the difference of the 'svn status' of the old and new working directories. This should remind you of what changes were scheduled in the old working directory - should you want to do the same in the new directory. After the new directory has been created and verified, I strongly suggest that you make a backup of the original directory and remove the original. The new directory can then be renamed to replace the original. dart:~/svn/DART/readonly_lanai > cd .. dart:~/svn/DART > duplicate_svn_working_directory.csh readonly_lanai Checking integrity of the existing working directory. No conflicts - proceeding. Checking out revision 10700 of https://svn-dares-dart.cgd.ucar.edu/DART/releases/Lanai into readonly_lanai_r10700.40020 Since the existing sandbox was readonly_lanai at r10700, the new sandbox name is readonly_lanai_r10700.40020 (the 40020 is a unique string and would be different if you execute duplicate_svn_working_directory.csh again). If this is NOT what you want to do, you have a few seconds to kill this job ... A readonly_lanai_r10700.40020/tutorial ... <snip of several thousand lines> ... Checked out revision 10700. Finished Checking out revision 10700 of https://svn-dares-dart.cgd.ucar.edu/DART/releases/Lanai into readonly_lanai_r10700.40020 readonly_lanai does not have any other branches in it. Making sure readonly_lanai_r10700.40020 is functionally the same as readonly_lanai Cycling over the files to compare in both directories. Checking 1 of 3443 ... readonly_lanai/adaptive_inflate/adaptive_inflate_mod.f90 is versioned. ... <snip of several thousand lines> ... Checking 3443 of 3443 ... readonly_lanai/utilities/utilities_mod.nml is versioned. The differences in the svn status of the old and new directories: IF THIS LIST IS NOT EMPTY - YOU MUST RESOLVE THIS BY HAND. The most common reasons are 'linked' files. The old working directory lines start with < START of svn status differences: By virtue of the fact there are no files listed here this conversion went smoothly. END of svn status differences. The list of files that were different is in different_files.txt.40020 The list of mixed revisions is in mixed_files.txt.40020 The summary of subversion differences is in summary.txt.40020 duplicate_svn_working_directory.csh complete.
OK - so now what ...
different_files.txt.40020 contains a list of all files that are
meaningfully different AFTER the best attempt at making sure there were
no differences. Any files in this list should be examined carefully.
Most often, they are unix 'links' - which you will have to manually recreate in the
new sandbox.
mixed_file.txt.40020 contains a list of all files that did not come from
the same top-level svn branch. This is mostly for use by the script to make sure the
new sandbox has the same tortured history as the original sandbox. Hopefully, you have
not mixed the Lanai release with some portions of the trunk or vice-versa. Even if you
did, the new sandbox should have the same origins. If any files are listed, you may
convince yourself that they are handled properly by doing an svn info
on the file in both the old and new sandboxes.
summary.txt.40020 contains a comparison of an svn status
in each of the sandboxes. The list of changes and svn permissions should be identical.
Only the differences will be listed here.
Any files in this list should be examined carefully.
It is possible that you may get the following warning:
WARNING: There are significant differences that you must manually resolve. WARNING: There are significant differences that you must manually resolve. WARNING: There are significant differences that you must manually resolve." Do not delete ${ORGDIR} until you are sure the changes you want exist in ${NEWDIR}This is a big clue that you need to really examine the contents of the three summary files.