Before we go on, you should know a bit about how to identify a particular revision in your repository. As you learned in the section called “Revisions”, a revision is a “snapshot” of the repository at a particular moment in time. As you continue to commit and grow your repository, you need a mechanism for identifying these snapshots.
You specify these revisions by using the
--revision
(-r
) switch plus
the revision you want (svn --revision REV) or
you can specify a range by separating two revisions with a colon
(svn --revision REV1:REV2). And Subversion
lets you refer to these revisions by number, keyword, or
date.
When you create a new Subversion repository, it begins its life at revision zero and each successive commit increases the revision number by one. After your commit completes, the Subversion client informs you of the new revision number:
$ svn commit --message "Corrected number of cheese slices." Sending sandwich.txt Transmitting file data . Committed revision 3.
If at any point in the future you want to refer to that revision (we'll see how and why we might want to do that later in this chapter), you can refer to it as “3”.
The Subversion client understands a number of
revision keywords. These keywords
can be used instead of integer arguments to the
--revision
switch, and are resolved into
specific revision numbers by Subversion:
Each directory in your working copy contains an
administrative subdirectory called
.svn
. For every file in a directory,
Subversion keeps a copy of each file in the administrative
area. This copy is an unmodified (no keyword expansion, no
end-of-line translation, no nothing) copy of the file as it
existed in the last revision (called the “BASE”
revision) that you updated it to in your working copy. We
refer to this file as the pristine
copy or text-base version
of your file, and it's always an exact byte-for-byte copy of
the file as it exists in the repository.
The latest (or “youngest”) revision in the repository.
The revision number of an item in a working copy. If the item has been locally modified, the “BASE version” refers to the way the item appears without those local modifications.
The most recent revision prior to, or equal to,
BASE
, in which an item changed.
The revision immediately before
the last revision in which an item changed.
(Technically, COMMITTED
- 1.)
PREV
, BASE
, and
COMMITTED
can be used to refer to local
paths, but not to URLs.
Here are some examples of revision keywords in action. Don't worry if the commands don't make sense yet; we'll be explaining these commands as we go through the chapter:
$ svn diff --revision PREV:COMMITTED foo.c
# shows the last change committed to foo.c
$ svn log --revision HEAD
# shows log message for the latest repository commit
$ svn diff --revision HEAD
# compares your working file (with local changes) to the latest version
# in the repository
$ svn diff --revision BASE:HEAD foo.c
# compares your “pristine” foo.c (no local changes) with the
# latest version in the repository
$ svn log --revision BASE:HEAD
# shows all commit logs since you last updated
$ svn update --revision PREV foo.c
# rewinds the last change on foo.c
# (foo.c's working revision is decreased)
These keywords allow you to perform many common (and helpful) operations without having to look up specific revision numbers or remember the exact revision of your working copy.
Anywhere that you specify a revision number or revision keyword, you can also specify a date inside curly braces “{}”. You can even access a range of changes in the repository using both dates and revisions together!
Here are examples of the date formats that Subversion accepts. Remember to use quotes around any date that contains spaces.
$ svn checkout --revision {2002-02-17} $ svn checkout --revision {15:30} $ svn checkout --revision {15:30:00.200000} $ svn checkout --revision {"2002-02-17 15:30"} $ svn checkout --revision {"2002-02-17 15:30 +0230"} $ svn checkout --revision {2002-02-17T15:30} $ svn checkout --revision {2002-02-17T15:30Z} $ svn checkout --revision {2002-02-17T15:30-04:00} $ svn checkout --revision {20020217T1530} $ svn checkout --revision {20020217T1530Z} $ svn checkout --revision {20020217T1530-0500} …
When you specify a date as a revision, Subversion finds the most recent revision of the repository as of that date:
$ svn log --revision {2002-11-28} ------------------------------------------------------------------------ r12 | ira | 2002-11-27 12:31:51 -0600 (Wed, 27 Nov 2002) | 6 lines …
You can also use a range of dates. Subversion will find all revisions between both dates, inclusive:
$ svn log --revision {2002-11-20}:{2002-11-29} …
As we pointed out, you can also mix dates and revisions:
$ svn log --revision {2002-11-20}:4040
Users should be aware of a subtlety that can become quite a stumbling-block when dealing with dates in Subversion. Since the timestamp of a revision is stored as a property of the revision—an unversioned, modifiable property—revision timestamps can be changed to represent complete falsifications of true chronology, or even removed altogether. This will wreak havoc on the internal date-to-revision conversion that Subversion performs.