Once you’ve finished making changes, you need to commit them to the repository, but before you do so, it’s usually a good idea to take a look at exactly what you’ve changed. By examining your changes before you commit, you can make a more accurate log message. You may also discover that you’ve inadvertently changed a file, and this gives you a chance to revert those changes before committing. Additionally, this is a good opportunity to review and scrutinize changes before publishing them. You can see an overview of the changes you’ve made by using svn status, and you can dig into the details of those changes by using svn diff.
Subversion has been optimized to help you with the task of examining your changes, and it is able to do many things without communicating with the repository. In particular, your working copy contains a hidden cached “pristine” copy of each version-controlled file within the .svn area. Because of this, Subversion can quickly show you how your working files have changed and can even allow you to undo your changes without contacting the repository.
To get an overview of your changes, you’ll use the svn status command. You’ll probably use svn status more than any other Subversion command.
If you run svn status at the
top of your working copy with no arguments, it will detect all file
and tree changes you’ve made. Here are a few examples of the most
common status codes that svn status
can return. (Note that the text following #
is not actually printed by svn status.)
? scratch.c # file is not under version control A stuff/loot/bloo.h # file is scheduled for addition C stuff/loot/lump.c # file has textual conflicts from an update D stuff/fish.c # file is scheduled for deletion M bar.c # the content in bar.c has local modifications
In this output format, svn status prints six columns of characters, followed by several whitespace characters, followed by a file or directory name. The first column tells the status of a file or directory and/or its contents. The codes we listed are:
A
item
The file, directory, or symbolic link item has been scheduled for addition into the repository.
C
item
The file item is in a state of conflict. That is, changes received from the server during an update overlap with local changes that you have in your working copy (and weren’t resolved during the update). You must resolve this conflict before committing your changes to the repository.
D
item
The file, directory, or symbolic link item has been scheduled for deletion from the repository.
M
item
If you pass a specific path to svn status, you get information about that item alone:
$ svn status stuff/fish.c D stuff/fish.c
svn status also has a
--verbose
(-v
) option, which will show you the status of
every item in your working copy, even if it has
not been changed:
$ svn status -v M 44 23 sally README 44 30 sally INSTALL M 44 20 harry bar.c 44 18 ira stuff 44 35 harry stuff/trout.c D 44 19 ira stuff/fish.c 44 21 sally stuff/things A 0 ? ? stuff/things/bloo.h 44 36 harry stuff/things/gloo.c
This is the “long form” output of svn status. The letters in the first column mean the same as before, but the second column shows the working revision of the item. The third and fourth columns show the revision in which the item last changed and who changed it.
None of the prior invocations to svn
status contact the repository—instead, they compare the
metadata in the .svn directory
with the working copy. Finally, there is the --show-updates
(-u
)
option, which contacts the repository and adds
information about things that are out of date:
$ svn status -u -v M * 44 23 sally README M 44 20 harry bar.c * 44 35 harry stuff/trout.c D 44 19 ira stuff/fish.c A 0 ? ? stuff/things/bloo.h Status against revision: 46
Notice the two asterisks: if you were to run svn
update
at this point, you would receive changes to README and trout.c. This tells you some very useful
information—you’ll need to update and get the server changes on
README before you commit, or the
repository will reject your commit for being out of date (more on this
subject later).
svn status can display much more information about the files and directories in your working copy than we’ve shown here—for an exhaustive description of svn status and its output, see “svn status” in Chapter 9.
Another way to examine your changes is with the svn diff command. You can find out exactly how you’ve
modified things by running svn diff
with no
arguments, which prints out file changes in unified diff format:
$ svn diff Index: bar.c =================================================================== --- bar.c (revision 3) +++ bar.c (working copy) @@ -1,7 +1,12 @@ +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> + +#include <stdio.h> int main(void) { - printf("Sixty-four slices of American Cheese... "); + printf("Sixty-five slices of American Cheese... "); return 0; } Index: README =================================================================== --- README (revision 3) +++ README (working copy) @@ -193,3 +193,4 @@ +Note to self: pick up laundry. Index: stuff/fish.c =================================================================== --- stuff/fish.c (revision 1) +++ stuff/fish.c (working copy) -Welcome to the file known as 'fish'. -Information on fish will be here soon. Index: stuff/things/bloo.h =================================================================== --- stuff/things/bloo.h (revision 8) +++ stuff/things/bloo.h (working copy) +Here is a new file to describe +things about bloo.
The svn diff command produces this output by comparing your working files against the cached “pristine” copies within the .svn area. Files scheduled for addition are displayed as all added text, and files scheduled for deletion are displayed as all deleted text.
Output is displayed in unified diff format. That is, removed
lines are prefaced with -
, and
added lines are prefaced with +
.
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 > patchfile
You could, for example, email the patch file to another developer for review or testing prior to a commit.
Subversion uses its internal diff engine, which produces unified
diff format by default. If you want diff output in a different format,
specify an external diff program using --diff-cmd
and pass it any flags you’d
like using the --extensions
(-x
)
option. For example, to see local differences in file foo.c in context output format while
ignoring case differences, you might run svn diff --diff-cmd
/usr/bin/diff --extensions '-i' foo.c
.