<?xml version="1.0" encoding="UTF-8" standalone="no"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Examining History</title><link rel="stylesheet" href="styles.css" type="text/css" /><meta name="generator" content="DocBook XSL Stylesheets V1.73.2" /><link rel="start" href="index.html" title="Version Control with Subversion" /><link rel="up" href="svn.tour.html" title="Chapter 2. Basic Usage" /><link rel="prev" href="svn.tour.cycle.html" title="Basic Work Cycle" /><link rel="next" href="svn.tour.cleanup.html" title="Sometimes You Just Need to Clean Up" /></head><body><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">Examining History</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="svn.tour.cycle.html">Prev</a> </td><th width="60%" align="center">Chapter 2. Basic Usage</th><td width="20%" align="right"> <a accesskey="n" href="svn.tour.cleanup.html">Next</a></td></tr></table><hr /></div><div class="sect1" lang="en" xml:lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="svn.tour.history"></a>Examining History</h2></div></div></div><p>Your Subversion repository is like a time machine. It keeps a record of every change ever committed, and allows you to explore this history by examining previous versions of files and directories as well as the metadata that accompanies them. With a single Subversion command, you can check out the repository (or restore an existing working copy) exactly as it was at any date or revision number in the past. However, sometimes you just want to <span class="emphasis"><em>peer into</em></span> the past instead of <span class="emphasis"><em>going into</em></span> the past.</p><p>There are several commands that can provide you with historical data from the repository:</p><div class="variablelist"><dl><dt><span class="term"><span class="command"><strong>svn log</strong></span></span></dt><dd><p>Shows you broad information: log messages with date and author information attached to revisions, and which paths changed in each revision.</p></dd><dt><span class="term"><span class="command"><strong>svn diff</strong></span></span></dt><dd><p>Shows line-level details of a particular change.</p></dd><dt><span class="term"><span class="command"><strong>svn cat</strong></span></span></dt><dd><p>Retrieves a file as it existed in a particular revision number and display it on your screen.</p></dd><dt><span class="term"><span class="command"><strong>svn list</strong></span></span></dt><dd><p>Displays the files in a directory for any given revision.</p></dd></dl></div><div class="sect2" lang="en" xml:lang="en"><div class="titlepage"><div><div><h3 class="title"><a id="svn.tour.history.log"></a>Generating a list of historical changes</h3></div></div></div><p>To find information about the history of a file or directory, use the <span class="command"><strong>svn log</strong></span> command. <span class="command"><strong>svn log</strong></span> will provide you with a record of who made changes to a file or directory, at what revision it changed, the time and date of that revision, and, if it was provided, the log message that accompanied the commit.</p><pre class="screen"> $ svn log ------------------------------------------------------------------------ r3 | sally | Mon, 15 Jul 2002 18:03:46 -0500 | 1 line Added include lines and corrected # of cheese slices. ------------------------------------------------------------------------ r2 | harry | Mon, 15 Jul 2002 17:47:57 -0500 | 1 line Added main() methods. ------------------------------------------------------------------------ r1 | sally | Mon, 15 Jul 2002 17:40:08 -0500 | 1 line Initial import ------------------------------------------------------------------------ </pre><p>Note that the log messages are printed in <span class="emphasis"><em>reverse chronological order</em></span> by default. If you wish to see a different range of revisions in a particular order, or just a single revision, pass the <code class="option">--revision (-r)</code> option:</p><pre class="screen"> $ svn log -r 5:19 # shows logs 5 through 19 in chronological order $ svn log -r 19:5 # shows logs 5 through 19 in reverse order $ svn log -r 8 # shows log for revision 8 </pre><p>You can also examine the log history of a single file or directory. For example:</p><pre class="screen"> $ svn log foo.c … $ svn log http://foo.com/svn/trunk/code/foo.c … </pre><p>These will display log messages <span class="emphasis"><em>only</em></span> for those revisions in which the working file (or URL) changed.</p><div class="sidebar"><p class="title"><b>Why Does <span class="command"><strong>svn log</strong></span> Not Show Me What I Just Committed?</b></p><p>If you make a commit and immediately type <span class="command"><strong>svn log</strong></span> with no arguments, you may notice that your most recent commit doesn't show up in the list of log messages. This is due to a combination of the behavior of <span class="command"><strong>svn commit</strong></span> and the default behavior of <span class="command"><strong>svn log</strong></span>. First, when you commit changes to the repository, <span class="command"><strong>svn</strong></span> only bumps the revision of files (and directories) that it commits, so usually the parent directory remains at the older revision (See <a class="xref" href="svn.basic.in-action.html#svn.basic.in-action.mixedrevs.update-commit" title="Updates and Commits are Separate">the section called “Updates and Commits are Separate”</a> for why). <span class="command"><strong>svn log</strong></span> then defaults to fetching the history of the directory at its current revision, and thus you don't see the newly-committed changes. The solution here is to either update your working copy or explicitly provide a revision number to <span class="command"><strong>svn log</strong></span> by using the <code class="option">--revision</code> (<code class="option">-r</code>) option.</p></div><p>If you want even more information about a file or directory, <span class="command"><strong>svn log</strong></span> also takes a <code class="option">--verbose (-v)</code> option. Because Subversion allows you to move and copy files and directories, it is important to be able to track path changes in the filesystem, so in verbose mode, <span class="command"><strong>svn log</strong></span> will include a list of changed paths in a revision in its output:</p><pre class="screen"> $ svn log -r 8 -v ------------------------------------------------------------------------ r8 | sally | 2002-07-14 08:15:29 -0500 | 1 line Changed paths: M /trunk/code/foo.c M /trunk/code/bar.h A /trunk/code/doc/README Frozzled the sub-space winch. ------------------------------------------------------------------------ </pre><p> <span class="command"><strong>svn log</strong></span> also takes a <code class="option">--quiet</code> (<code class="option">-q</code>) option, which suppresses the body of the log message. When combined with <code class="option">--verbose</code>, it gives just the names of the changed files.</p><div class="sidebar"><p class="title"><b>Why Does <span class="command"><strong>svn log</strong></span> Give Me an Empty Response?</b></p><p>After working with Subversion for a bit, most users will come across something like this:</p><pre class="screen"> $ svn log -r 2 ------------------------------------------------------------------------ $ </pre><p>At first glance, this seems like an error. But recall that while revisions are repository-wide, <span class="command"><strong>svn log</strong></span> operates on a path in the repository. If you supply no path, Subversion uses the current working directory as the default target. As a result, if you're operating in a subdirectory of your working copy and attempt to see the log of a revision in which neither that directory nor any of its children was changed, Subversion will show you an empty log. If you want to see what changed in that revision, try pointing <span class="command"><strong>svn log</strong></span> directly at the top-most URL of your repository, as in <span class="command"><strong>svn log -r 2 http://svn.collab.net/repos/svn</strong></span>.</p></div></div><div class="sect2" lang="en" xml:lang="en"><div class="titlepage"><div><div><h3 class="title"><a id="svn.tour.history.diff"></a>Examining the details of historical changes</h3></div></div></div><p>We've already seen <span class="command"><strong>svn diff</strong></span> before—it displays file differences in unified diff format; it was used to show the local modifications made to our working copy before committing to the repository.</p><p>In fact, it turns out that there are <span class="emphasis"><em>three</em></span> distinct uses of <span class="command"><strong>svn diff</strong></span>:</p><div class="itemizedlist"><ul type="disc"><li><p>Examining local changes</p></li><li><p>Comparing your working copy to the repository</p></li><li><p>Comparing repository to repository</p></li></ul></div><div class="sect3" lang="en" xml:lang="en"><div class="titlepage"><div><div><h4 class="title"><a id="svn.tour.history.diff.local"></a>Examining Local Changes</h4></div></div></div><p>As we've seen, invoking <span class="command"><strong>svn diff</strong></span> with no options will compare your working files to the cached “<span class="quote">pristine</span>” copies in the <code class="filename">.svn</code> area:</p><pre class="screen"> $ svn diff Index: rules.txt =================================================================== --- rules.txt (revision 3) +++ rules.txt (working copy) @@ -1,4 +1,5 @@ Be kind to others Freedom = Responsibility Everything in moderation -Chew with your mouth open +Chew with your mouth closed +Listen when others are speaking $ </pre></div><div class="sect3" lang="en" xml:lang="en"><div class="titlepage"><div><div><h4 class="title"><a id="svn.tour.history.diff.wcrepos"></a>Comparing Working Copy to Repository</h4></div></div></div><p>If a single <code class="option">--revision</code> (<code class="option">-r</code>) number is passed, then your working copy is compared to the specified revision in the repository.</p><pre class="screen"> $ svn diff -r 3 rules.txt Index: rules.txt =================================================================== --- rules.txt (revision 3) +++ rules.txt (working copy) @@ -1,4 +1,5 @@ Be kind to others Freedom = Responsibility Everything in moderation -Chew with your mouth open +Chew with your mouth closed +Listen when others are speaking $ </pre></div><div class="sect3" lang="en" xml:lang="en"><div class="titlepage"><div><div><h4 class="title"><a id="svn.tour.history.diff.reposrepos"></a>Comparing Repository to Repository</h4></div></div></div><p>If two revision numbers, separated by a colon, are passed via <code class="option">--revision (-r)</code>, then the two revisions are directly compared.</p><pre class="screen"> $ svn diff -r 2:3 rules.txt Index: rules.txt =================================================================== --- rules.txt (revision 2) +++ rules.txt (revision 3) @@ -1,4 +1,4 @@ Be kind to others -Freedom = Chocolate Ice Cream +Freedom = Responsibility Everything in moderation Chew with your mouth open $ </pre><p>A more convenient way of comparing a revision to the previous revision is to use the <code class="option">--change (-c)</code>: </p><pre class="screen"> $ svn diff -c 3 rules.txt Index: rules.txt =================================================================== --- rules.txt (revision 2) +++ rules.txt (revision 3) @@ -1,4 +1,4 @@ Be kind to others -Freedom = Chocolate Ice Cream +Freedom = Responsibility Everything in moderation Chew with your mouth open $ </pre><p>Lastly, you can compare repository revisions even when you don't have a working copy on your local machine, just by including the appropriate URL on the command line:</p><pre class="screen"> $ svn diff -c 5 http://svn.example.com/repos/example/trunk/text/rules.txt … $ </pre></div></div><div class="sect2" lang="en" xml:lang="en"><div class="titlepage"><div><div><h3 class="title"><a id="svn.tour.history.browsing"></a>Browsing the repository</h3></div></div></div><p>Using <span class="command"><strong>svn cat</strong></span> and <span class="command"><strong>svn list</strong></span>, you can view various revisions of files and directories without changing the working revision of your working copy. In fact, you don't even need a working copy to use either one.</p><div class="sect3" lang="en" xml:lang="en"><div class="titlepage"><div><div><h4 class="title"><a id="svn.tour.history.browsing.cat"></a><span class="command"><strong>svn cat</strong></span></h4></div></div></div><p>If you want to examine an earlier version of a file and not necessarily the differences between two files, you can use <span class="command"><strong>svn cat</strong></span>:</p><pre class="screen"> $ svn cat -r 2 rules.txt Be kind to others Freedom = Chocolate Ice Cream Everything in moderation Chew with your mouth open $ </pre><p>You can also redirect the output directly into a file:</p><pre class="screen"> $ svn cat -r 2 rules.txt > rules.txt.v2 $ </pre></div><div class="sect3" lang="en" xml:lang="en"><div class="titlepage"><div><div><h4 class="title"><a id="svn.tour.history.browsing.list"></a><span class="command"><strong>svn list</strong></span></h4></div></div></div><p>The <span class="command"><strong>svn list</strong></span> command shows you what files are in a repository directory without actually downloading the files to your local machine:</p><pre class="screen"> $ svn list http://svn.collab.net/repos/svn README branches/ clients/ tags/ trunk/ </pre><p>If you want a more detailed listing, pass the <code class="option">--verbose (-v)</code> flag to get output like this:</p><pre class="screen"> $ svn list -v http://svn.collab.net/repos/svn 20620 harry 1084 Jul 13 2006 README 23339 harry Feb 04 01:40 branches/ 21282 sally Aug 27 09:41 developer-resources/ 23198 harry Jan 23 17:17 tags/ 23351 sally Feb 05 13:26 trunk/ </pre><p>The columns tell you the revision at which the file or directory was last modified, the user who modified it, the size if it is a file, the date it was last modified, and the item's name.</p><div class="warning" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Warning</h3><p>The <span class="command"><strong>svn list</strong></span> with no arguments defaults to the <span class="emphasis"><em>repository URL</em></span> of the current working directory, <span class="emphasis"><em>not</em></span> the local working copy directory. After all, if you wanted a listing of your local directory, you could use just plain <span class="command"><strong>ls</strong></span> (or any reasonable non-Unixy equivalent).</p></div></div></div><div class="sect2" lang="en" xml:lang="en"><div class="titlepage"><div><div><h3 class="title"><a id="svn.tour.history.snapshots"></a>Fetching older repository snapshots</h3></div></div></div><p>In addition to all of the above commands, you can use <span class="command"><strong>svn update</strong></span> and <span class="command"><strong>svn checkout</strong></span> with the <code class="option">--revision</code> option to take an entire working copy “<span class="quote">back in time</span>” <sup>[<a id="id353066" href="#ftn.id353066" class="footnote">9</a>]</sup>:</p><pre class="screen"> $ svn checkout -r 1729 # Checks out a new working copy at r1729 … $ svn update -r 1729 # Updates an existing working copy to r1729 … </pre><div class="tip" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Tip</h3><p>Many Subversion newcomers attempt to use the above <span class="command"><strong>svn update</strong></span> example to “<span class="quote">undo</span>” committed changes, but this won't work as you can't commit changes that you obtain from backdating a working copy if the changed files have newer revisions. See <a class="xref" href="svn.branchmerge.advanced.html#svn.branchmerge.advanced.resurrect" title="Resurrecting Deleted Items">the section called “Resurrecting Deleted Items”</a> for a description of how to “<span class="quote">undo</span>” a commit.</p></div><p>Lastly, if you're building a release and wish to bundle up your files from Subversion but don't want those pesky <code class="filename">.svn</code> directories in the way, then you can use <span class="command"><strong>svn export</strong></span> to create a local copy of all or part of your repository sans <code class="filename">.svn</code> directories. As with <span class="command"><strong>svn update</strong></span> and <span class="command"><strong>svn checkout</strong></span>, you can also pass the <code class="option">--revision</code> option to <span class="command"><strong>svn export</strong></span>:</p><pre class="screen"> $ svn export http://svn.example.com/svn/repos1 # Exports latest revision … $ svn export http://svn.example.com/svn/repos1 -r 1729 # Exports revision r1729 … </pre></div><div class="footnotes"><br /><hr width="100" align="left" /><div class="footnote"><p><sup>[<a id="ftn.id353066" href="#id353066" class="para">9</a>] </sup>See? We told you that Subversion was a time machine.</p></div></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="svn.tour.cycle.html">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="svn.tour.html">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="svn.tour.cleanup.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Basic Work Cycle </td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right" valign="top"> Sometimes You Just Need to Clean Up</td></tr></table></div></body></html>