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

Re: Simple Label=RevisionID Discussion

From: John Rouillard <rouilj_at_renesys.com>
Date: 2006-12-05 18:40:49 CET

Sorry for the delayed response I am at a system admin conference this
week.

On Sat, Dec 02, 2006 at 08:53:14PM -0600, Bob Hiestand wrote:
> On 12/1/06, John Rouillard <rouilj@renesys.com> wrote:
> >Actually it came up just today. We couldn't figure out why a
> >particular line was in the config file. So we did an svn blame, read
> >the log message and got a bit of a clue. Then checked the ticket
> >associated with the change (encoded in the log message yech) and found
> >out why the more efficient change we were going to do wouldn't work.
>
> So in two operations (svn blame and then svn log) you found what you
> were after? That seems reasonable to me. How can this be simpler?

Actually it can't be easier. However making this senario work makes
other senarios's harder compared to CVS.

> >The problem with using an svn branch as a label is that it doesn't
> >relate to the original tree at all. The search I did above had dozens
> >of changes that (should) never have made it into production, but I had
> >to wade through them anyway.
>
> In CVS (which I invoke as it appears to be the point of comparison,
> rather than the requested label design) you have to wade through
> exactly the same information. It would be simpler only if the change
> was merged through multiple branches, thus necessitating (in SVN)
> running multiple instances of the search commands.

That's true, and can occur in more advanced senarios where there are
multiple production branches. I have never used this model but others
have in CVS.
 
> CVS functionality, on the other hand, fails entirely in this if you
> ever want to trace a renamed file. Rather, it gives you the choice:
> either be able to follow renamed files through their history, or be
> able to reconstruct the state of the repository at a branch at any
> time. You can't have both. The SVN method of versioning the file
> system instead of individual files solves this issue.

Agreed. That's part of the reason I am using SVN.

> >What I am currently working through is to have a branch called
> >production. When I need to copy files from testing -> production I
> >need to:
> >
> > svn rm the file in the production branch
> > svn cp the file from test to production
> > (why doesn't copy just copy over the existing production file and
> > create a new version. Anyway...)
>
> I think this is the problem. Without specific knowledge of your
> process, this is not a good fit for the tool and your expressed
> requirements.
>
> Instead of copying individual files, you should be recreating the tag
> entirely. If you do that, the file history you believe is missing is
> preserved transparently.

How do I create a mixed revision tag without a working copy? AFAICT it
is a major tracking nightmare. Even building it from a working copy is
a nightmare. What I need it to update the current HEAD release of a
BRANCH with a few new files from the trunk. These files do not
(necesarily) exist as the HEAD release at any version of the
repository.
 
> >Repeat for each file that needs copying (leaving the production tree
> >in an inconsistant state while the copies are going on). Now in
> >production if I want to use 'svn annotate' I really can't since the
> >removal of the file clobbers the history for the file. I can get to
> >the older version by somehow divining the peg revision (which isn't
> >trivial) and I (assume) I can diff them using 'svn diff
> >production/path production/path@PEG'. However 'svn log' stops at the
> >copy (well goes down the trunk) not down the branch history.
>
> All this goes away if you don't try to promote individual files. Is
> there a reason you are doing it that way?

Yes. In order for testing to occur, all files that are distributed
must go through SVN. It provides the ability to undo the testing
config and distribute the last known good configuration. Let's try a
different (very very simple) example.

   A file (file1) that sets permissions on who can use what in an
   application is changed. It is checked in at rev 1390 (note the prior
   rev of this file that exists at 1389 has been accepted to the
   production). It is then deployed in testing.
  
   While this is going on another file (file2) is changed that allows a
   user to access a different application. It is checked in at revision
   1391. It is deployed in testing.

   Now a problem was discovered in file1, and a new revision of it was
   checked in at rev 1392.

   The person who checked in file2 requests that the file be reviewed for
   production use.

It is reviewed and accepted onto the production branch. How is this to
be done?

    I can't use the trunk at revision 1391 because I will also
    get the broken file1.

    I can't use revision 1393 because I will get the untested file1.

    I can't use rev 1389 because although that revision has a valid
    file1, it doesn't have the proper file2.

