[svn.haxx.se] · SVN Dev · SVN Users · SVN Org · TSVN Dev · TSVN Users · Subclipse Dev · Subclipse Users · this month's index

Re: Subversion "labels" vs. "tags"

From: Tim Hill <tim_at_realmsys.com>
Date: 2005-06-03 19:31:18 CEST

Comments inline...

Julian Foad wrote:

> Tim Hill wrote:
>
>> ok, let's consider patch propogation.
>
>
> Cool. Thanks for taking the time to present this use case.
>
> Now, as usual, I'm going to go through it and comment. Well, OK, I'm
> going to push the case for the present Subversion tags mechanism a
> bit, but I think I need to push a bit in order to draw out a good
> argument from you. :-) I hope you don't mind.

Of course not -- it forces me to justify things to myself as I create
the case. Good dialog :)

>
> Oh, and let me make it clear that I don't necessarily think
> revision-alias labels are a bad idea; I'm still just trying to fully
> understand the rationale for them.
>
> By the way, I don't know, but it might help a bit to know what your
> background is. For example, are you accustomed to some particular
> version control system other than Subversion, or do you have wide
> experience, or what? One thing that makes me wonder is in the next
> sentence where you refer to your mainline build as the "main branch";
> if you were accustomed to Subversion you would have called it the
> "trunk".

25 years of software development and driving s/w teams, mostly
system-level (OS, tools etc.). Have used SCC from SCCS, RCS, PVCS, VSS
(yuck), versions of Perforce and SVN. And just so you know, I consider
SVN to be the best I've yet seen, which is why I'm pushing to fill what
few holes I see in the product :) The "main" thing comes from a large
nameless s/w company, but I chose it on purpose to try to abstract away
from svn-specific stuff.

>
>> I have a mainline build ("main" branch) and a release branch ("rel1")
>> that just takes bug fixes for a released version of the product. The
>> mainline undergoes cycles of dev/test/stabilize, and at each
>> stabilization point a "stable" tag is created so that the last stable
>> build is easily accessible.
>
>
> OK, I imagine that's a common scenario.
>
>> A bug is found in the mainline in "foo.c". It is tracked in a defect
>> tool, fixed in the mainline, checked-in, and undergoes the normal
>> dev/test/stabilize process. Product support then decides that the bug
>> is serious enough that it should be fixed in the "rel1" branch also,
>> ready for the 1.1 release.
>
>
> OK.
>
>> How do I merge the fix into the "rel1" branch? Specifically, which
>> revisions off the mainline do I compare to get the changes necessary
>> to push into "foo.c" in the "rel1" branch?
>>
>> There are actually four points in time that are significant (working
>> backwards):
>> [1] The rev# of the latest stable build of the mainline branch. Call
>> this rev# STABLE.
>> [2] The rev# where the fix to "foo.c" was checked into the mainline
>> (that is, when the defect was marked as fixed). Call this rev# FIXED.
>> [3] The rev# where the last change to "foo.c" was made prior to
>> FIXED. Call this rev# PREFIXED.
>> [4] The rev# where "rel1" was branched off of the mainline. Call this
>> rev# REL1.
>>
>> What I want to merge into the head of "rel1" is: DIFF foo.c -r
>> PREFIXED:FIXED. However I also need to examine DIFF foo.c -r
>> REL1:PREFIXED to make sure that the fix does not depend upon changes
>> made to foo.c between REL1 and PREFIXED. Note that I cannot take DIFF
>> -r PREFIXED:STABLE since other changes may have occurred in foo.c
>> between FIXED and STABLE (I'm assuming "rel1" has its own
>> testing/stabilization cycle).
>
>
> OK.
>
>> How do I locate and use the various rev# values needed? STABLE is
>> available in the "stable" tag noted above, so that's easy (but not
>> much use in this scenario).
>>
>> Neither FIXED not PREFIXED are available via tagging.
>
>
> Well, that depends whether you tagged them! (Actually I wouldn't
> expect you to have tagged PREFIXED - see below - but you suggest below
> that you would have labeled FIXED if you had labels, so I suggest you
> would have tagged it if you only have tags.)

Really? see below.

