This text is a work in progress—highly subject to change—and may not accurately describe any released version of the Apache™ Subversion® software. Bookmarking or otherwise referring others to this page is probably not such a smart idea. Please visit for stable versions of this book.

Peg and Operative Revisions

Chúng ta sao chép, di chuyển, đổi tên và thay thế hoàn toàn những tập tin và thư mục trong máy của chúng ta rất thường xuyên. Hệ thống kiểm soát phiên bản của bạn không nên theo cách của bạn làm những việc này trên những tập tin và thư mục đã được kiểm soát phiên bản. Hỗ trợ quản lý tập tin của Subversion rất linh động, cung cấp một độ linh hoạt tương tự khi bạn thao tác những tập tin chưa định phiên bản. Subversion's file management support is quite liberating, affording almost as much flexibility for versioned files as you'd expect when manipulating your unversioned ones. But that flexibility means that across the lifetime of your repository, a given versioned object might have many paths, and a given path might represent several entirely different versioned objects. This introduces a certain level of complexity to your interactions with those paths and objects.

Subversion khá thông minh trong việc để ý khi lịch sử phiên bản của một đối tượng có bao gồm loại thay đổi địa chỉ này. Ví dụ, nếu bạn yêu cầu nhật ký lịch sử phiên bản của một tập tin cụ thể mà đã được đổi tên vào tuần trước, Subversion sẽ cung cấp toàn bộ nhật ký đó—phiên bản mà trong đó việc đổi tên bản thân nó diễn ra, cộng thêm nhật ký của những phiên bản liên quan trước và sau việc đổi tên này. Vì vậy, đa số thời gian bạn không cần thiết phải suy nghĩ về những vấn đề này. Tuy nhiên, thỉnh thoảng Subversion cần sự trợ giúp của bạn trong việc làm rõ một số vấn đề không rõ ràng.

Ví dụ đơn giản nhất của điều này xảy ra khi một thư mục hoặc tập tin bị xoá bỏ khỏi kiểm soát phiên bản, sau đó một thư mục hoặc một tập tin được tạo ra với cùng tên và được thêm vào kiểm soát phiên bản. Cái mà bạn xoá và cái mà bạn thêm vào sau đó không phải là một. Chúng chỉ đơn thuần là tình cờ có cùng một đường dẫn—ví dụ, /trunk/object. Cái gì, có phải là bạn yêu cầu Subversion cung cấp lịch sử của /trunk/object? Có phải bạn đang hỏi về đối tượng hiện đang ở vị trí này, hay cái cũ mà bạn đã xoá khỏi vị trí này? Có phải bạn đang hỏi về việc đã xảy ra với tất cả những đối tượng mà đã từn tồn tại ở đường dẫn này? Subversion cần gợi ý về điều mà bạn thực sự cần thực hiện.

And thanks to moves, versioned object history can get far more twisted than even that. For example, you might have a directory named concept, containing some nascent software project you've been toying with. Eventually, though, that project matures to the point that the idea seems to actually have some wings, so you do the unthinkable and decide to give the project a name.[11] Let's say you called your software Frabnaggilywort. At this point, it makes sense to rename the directory to reflect the project's new name, so concept is renamed to frabnaggilywort. Life goes on, Frabnaggilywort releases a 1.0 version and is downloaded and used daily by hordes of people aiming to improve their lives.

It's a nice story, really, but it doesn't end there. Entrepreneur that you are, you've already got another think in the tank. So you make a new directory, concept, and the cycle begins again. In fact, the cycle begins again many times over the years, each time starting with that old concept directory, then sometimes seeing that directory renamed as the idea cures, sometimes seeing it deleted when you scrap the idea. Or, to get really sick, maybe you rename concept to something else for a while, but later rename the thing back to concept for some reason.

In scenarios like these, attempting to instruct Subversion to work with these reused paths can be a little like instructing a motorist in Chicago's West Suburbs to drive east down Roosevelt Road and turn left onto Main Street. In a mere 20 minutes, you can cross Main Street in Wheaton, Glen Ellyn, and Lombard. And no, they aren't the same street. Our motorist—and our Subversion—need a little more detail to do the right thing.

Fortunately, Subversion allows you to tell it exactly which Main Street you meant. The mechanism used is called a peg revision, and you provide these to Subversion for the sole purpose of identifying unique lines of history. Because at most one versioned object may occupy a path at any given time—or, more precisely, in any one revision—the combination of a path and a peg revision is all that is needed to unambiguously identify a specific line of history. Peg revisions are specified to the Subversion command-line client using at syntax, so called because the syntax involves appending an at sign (@) and the peg revision to the end of the path with which the revision is associated.