If I have a requirement that every version of every file that exists
in production must come from somewhere on the trunk (to reduce the
chance/prevent the case where untested/unreviewed files sitting in
somebody's workspace are allowed on the production branch), how do I
do it?

Copying is my only alternative. This leads to what we discused
above. A nice simple method for determing when a line in a file was
changed, eliminates duplicate comments on the branch and the trunk,
guarantees that the version in production came from the trunk. However
this makes other use cases more difficult.

If I relax my requirements and allow a merge to occur, the I greatly
increase the risk of unintended changes making it onto the production
branch. But I continue anyway and check out a copy of the head of the
production branch. I then merge the individual file file2 from the
trunk at last time it was merged into production to revision
1391. Then I commit the change and provide a log message that allows
me to find the original file's log messages that apply to this
check-in.

The benefit that using a workspace does get me is that I can merge
more than one file in a single commitment and it looks like a single
changeset making rollback much easier. (mucc may allow this single
commit operation for all the copies/detes that are needed under the
copy senario, but I am not sure). Also I can easily determine the
contents/version of the files on the production branch.

However if I commit multiple files, I may have a different revision of
log messages for each file increasing the documentation burden.

The drawback is that I have to do all the merge tracking which isn't
trivial. I may be able to just svn cat the file rather than actually
merging, but I still have the documentation burden.

Plus I now have the non-trivial chance that somebody is going to screw
up their "pristene" working copy and end up comitting something that
they didn't intend. I've almost done it on occassion and my remedy is
to check out the entire tree, make the merges, check in and delete the
tree. Painful in time as it can have 5000+ files in a checkout
scattered across a hundred+ directories (thinking of the largest CVS
deployment I heard about, and being very happy I didn't have to deal
with it 8-)).

> >Also if I want to figure out which revisions of which files in my
> >testing tree made it into production I can do a linear search down the
> >production tree and look at every single copy for every single file at
> >each revision. Takes a while, but that is required for some audit
> >senarios.
>
> Simply running svn info on the files will tell you the last-changed
> revision, which for this purpose is the same as the CVS revision
> number from cvs status.

It will for only the last change, not for the change before that in a
copy senario. I have to use peg revisions. See the use cases below.
 
> >> >>On the other hand, CVS doesn't inherently stop you from moving
> >> >>tags, thereby losing history of how they were placed, which
> >> >>SVN doesn't do.
> >
> >This is true, but by policy you can choose to use both floating and
> >static tags.
>
> Right, a lot of work flow must stem from individual policies. The
> point I was making above is that SVN allows you to retrieve the
> previous state of a floating tag, which isn't possible in CVS.

Yes, but the tag doesn't provide quite the same info as easily as a
tag on CVS does. Lets look at the tag/branch created in SVN using the
copy model or the merge model compared to the CVS tag in three typical
use cases.

I have the same file in production branch and on trunk in SVN and only
one file on trunk in CVS.

Using the svn copy to production model:

  find the development history of the file

    1 svn info/anno on the file in the production tree
         works fine.

    1 cvs info/anno works fine

  find/audit the deployment history (i.e. each version of the file on
    the trunk that was copied to the production branch) or determine
    what version of the file was deployed on a given date

    1 "svn info file" to discover the copy point of the head revision of file
    2 "svn info file@(one less than the copy revision gotten in step 1)"
      returns the prior revision of the file on the production
      branch. Note it will not work without the peg revision.
    3..... repeat 2 as needed to fulfil audit requirements, or find out if
      a given revision of a file on the trunk was moved into production.
  
    1 use "cvs info file" and look at the log for the
      PRODUCTION_<datetime> tags. Each tag corresponds to a prior
      location where that version of the file was in production.
      Also if you need to audit a given version of the trunk file to
      see if it ever made it into production, just cvs log the file
      and see if it has the PRODUCTION_<datetime> tag. If not it never
      made it into production.

   roll back the prior change (also find all files that were changed
      by a single logical promotion)
    1 svn info the current version of the file and extract the
      revision.
    2 delete the current revision of the file
    3 resurrect the prior revision of the file using peg revision
    4 repeat for every file in the "changeset" as manually
      constructed from the revision message (i.e. it wasn't explicitly
      stated above, but the change message to the copy command should
      be the same for all files that are being deployed as a
      set). However if mucc works for commiting the logical single
      delete/copy operations as a single revision change then this is
      as easy as the merge case I think and can just unroll the last
      change.

    1 cvs info the file and find the prior PRODUCTION_<datetime> tag
    2 move the PRODUCTION tag to match the prior PRODUCTION_<datetime>
      tag
    3 repeat for every file that has the same tag
      PRODUCTION_<datetime> as in step 1. (Note finding every file
      is just as bad in a copy model of SVN as in CVS for the non mucc
      case.)

  rollback a change that is not the latest commit to the production tree,
    but is the latest version of the given file(s) on the production
    tree.

    SVN for each file in the logical change delete the head and copy
      from the prior trunk revision (see prior use case to identify
      that revision).

    CVS acts just like rolling back the prior change since it is
      file based. Just choose different files.

Now we analyze these four use cases in the merge model

  find the development history of the file
     1 find the proper name for the file on the trunk
     2 svn info/anno on that file

  find/audit the deployment history or determine what version of the
    file was deployed on a given date

     1 svn info works fine although the log information present on the
        trunk is missing and requires additional svn log/info on the
        trunk version of the file.
  
   roll back the prior change
     1 use svn to unmerge the top two revisions on the tree
     2 check in. (Much easier and less error prone
       than CVS or SVN/copy).

  rollback a change that is not the latest commit to the production tree,
    but is the latest version of the given file(s) on the production tree.

     1 svn up the current wc of the production tree to a mixed
       rev tree with the earlier copies of the file that need to be
       reverted.
     2 check in. (Much easier and less error prone than CVS or SVN/copy).