>
>> Assuming I'm using the recommended best practice of marking defect #s
>> in the message log, I will need to manually examine the log to
>> extract the rev# from the log messages.
>
>
> Well, actually what you need to do is find the revision number in
> which the fix was made, if you haven't tagged it. To find the
> revision number, you could look through the log messages, or perhaps
> you can look in your bug tracker, or perhaps you have it in a revision
> property as I mention under your point (b) below. In this project we
> try to close bugs in the issue tracker with a comment like "Fixed in
> r1234.", so the information is fairly easy to find manually.
>
>> REL1 is available via the --stop-on-copy switch, but this is not
>> available in the DIFF or MERGE commands, only LOG. So , again, I have
>> to do a manual scan of the log to obtain the rev#.
>
>
> Again, you only have to do a manual scan if you haven't tagged it. I
> would expect that you would have tagged it. At the time when you
> started your "rel1" branch you would have done:
>
> svn copy . $BRANCHES/rel1 # start a "rel1" branch
> svn copy $BRANCHES/rel1 $TAGS/rel1-start # label your "rel1" starting
> point
>
> and then you would start to modify the "rel1" branch, and you would
> tag various release candidates ("rel1-rc1" or whatever) along the road
> towards finishing it. When finished, you would tag the final version
> of it ("rel1") and delete the branch.
>
> svn checkout $BRANCHES/rel1
> # modify stuff; it seems stable enough to release
> svn cp . $TAGS/rel1-rc1 # tag a release candidate
> # now it's been tested and is definitely stable and complete
> svn copy . $TAGS/rel1 # tag the final version of it
> svn delete $BRANCHES/rel1 # the branch is no longer
> needed
>
> At least that's roughly how we do it in this Subversion project.
> Actually, we haven't been tagging the start of the branch, but we
> could and would do if we found it useful.
>
>> This is a lot of work for what is not an unusual scenario. How can it
>> made less manual (read: less error-prone)?
>
>
>> (a) I could add lots of tags. If FIXED was available as a tag, that
>> would work. But creating a tag for *every* defect fix seems
>> excessive, even if tags are cheap. And who will remember to do this?
>
>
> Umm... it'll be fun to see if you can convince us that the same
> comments don't apply to revision-alias labels :-)
>
>> More importantly, how do I locate PREFIXED? This is a *relative* rev#
>> and is conceptually related to the COMMITTED rev#, but with an
>> arbitrary starting point.
>
>
> Actually, this is easy if you are working with actual revision numbers
> either manually or in a programming/scripting language: you can just
> subtract 1. You can see that this is correct by thinking about the
> difference between foo.c in revision PREFIXED and revision (FIXED-1):
> by definition, there is no difference.

hehe -- absolutely right, you got me on that! Serves me right for
writing an email late at night.

>
> If you are working with a tag, then you can't at present get
> Subversion to calculate the previous revision for you. That is a
> deficiency which I admit is important in this scenario.
>
> There was a proposal for adding a syntax for doing this within the
> revision-number argument: something like "-rHEAD-1" or
> "-r{2005-05-31}-1" would mean the previous version of the item before
> the version in HEAD or the specified date, and "-rBLAH-2" would mean 2
> versions of the item before BLAH (which is different from the revision
> number that is 2 less than "-rBLAH"). The proposal was quite well
> developed - not far from being committable - but it didn't get
> finished or approved or whatever. We might want to ressurect it.
>
> I'm not sure whether that proposal would allow you to get the version
> that came before a particular tag. It might, something like:
> "$TAGS/rel1-start/foo.c -rHEAD-1".
>
> Anyway, I concede that there is definitely missing functionality here,
> and I don't think this has been mentioned before in this discussion so
> thank you for bringing this point to light.

I did discuss this in a thread on the users forum. Off topic, I do feel
that the svn database contains a log of valuable information (and could
contain more) that is currently difficult to mine because of limitations
in the representation of revisions to the toolchain.

>
>
>> (b) I could create a script to do the necessary SVN LOG scan, pluck
>> out the rev#, and paste it into a DIFF/MERGE command. This could work
>> for FIXED, but not PREFIXED.
>
>
> Actually it does work for PREFIXED, by subtracting 1 from FIXED.

ok, don't rub it in!!! :)

