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