Section 5.4. Getting Information about the Repository


5.4. Getting Information about the Repository

Subversion has a number of different commands that allow you to query the repository and working copy for a wealth of information about their current states, as well as their history. As your development in a working copy progresses, these commands will become invaluable tools, letting you quickly find out things like "what files have I changed since the last commit?" or "which branch of this directory am I currently working on?"

5.4.1. Getting Information on the Current State

The current state of the repository is easily queried with the svn status command, which outputs the current state of all files in your working copy that have been in some way modified from their pristine repository state.

 $ svn status A  +   pie.txt D      cake.txt _M     custard.txt 

The output for svn status consists of a list of files, one per line. By default, each line is made up of five columns of status information, followed by a filename. Each of the five columns uses single character symbols to convey the current status of the file. This is shown in Table 5.1.

Table 5.1. Status Command Ouput Symbols

First column

Shows whether a file was added, removed, or modified.

     

The file has not been modified.

A

    

The file is scheduled for addition to the repository.

D

    

The file is scheduled for deletion.

M

    

The contents of a file have been modified locally in the working copy.

C

    

A conflict occurred during a merge or update.

G

    

Reserved for showing merged files, but not yet used. (Non-conflicted, merged files will be marked with an M.)

?

    

The file has never been under version control.

!

    

The file was under version control, but was removed from the working copy using a tool other than Subversion.

~

    

Subversion tried to add a file of this name (e.g., during an update), but an unversioned file of the same name already exists.

X

    

An unversioned file used by an externals definition. (See Section 6.3.1, "File Properties," for more information on externals.)

R

    

A versioned file that has replaced another versioned file of the same name.

I

    

An ignored file. Only shown when both the --verbose and --no-ignore options are given.

Second Column

Shows whether a file's properties have been modified.

     

No properties have been modified on the file.

 

M

   

A property has been modified locally on the file.

 

C

   

A conflict occurred when merging or updating one or more of the file's properties.

Third Column

Indicates whether a file or directory has been locked in the working copy, due to another in-progress operation.

     

The file or directory is not locked.

  

L

  

The directory has been locked in the working copy. If there is no in-progress operation, you may need to run svn cleanup to remove the locked state. (This can happen if a command is interrupted.)

Fourth Column

This column indicates files scheduled for either addition or modification that are bringing previous history with them from another file.

     

No history is being brought from another file.

   

+

 

The file is contained within a directory that is scheduled for addition with history.

A

  

+

 

This file is scheduled for addition, and brings history from another file with it, probably as a result of an svn move or svn copy.

M

  

+

 

The file is contained within a directory that is scheduled for addition with history, and has also been locally modified.

Fifth Column

Indicates whether a file's path has been switched.

     

The file's base URL is the same as its parent directory.

    

S

The file has been switched (using svn switch) to a URL different from the URL of the file's parent directory.


Normally, svn status doesn't contact the repository. Instead, it determines which files have been modified by comparing them with pristine copies of the files, which Subversion keeps in the working copy's .svn directory. Sometimes, though, you are interested in seeing which files have also changed in the repository (and thus will be merged at the next svn update). To get this information out of Subversion, you need to run svn status with the --show-updates (-u) option.

 $ svn status --show-updates address.cpp 

The --show-updates option tells Subversion to output three pieces of extra information. The first is an * in the eighth column of output of each file that has been modified in the repository. Additionally, Subversoon will output the current revision of each file in the repository, as well as the HEAD revision of the repository, which the comparison is being made against.

 $ svn status --show-updates M             34   run.sh        *      56   stop.sh Status against revision:      92 

If you want even more information, you can run svn status in verbose mode, using the --verbose (-v) option. In this mode, the status command will output all files, not just ones that have been modified (ignored files will still be ignored). Additionally, it will show the last revision in which each file was committed and who made the commit, as well as the current revision in the working copy, in the following order: current revision, last committed, last committed by.

 $ svn status --show-updates --verbose               29      29 bill        passwd M             34      34 bill        run.sh        *      56      56 bill        stop.sh Status against revision:      92 

