You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@subversion.apache.org by Tim Hill <ti...@realmsys.com> on 2005/06/01 18:32:05 UTC

Re: Subversion "labels" vs. "tags"

ok, let's consider patch propogation. 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.

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.

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).

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. 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.

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#.

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? 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.

(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. And it depends upon well-formatted log file 
messages, and "prayer-based parsing" common to semi-formal data sets.

(c) Use mnemonic labels for revisions, and a convention that creates a 
label named "DEFECT-FIX:nnnn" for appropriate check-ins. Now FIXED is 
*directly* accessible to me *and* the toolchain. This leaves PREFIXED up 
in the air, however.

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#). 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.

--Tim


Julian Foad wrote:

> 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".
>
>
> What I'm getting at is that a tag is not _just_ an alias for a 
> revision number, and you shouldn't have to convert it to a revision 
> number in order to use it in common situations.  You should be able to 
> specify it directly in the command - not within the "--revision" 
> parameter, because it isn't just a revision, but somewhere in the 
> command.
>
> For my example of where you don't have to manually convert it to a 
> revision number, I'll find the difference between "foo.c" as it was at 
> tag TAG1 and now:
>
> svn diff --old=$TAGS/TAG1 --new=. foo.c
>
> I'll admit again that this syntax is not quite as brief as you might 
> want, but it's not grossly inappropriate either, is it?  Also, I'll 
> admit again that using an environment variable like that is flakey and 
> not really acceptable in more complex situations, but that's 
> irrelevant to the argument that the user needs to translate the tag to 
> a revision number manually.
>
> - Julian
>

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org

Re: Subversion "labels" vs. "tags"

Posted by Brad Appleton <br...@gmail.com>.
Tim Hill wrote:
> ok, let's consider patch propogation. 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.
> 
> 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.
> 
> 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?

Thanks Tim for introducing this real-world scenario!

Thinking totally outside of any specific implementation, my first 
inclination is to think of a change-set or change-package that 
identifies ONLY the set of files that were created/updated to make the 
fix and the set of changes/revisions for each file. Those are the set of 
files and file versions I want to merge to rel1.

So if a bugfix name/number can be associated with the revision that was 
created when I committed the fix to the mainline (and assuming I didnt 
do any intermediate "commits" while fixing the bug - which is a BIG 
assumption) then I want to apply that revno to only those files that 
were changed/added/removed for the bugfix.

This means a revision-alias by itself may be insufficient. The 
corresponding revnum tells me the configuration of the codebase at the 
time of the commit. It does not give me any easy way to distinguish the 
CONTENT of the change/fix from its CONTEXT:
* The CONTENT of the change is the set of changes made to the set of 
files+directories that were changed
* The CONTEXT of the change is everything that was NOT changed that was 
used to build+test prior to committing my changes.

So, regardless of whether I used a "copy" or a revision-alias, I would 
have to do some extra work to identify the CONTENT of the change: either 
by limiting the "copy" to be only the set of files changed, or by having 
a separate mechanism to know the set of files changed and then 
associating it with either a copy or a revision-alias.

In general it seems it would be useful to have some auto/builtin 
*qualifier* as a shorthand that could automatically compute this.
I think it would be useful to be able to say something like
REVNO[QUALIFIER], as in HEAD[changed] or HEAD[!changed] or HEAD[wildcard]

I dont particularly like the syntax in my example, but hopefully you get 
the idea. And it something that might apply to both revnums and to 
"copies" (tho maybe not completely for the latter).

Seems to me that regardless of whether revision-aliases are implemented, 
that the ability extract content|context from an associated revno is 
still pretty important.

How do I do this today in SVN? Is there a builtin, or do I have to 
conjure it up on my own using various conventions and assumptions? (and 
properties|comments?)

-- 
Brad Appleton <br...@bradapp.net> www.bradapp.net
    Software CM Patterns (www.scmpatterns.com)
    Effective Teamwork, Practical Integration
"And miles to go before I sleep" --Robert Frost


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org

Re: Subversion "labels" vs. "tags"

Posted by Tim Hill <ti...@realmsys.com>.
(below...)

Julian Foad wrote:

> Tim Hill wrote:
>
>> 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.
>
>
> That's about twice my experience in all respects, so I'm _very_ glad 
> to have your help.
>
>>> [you could store the bug number in a revision property]
>>
>>
>> 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.
>
>
> Hmm ... yes.
>
>> But, really, is creating a tag, with all the branching etc needed, as 
>> easy as this:
>>
>>     svn commit foo.c --label "DEFECT-FIX:1234"
>
>
> Well, it requires two separate svn commands but it's even easier than 
> that if you write a script/macro/shell-function to help:
>
>   svn-commit-fix 1234 foo.c
>
> where svn-commit-fix is
> [[[
> #!/bin/sh
> REPOS=http://...
> FIX=$1
> shift
> svn commit "$@" &&
>   svn copy $REPOS/trunk $REPOS/tags/DEFECT-FIX-$FIX
> ]]]
>
>
> OK, so some things ought to be built-in, and using external scripts 
> and environment variables is not ideal, but I'm trying to concentrate 
> on the important facets of the functionality and not worry about the 
> command-line syntax to invoke it yet.  We can easily add some built-in 
> syntax if we think it's important.
>
> More important is that that method results in two commits.  That is a 
> bigger deal, perhaps indicating that it isn't doing conceptually what 
> you want.  In your example, the label was to be applied at the same 
> time as the commit, but in practice this would only sometimes be the 
> case.  At other times, the user would apply the label later, so we 
> shouldn't be thinking about how to combine the two commits into one, 
> but we do need to think about whether the action of labelling should 
> be a versioned event.
>
> Do you have any views yet on whether you would want revision-alias 
> labels to be version-controlled, or on what the significant 
> implications would be if they were or weren't?
>
>
>> 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.
>
>
> Well, that's really just saying that what we mean by a "label" is an 
> alias for a revision number, on which I think we are roughly in 
> agreement.  Unless you mean that it should be a more general function 
> than a simple 1-to-1 mapping?
>
>
>> 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.
>
>
> That's an interesting idea.  Would you care to start a separate mail 
> thread about it?
>
>
>> 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.
>
>
> Yes.
>
>> 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.
>
>
> What I was really saying is that if you want to refer to them by name 
> rather than number, which is your basic premise, then yes, creating a 
> tag is the closest you can get to your ideal in basic command-line 
> usage at present.
>
>>  otoh you also mention the use of revision properties
>
>
> What I was thinking there is that if you, as administrator, currently 
> want to set up a system that links Subversion to your bug tracker and 
> provides the easiest possible command-line experience for your users, 
> the best way is probably by writing scripts that store and use the bug 
> number in a revision property.
>
>> typically hundreds/thousands of defects in a medium project. Is the 
>> tool *really* up to managing all those tags? Are users/admins?
>
>
> Another good point.  No, not when they all go into one directory.  A 
> thousand should be fine but gets slow on BerkeleyDB repositories, and 
> some large projects have hundreds of thousands of issues reported.  
> Issue #2067 ("Perf issues with BDB and directories with a large number 
> of items") is a major factor on BDB, but it's probably not the only 
> problem that would make large lists unmanageable.  Of course, it might 
> not be much easier to ensure that a dedicated list of labels remains 
> manageable.
>
>
>
> This is what I think we should do next:
>
> + Consider various avenues that cropped up that might be useful 
> regardless of labelling, such as revision-number arithmetic (issue 
> #1213) and substitution of property values into a command.  We should 
> file issues for these as and when they are moderately well thought out.
>
> + Write a detailed proposal for revision-alias labels that would cover 
> this simple use case, and discuss it.
>
> + Consider a more complex use case like the following:  Each bug fix 
> to be tracked consists of a series of non-consecutive commits.  If it 
> is known in advance that the fix will be complex, then that work is 
> done on a branch, and the result is afterwards merged to the trunk, 
> but often a commit is made to the trunk that aims to fix the bug, but 
> is then seen to be incomplete and one or more follow-ups are made, 
> with other unrelated commits happening in between them.  We need to 
> determine whether and how "labels" should track this situation.

I agree with this. I'm going to go off-line for a few days and work this 
up, and will then re-post here.

--Tim

>
> - Julian
>

Re: Subversion "labels" vs. "tags"

Posted by Julian Foad <ju...@btopenworld.com>.
Tim Hill wrote:
> 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.

That's about twice my experience in all respects, so I'm _very_ glad to have 
your help.

>> [you could store the bug number in a revision property]
> 
> 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.

Hmm ... yes.

> But, really, is creating a tag, with all the branching etc needed, as 
> easy as this:
> 
>     svn commit foo.c --label "DEFECT-FIX:1234"

Well, it requires two separate svn commands but it's even easier than that if 
you write a script/macro/shell-function to help:

   svn-commit-fix 1234 foo.c

where svn-commit-fix is
[[[
#!/bin/sh
REPOS=http://...
FIX=$1
shift
svn commit "$@" &&
   svn copy $REPOS/trunk $REPOS/tags/DEFECT-FIX-$FIX
]]]


OK, so some things ought to be built-in, and using external scripts and 
environment variables is not ideal, but I'm trying to concentrate on the 
important facets of the functionality and not worry about the command-line 
syntax to invoke it yet.  We can easily add some built-in syntax if we think 
it's important.

More important is that that method results in two commits.  That is a bigger 
deal, perhaps indicating that it isn't doing conceptually what you want.  In 
your example, the label was to be applied at the same time as the commit, but 
in practice this would only sometimes be the case.  At other times, the user 
would apply the label later, so we shouldn't be thinking about how to combine 
the two commits into one, but we do need to think about whether the action of 
labelling should be a versioned event.

Do you have any views yet on whether you would want revision-alias labels to be 
version-controlled, or on what the significant implications would be if they 
were or weren't?


> 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.

Well, that's really just saying that what we mean by a "label" is an alias for 
a revision number, on which I think we are roughly in agreement.  Unless you 
mean that it should be a more general function than a simple 1-to-1 mapping?


> 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.

That's an interesting idea.  Would you care to start a separate mail thread 
about it?


> 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.

Yes.

> 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.

What I was really saying is that if you want to refer to them by name rather 
than number, which is your basic premise, then yes, creating a tag is the 
closest you can get to your ideal in basic command-line usage at present.

>  otoh you also mention the use of revision properties

What I was thinking there is that if you, as administrator, currently want to 
set up a system that links Subversion to your bug tracker and provides the 
easiest possible command-line experience for your users, the best way is 
probably by writing scripts that store and use the bug number in a revision 
property.

> typically hundreds/thousands of defects in a medium project. Is the tool 
> *really* up to managing all those tags? Are users/admins?

Another good point.  No, not when they all go into one directory.  A thousand 
should be fine but gets slow on BerkeleyDB repositories, and some large 
projects have hundreds of thousands of issues reported.  Issue #2067 ("Perf 
issues with BDB and directories with a large number of items") is a major 
factor on BDB, but it's probably not the only problem that would make large 
lists unmanageable.  Of course, it might not be much easier to ensure that a 
dedicated list of labels remains manageable.



This is what I think we should do next:

+ Consider various avenues that cropped up that might be useful regardless of 
labelling, such as revision-number arithmetic (issue #1213) and substitution of 
property values into a command.  We should file issues for these as and when 
they are moderately well thought out.

+ Write a detailed proposal for revision-alias labels that would cover this 
simple use case, and discuss it.

+ Consider a more complex use case like the following:  Each bug fix to be 
tracked consists of a series of non-consecutive commits.  If it is known in 
advance that the fix will be complex, then that work is done on a branch, and 
the result is afterwards merged to the trunk, but often a commit is made to the 
trunk that aims to fix the bug, but is then seen to be incomplete and one or 
more follow-ups are made, with other unrelated commits happening in between 
them.  We need to determine whether and how "labels" should track this situation.

- Julian

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org

Re: Subversion "labels" vs. "tags"

Posted by Tim Hill <ti...@realmsys.com>.
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".
>>>
>
>

Re: Subversion "labels" vs. "tags"

Posted by Julian Foad <ju...@btopenworld.com>.
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.

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".

> 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.)

> 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.

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.


> (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.

> 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.

> (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.)

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.

> 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


>> 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".


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org