But what of the --revision (-r) of which we've spoken so much in this book? That revision (or set of revisions) is called the operative revision (or operative revision range). Once a particular line of history has been identified using a path and peg revision, Subversion performs the requested operation using the operative revision(s). To map this to our Chicagoland streets analogy, if we are told to go to 606 N. Main Street in Wheaton,[12] we can think of Main Street as our path and Wheaton as our peg revision. These two pieces of information identify a unique path that can be traveled (north or south on Main Street), and they keep us from traveling up and down the wrong Main Street in search of our destination. Now we throw in 606 N. as our operative revision of sorts, and we know exactly where to go.

Say that long ago we created our repository, and in revision 1 we added our first concept directory, plus an IDEA file in that directory talking about the concept. After several revisions in which real code was added and tweaked, we, in revision 20, renamed this directory to frabnaggilywort. By revision 27, we had a new concept, a new concept directory to hold it, and a new IDEA file to describe it. And then five years and thousands of revisions flew by, just like they would in any good romance story.

Now, years later, we wonder what the IDEA file looked like back in revision 1. But Subversion needs to know whether we are asking about how the current file looked back in revision 1, or whether we are asking for the contents of whatever file lived at concept/IDEA in revision 1. Certainly those questions have different answers, and because of peg revisions, you can ask those questions. To find out how the current IDEA file looked in that old revision, you run:

$ svn cat -r 1 concept/IDEA 
svn: E195012: Unable to find repository location for 'concept/IDEA' in revision 1

Of course, in this example, the current IDEA file didn't exist yet in revision 1, so Subversion gives an error. The previous command is shorthand for a longer notation which explicitly lists a peg revision. The expanded notation is:

$ svn cat -r 1 concept/IDEA@BASE
svn: E195012: Unable to find repository location for 'concept/IDEA' in revision 1

And when executed, it has the expected results.

The perceptive reader is probably wondering at this point whether the peg revision syntax causes problems for working copy paths or URLs that actually have at signs in them. After all, how does svn know whether news@11 is the name of a directory in my tree or just a syntax for revision 11 of news? Thankfully, while svn will always assume the latter, there is a trivial workaround. You need only append an at sign to the end of the path, such as news@11@. svn cares only about the last at sign in the argument, and it is not considered illegal to omit a literal peg revision specifier after that at sign. This workaround even applies to paths that end in an at sign—you would use filename@@ to talk about a file named filename@.

Let's ask the other question, then—in revision 1, what were the contents of whatever file occupied the address concepts/IDEA at the time? We'll use an explicit peg revision to help us out.

$ svn cat concept/IDEA@1
The idea behind this project is to come up with a piece of software
that can frab a naggily wort.  Frabbing naggily worts is tricky
business, and doing it incorrectly can have serious ramifications, so
we need to employ over-the-top input validation and data verification

Notice that we didn't provide an operative revision this time. That's because when no operative revision is specified, Subversion assumes a default operative revision that's the same as the peg revision.

As you can see, the output from our operation appears to be correct. The text even mentions frabbing naggily worts, so this is almost certainly the file that describes the software now called Frabnaggilywort. In fact, we can verify this using the combination of an explicit peg revision and explicit operative revision. We know that in HEAD, the Frabnaggilywort project is located in the frabnaggilywort directory. So we specify that we want to see how the line of history identified in HEAD as the path frabnaggilywort/IDEA looked in revision 1.

$ svn cat -r 1 frabnaggilywort/IDEA@HEAD
The idea behind this project is to come up with a piece of software
that can frab a naggily wort.  Frabbing naggily worts is tricky
business, and doing it incorrectly can have serious ramifications, so
we need to employ over-the-top input validation and data verification

And the peg and operative revisions need not be so trivial, either. For example, say frabnaggilywort had been deleted from HEAD, but we know it existed in revision 20, and we want to see the diffs for its IDEA file between revisions 4 and 10. We can use peg revision 20 in conjunction with the URL that would have held Frabnaggilywort's IDEA file in revision 20, and then use 4 and 10 as our operative revision range.

$ svn diff -r 4:10
Index: frabnaggilywort/IDEA
--- frabnaggilywort/IDEA	(revision 4)
+++ frabnaggilywort/IDEA	(revision 10)
@@ -1,5 +1,5 @@
-The idea behind this project is to come up with a piece of software
-that can frab a naggily wort.  Frabbing naggily worts is tricky
-business, and doing it incorrectly can have serious ramifications, so
-we need to employ over-the-top input validation and data verification
+The idea behind this project is to come up with a piece of
+client-server software that can remotely frab a naggily wort.
+Frabbing naggily worts is tricky business, and doing it incorrectly
+can have serious ramifications, so we need to employ over-the-top
+input validation and data verification mechanisms.

Fortunately, most folks aren't faced with such complex situations. But when you are, remember that peg revisions are that extra hint Subversion needs to clear up ambiguity.

[11] You're not supposed to name it. Once you name it, you start getting attached to it.—Mike Wazowski

[12] 606 N. Main Street, Wheaton, Illinois, is the home of the Wheaton History Center. It seemed appropriate…