If you would like to output all files, including those that have been ignored in the configuration files or the svn:ignore property, you can tell svn status to disregard ignores with --no-ignore.

Getting Detailed File Info

Sometimes you need detailed information about a particular file or directory. In this case, the command you want to use is svn info. The info command gives you a dump of all the information that Subversion has stored about a file or directory in the working copy.

 $ svn info Table.m Path: trunk/Table.m Name: Table.m 

 URL: http://svn.example.com/repos/trunk/Table.m Revision: 3276 Node Kind: file Schedule: normal Last Changed Author: bill Last Changed Rev: 3271 Last Changed Date: 2004-07-23 10:25:19 -0660 (Fri, 23 Jul 2004) Text Last Updated: 2004-07-23 10:25:19 -0660 (Fri, 23 Jul 2004) Properties Last Updated: 2004-06-13 14:33:54 -0660 (Sun, 13 Jun 2004) Checksum: fe1f3b5946fd8d68cd2879c38457f447 

The first few lines of the info command's output identify the file that we're dealing with. The Path entry shows the location of the file relative to the base of the working copy, whereas the Name entry shows just the basename of the file. URL, on the other hand, shows the URL of the file in the repository.

After the identifiers, the next three items show the current state of the file in the working copy. The Revision enTRy shows the current revision of the file in the working copy, and the Node Kind enTRy indicates whether the entity being examined is a file or directory. Schedule shows whether the file is scheduled for any action on the next commit. An entry of normal (as in the preceding example) indicates that no specific action is scheduled.

Next, some information about the file's history is given. The Last Changed Author entry gives the username of the last person to commit a change for the file, and of course the Last Changed Rev and Last Changed Date give the revision number and date of the last commit. Additionally, there are entries that tell you when the files contents (Text) were last updated, and when the file's properties were last updated in the current working copy.

The final piece of information shown is a checksum. This is an MD5 sum of the pristine state of the file. This can be used to verify that the download from the repository wasn't corrupted, or to see if a file has changed in the working copy (of course, svn status is a much easier way to find that out).

Often you only want a particular piece of information about a file, not the entire info data dump. The svn info command doesn't have any way to explicitly specify a particular piece of data, but it is easy enough to get that information by combining svn info with the UNIX command grep. All you have to do is use a pipe (|) to pass the output of svn info to grep and search for a string that begins with the property name that you're looking for (the ^ before Checksum tells grep to only find lines that begin with the word "Checksum").

 $ svn info Table.m | grep ^Checksum Checksum: fe1f3b5946fd8d68cd2879c38457f447 