> >It is just that SVN doesn't implement the work model a number of us
> >are describing. Mainly mixed revision from the trunk being used
> >together.
>
> From your last message, I think SVN can implement your work model.
> However, I haven't seen a great deal of detail about your specific
> process.

Do the use cases above along with:

  http://svn.haxx.se/users/archive-2006-11/1276.shtml
  http://svn.haxx.se/users/archive-2006-11/1319.shtml
  http://svn.haxx.se/users/archive-2006-11/0923.shtml
  http://svn.haxx.se/users/archive-2006-11/1356.shtml
  
and possibly:

  http://svn.haxx.se/users/archive-2006-11/1256.shtml

and

  http://svn.haxx.se/users/archive-2006-11/1324.shtml

help?

> >We need to be able to track which trunk revisions of individual files
> >were used in creating a branch, and we need to be able to update the
> >branch maintaining the trunk->branch history as well as the branch
> >history (to see which versions of the trunk files have been placed in
> >production).
>
> >CVS tags do that very well as they:
>
> Actually, no they don't. You can't ask in CVS "which versions of this
> file have ever been in production?". You can in SVN.

See use cases above. It does require a secondary non-moving tag. Now
that I think of it, I may be able to do the same with non-versioned
properties to make the "find/audit the deployment history..." use case
less of a pain.
 
> > exist on the time axis of the trunk (not in some
> > unconnected spacial component)
>
> While not connected as much as would be convenient, they are not
> unconnected.

Yeah, there is the copy info from copy -> original.

> > can be moved to capture the current "head" revision of the branch
> > (and can be permanetly marked to allow rollback fo a head of a
> > branch)
>
> Supported by SVN. Even better, this is supported by an atomic change,
> which CVS doesn't allow. Ever delete a file and re-tag your working
> directory in CVS? You just created a problem, because the old version
> of the file still has the tag.

Only in the merge model which is asking for problems, I have seen too
many developers check in/tag working copy with crap in it. Took a good
while to figure out what happend. That must not happen under this
senario hence using merges isn't a realistic option.
 
> > can NOT tag items that are not checked into the trunk.
>
> You can of course tag items that have never been on the trunk in CVS.
> Here I think you mean that you can't tag revisions that haven't been
> checked in.

Yes, I was imprecise in my language. Replace trunk with repository and
you are absolutely correct.

> I am not very experienced with SVN hooks, having only
> implemented simple checks, but I believe you can probably prevent this
> by allowing only copies in the /tags directory scheme, and not
> changes.

AFAICT there is no way to tell what the source is. A copy looks like
an add in a workspace. A delete looks the same.

> > enforce tag renames via taginfo (so you can change PRODUCTION
> > but not PROD_200612011622)
>
> Supported also by SVN hooks.

Yup.
 
> >As a result I can:
> >
> > use annotate on the trunk to find the original point where a line
> > was entered
>
> Subject to the caveats of renames, as above. And, as above, this
> takes the same amount of work in SVN unless you're following a change
> that was merged from one branch to another several times.

Agreed under the copy model.
 
> > use log to discover what tags/labels are associated with the file
> > revision
>
> Yup, this isn't easy in SVN. It also doesn't seem to be a common
> operation. Normally, I am asking the other question: What was in
> this tag?

True, this is the inverse of your question,
 
> > using log to determine if the revision ever made it into production
> > (possibly triggering a massive security sweep if it did.)
>
> As mentioned above, this is absolutely not possible in CVS. You can
> determine whether a revision is CURRENTLY in production, but not
> historical information. Unless, of course, you mean by retaining the
> type of PROD_timestamp tags you mentioned in passing, in which case
> you are correct, as it is simply a restatement of the previous point.

Yup the PROD_timestamp saves the day.
 
> > automatedly update files from a known static location.
>
> I'm not sure exactly what you mean, but this sounds like basic source
> control, which is supported by SVN (otherwise no one would use it :).
>
> >Does this make my use case a little clearer?
>
> Not yet. How do you use branches in your process? My vague
> understanding is that your process is mostly single-branched.

In general it is. Trunk is development/test, copied to the production
or other distribution branches. Then the distribution mechanism(s)
always update from the "production branches" E.G. you may have
production branches for different classes of machines or that are on
different update schedules.

I can see using a classical branch/merge model onto the trunk for
reorganization of the repository, or other major changes that need
multiple steps tracked that would break the trunk.

-- 
				-- rouilj
John Rouillard
System Administrator
Renesys Corporation
603-643-9300 x 111
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@subversion.tigris.org
For additional commands, e-mail: users-help@subversion.tigris.org
Received on Tue Dec 5 18:41:39 2006

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