>
>> And it depends upon well-formatted log file messages, and
>> "prayer-based parsing" common to semi-formal data sets.
>
>
> Yes. Similarly the script could get the information from a dedicated
> "bug number" revision property (look up "revision properties" in the
> Subversion book if this doesn't make sense), or from your bug
> tracker. Either of those could give you the information in a more
> formal structure.

I agree -- but the issue is that having created this formal data svn
doesn't really allow me to do much with it, programmatically speaking.

>
>> (c) Use mnemonic labels for revisions, and a convention that creates
>> a label named "DEFECT-FIX:nnnn" for appropriate check-ins.
>
>
> Right! Now, why don't your arguments above about tags apply equally
> to this? You said:
>
> "But creating a tag for *every* defect fix seems excessive, even if
> tags are cheap. And who will remember to do this?"
>
> I say: Creating a tag or a label for every defect only seems excessive
> if you think the creation is an expensive operation or if the list of
> them is going to make it hard to find other kinds of tags/labels.
> Creation (of a tag) is not expensive, and to keep from cluttering your
> list of release tags (say), you can use a separate tag name space -
> e.g. "$TAGS/bugs/..." (This begs the question of whether the "labels"
> mechanism would want such a namespace mechanism.)

But, really, is creating a tag, with all the branching etc needed, as
easy as this:

    svn commit foo.c --label "DEFECT-FIX:1234"

???
Or, better yet, just using a generic property switch (below).

>
> As for remembering to do it, well, what's there's no difference
> between remembering to create a tag and remembering to create a
> label. Presumably you would automate it.
>
>> Now FIXED is *directly* accessible to me *and* the toolchain.
>
>
> It appears to me that it would be accessible to the "svn" command via
> the "-r" option argument rather than via a normal non-option
> argument. Is that all you mean by "directly"?
>
> Perhaps I'm being unreasonably hard on you. I can see that there is
> some fairly profound respect in which identifying a marked point in
> history by path (a tag) is different from identifying it by revision
> (a label) ... I just don't know what the implications of this
> difference are.

ok, what I'm really getting at is that labels should be able to act as a
*function* within a command-line; the return value of the label is its
rev#, and this return value can be used *within* an svn command wherever
a rev# is expected. Tags can *represent* a rev#, but this implied
information can only be recovered in certain commands and only implicitly.

You mention the use of revision properties, which would indeed be a
prefect way to handle my scenario EXCEPT that there is no way to feed
the value of such a property back into an svn command. IMHO svn is
crying out for a way to access properties within the command line. In
fact, providing such a feature would in fact provide a perfectly valid
label mechanism virtually for free, as well as any number of other
useful enhancements.

>
>> This leaves PREFIXED up in the air, however.
>
>
> Addressed above.
>
>
>> So, my ideal is the command:
>>
>> svn diff foo.c --revision PRIOR:!DEFECT-FIX:1234
>>
>> Or something like it. Here I'm using "!" to indicate a rev# expressed
>> as a label (insert your own syntax here), and am assuming PRIOR means
>> "the last time this item was changed" (like COMMITTED but relative to
>> the other rev#).
>
>
> OK. The tags version of that command would be something like:
>
> svn diff $TAGS/DEFECT-FIX-1234/foo.c --revision HEAD-1:HEAD
>
> (The syntax "HEAD-1" or "PRIOR" is not supported yet, but that seems
> to be equally necessary for either approach.)
>
>> Skipping the ugly syntax and some significant issues around the
>> semantics/implementation of PRIOR, I think this is a significant
>> improvement over manually scanning logs.
>
>
> It seems to me that the syntax and the ability to specify one revision
> relative to another are perhaps some of the most important issues
> here. However, you are certainly bringing out some interesting points
> and helping us to understand the issue. Thanks for your continuing
> patience in working through this.
>
> - Julian

ok, lets' see where I think we are...

1. I think we agree that there might be a case for some enhancements to
relative revision numbers to handle the PRIOR or -1 case.

2. I'm not clear on your position wrt how the rev# of the defect
check-in is tracked. At one point I think you're arguing that, yes, you
*should* indeed create a tag for each such check-in. otoh you also
mention the use of revision properties (yes, I'm well aware of the
property system in svn -- a feature I very much like). There are
typically hundreds/thousands of defects in a medium project. Is the tool
*really* up to managing all those tags? Are users/admins?

>
>
>>> Julian Foad wrote:
>>>
>>>> Tim Hill wrote:
>>>>
>>>>> Yes, this is certainly one way. The main objection I have to the
>>>>> current scheme is that tags are just a convention, and as a result
>>>>> the toolchain cannot use the implied REV# information directly --
>>>>> it has to be manually imputed by a user and translated by him/her
>>>>> to a REV# for consumption by the toolchain. This makes
>>>>> scripting/automation difficult for some common SVN operations and
>>>>> adds burden to the dev process.
>>>>
>>>>
>>>> Please give an example (stating the desired task and showing actual
>>>> commands for doing it) of a situation in which the user has to do
>>>> this "translation".
>>>
>
>
Received on Fri Jun 3 19:36:47 2005

This is an archived mail posted to the Subversion Dev mailing list.