By default, svn info is a non-recursive command. If you prefer that it recurse into directories, you can use the --recursive (-R) option. Of course, with multiple files it is even more likely that you will want to grep for just a single item in the output. However, if you just grab a single line, the output will be nearly useless, because in many cases you will have no idea which file each line is referring to. The easiest way to get useful, but not excessive, output (in this case) is to use the grep command to search for both the item of interest and either the Name or Path enTRies. That way, the name of each file is output, followed by the data entries you are interested in. For example, the following command finds the last changed date for every file in trunk.

 $ svn info --recursive trunk/* | grep -E ' ^Path|^Last Changed Date' Path: hello.c Last Changed Date: 2004-12-04 01:03:39 -0500 (Sat, 04 Dec 2004) Path: Makefile Last Changed Date: 2004-12-06 11:12:47 -0500 (Sat, 06 Dec 2004) 

Examining File Changes

After you get in the habit of using it regularly, the svn diff command will easily become one of your most used and most trusted tools in the Subversion toolbox. The basic function of svn diff is to output the differences between two revisions, showing additions and deletions inline with each other.

By default, svn diff shows the differences between a file in your working copy and the pristine version of the current revision of that file. So, for example, if you have made changes to the file rabbit.c in your working copy, the diff command will show you exactly what those changes were.

 $ svn diff rabbit.c Index: rabbit.c =================================================================== --- rabbit.c    (revision 8) +++ rabbit.c    (working copy) @@ -5,5 +5,5 @@         if(item == CARROT)                 eat(item);         else if(item == CAT) -               run_away(FAST, item); +               hop_away(FAST, item);  } 

The svn diff command doesn't stop at showing local modifications, though. By using the --revision (-r) option, you can make svn diff output the differences between arbitrary revisions of files. All you need to do is pass the --revision option with two revision numbers separated by a colon. The command then returns the differences between the first revision and the second revision.

 $ svn diff --revision 32:48 cat.html Index: cat.html =================================================================== 

 --- cat.html     (revision 32) +++ cat.html     (revision 48) ---- output snipped ---- 

You can even get svn diff to give you the differences between two completely different files, from two completely different revisions. To do so, first you give svn diff two different paths to files in your working copy or URLs to a repository. Then, if you want to specify the revisions for each file, you enter a --revision REV1:REV2, just as with a single file.

[View full width]

$ svn diff --revision 736:103 http://svn.example.com/repos/hen.h http://svn.example.com /repos/fox.py Index: hen.h =================================================================== --- hen.h (revision 736) +++ fox.ph (revision 103) ---- output snipped ----

There is also another subtly different method that you can use for identifying which revision of a file to use, which is the peg revision method. Say, for example, that in revision 12 you had deleted a file named cat.html. Then, later, you renamed the file kitty.html to cat.html. If you do a diff on cat.html and compare revisions 10 and 32 using -r 10:32, Subversion will follow the history of the current cat.html file to compare it at the given revisions (which, at revision 10 was the file kitty.html). If you really want to compare the file cat.html that existed at revision 10 with the current cat.html, you need a way to specifically tell Subversion. This is done by appending the revision numbers after each filename with an @, instead of using the --revision option.

 $ svn diff http://svn.example.com/repos/cat.html@10 http://svn.example.com/repos/cat.html@32 

5.4.2. Getting the Repository's History

Subversion provides a couple of commands for examining the history of a file or directory in the repository.

Checking the Logs

You can easily see the entire log history of a file (or collection of files) by using the svn log command. When svn log is run with no options, it outputs the logs for the current directory, which includes the change histories for all of the files that are contained in the directory.

 $ svn log ---------------------------------------------------------------------- r9 | bill | 2004-08-05 22:44:48 -0500 (Thu, 05 Aug 2004) | 26 lines Added a check to test porridge temperature. Temperatures are represented with an enumeration, using   values of TOO_HOT, TOO_COLD, and JUST_RIGHT ---------------------------------------------------------------------- r8 | bill | 2004-08-05 22:21:48 -0500 (Thu, 05 Aug 2004) | 52 lines Initial commit of porridge.cpp ---------------------------------------------------------------------- 

To specify individual files and directories that you would like the history for, you can list files on the command line that svn log should examine. These can either be a list of files in your working copy or a URL (which may be followed by a list of files relative to the URL to be used instead of the base URL).

 $ svn log http://svn.example.com/repos/branch/foo_branch foo.cpp foo.h 

Subversion shows each log entry, in descending revision order, for every file involved. All of the log entries for the different files are mixed into a single listing, and each log is shown only once, even if it applies to multiple files. By default, svn log doesn't give a breakdown showing which files each log applies to, but if you pass the --verbose (-v) option it will show that information.

 $ svn log --verbose ---------------------------------------------------------------------- r10 | bill | 2003-06-14 19:44:06 -0500 (Sat, 14 Jun 2003) | 98 lines Changed paths:    A Bear.cpp    A Bear.h    M Makefile Added the class Animal::Bear ---------------------------------------------------------------------- 

The default behavior of svn log is to output the logs for all of the revisions from the given file's BASE revision back to revision number one (or, in the case of a URL, from the repository HEAD back to revision one). If you don't want that much information, you can restrict the revisions that are looked at by passing the --revision (-r) option to svn log, with a range of revisions in the form REV1:REV2 (you can also give just a single revision if that's all you want).

 $ svn log --revision 45:82 test.c 

There is one quirk that you should be aware of regarding how svn log works. Its default behavior, if no URL or path is given, is to show the log for . (i.e., the current working copy directory). When the files in a directory are committed, though, the BASE revision of the directory is not updated. So, if you check out a directory at revision 2859 and then perform three commits of changes to files inside the directory, the directory will still be at revision 2859, even though some of its contents are at later revisions. If you then perform an svn log in the directory with no path, the BASE will be taken from the directory (2859), and none of the changes that were committed will be shown (which is probably not what you really wanted). To get a complete log output, with the BASE revision of the most recently committed file in your directory, a better way to run svn log is with a wildcard, instead of an empty path.

 $ svn log * 

Who's to Blame?

Another useful tool for examining a file's history is the svn blame command. The blame command causes Subversion to output an entire file, with information about which user committed each line, and what revision that commit occurred in.

 $ svn blame rabbit.c      20      bill #include "rabbit.h"      20      bill      32      bill int examine_item(int item)      32      bill {      53      ted     if(item == CARROT)      53      ted        eat(item);      53      ted     else if(item == CAT)      86      drew       hop_away(FAST, item);      53      ted     return 0;      32      bill } 

You should be a little careful when trusting the output from svn blame, though. The blame entry for a line shows the last revision where any change was made, including whitespace. So, if a developer adjusts the spacing on a line, and then commits, that developer will be shown as the author, even though someone else may have actually made the last substantive modification.

Examining Files in the Repository

Often, you will find yourself wanting to know what files are in a particular directory in the repository. One option, of course, is to check out a working copy of that directory, but if all you want to know is the contents of the directory, checking out the whole thing wastes time and bandwidth, and is just generally an all-around clunky way of dealing with the problem. Fortunately, Subversion comes to your rescue with the svn list command.

When you run svn list, it contacts the repository and downloads just a list of the files in the given directory, which are then output to the terminal. The directory to list needs to be supplied as a URL to a directory or file in a repository, or as a path to a directory in a working copy (in which case Subversion will use that file's associated URL to contact the repository). If no directory is given, svn list uses the current working copy directory.

 $ svn list http://svn.example.com/repos/branches test_harness-branch_bill/ web_site-dev_branch/ application-version_2_0_beta/ 

The default behavior of svn list is to non-recursively display only the files that are in the HEAD revision of the given directory. If you would rather see a different revision, you can specify one with the --revision option, in which case Subversion will list the files that existed in that particular version. If you would like to see a recursive tree of the files in the given directory, you can request that with the --recursive option.

 $ svn list --revision 7 --recursive http://svn.example.com/repos branches/ tags/ trunk/ trunk/Makefile trunk/app.c 

If you need more information than just the names of the files in a directory, you can use the --verbose option. In verbose mode, svn list will show (in addition to each file's name) the last revision the files were committed in, the user who made that commit, the date of the commit, and the size of the file, in bytes.

 $ svn list --verbose http://svn.example.com/repos/trunk       7 bill              9 Aug 03 22:16 bar.c       6 bill              0 Aug 03 22:12 foo.c      10 bill              0 Aug 06 00:37 test.py       2 bill                Jul 31 13:47 trunk/ 

Getting a Single File

Sometimes, you need to look at just one single file from the repository. Unfortunately, svn checkout doesn't allow you to specify just a single file, only directories. Getting single files is where the svn cat command comes in handy. When run, svn cat contacts the repository and downloads just a single file, which it outputs to the terminal. In many cases, you will then want to redirect (using a >) svn cat's output into a file.

 $ svn cat http://svn.example.com/repos/trunk/foo.c > foo.c 



    Subversion Version Control. Using The Subversion Version Control System in Development Projects
    Subversion Version Control. Using The Subversion Version Control System in Development Projects
    ISBN: 131855182
    EAN: N/A
    Year: 2005
    Pages: 132

    flylib.com © 2008-2017.
    If you may any questions please contact us: flylib@qtcs.net