[comp.unix.misc] CVS and divergent development

emcguire@ccad.uiowa.edu (Ed McGuire) (05/22/91)

Is there a capability within CVS to support parallel development
of more than one version of the same software derived from a common
ancestor?

Our development plan was initially to freeze code periodically,
tag it with a release name and deliver it, then begin development
of the next planned release.

We have found in practice that it will be necessary to do `bug fix'
releases derived from the originally released version concurrently
with the development of the next planned release.  This leads to
the problem of how to to maintain the `bug fix' release under CVS.

The method we're using right now is pretty crude, requiring careful
bookkeeping:  keeping track of which files were fixed and what their
RCS revision numbers are.

The developer of a `bug fix' release copies out the original release
by tag.  When ready, s/he commits each modified file to a branch
off the original file.  Thus the `bug fix' release consists partly
of original trunk nodes and partly of branch tips.

To tag the `bug fix' release, a new tag synonymous for the original
release is first created.  Then `rcs -N' is used to relink the tag
of each modified source with the branch tip.

Am I missing the obvious?
-- 
peace.  -- Ed
"Over here, Bones!  This man's dying!"
"Damn it, Jim!  I'm a doctor, not a . . .  What did you say?"

emcguire@ccad.uiowa.edu (Ed McGuire) (05/23/91)

A clarification to my question seems necessary, if the reply I just
received by mail is any evidence.  I'm sorry if I did not make
clear what I wanted.

I understand how CVS supports divergent development in the sense
that programmers can modify copies of the code concurrently, the
result being a set of divergent descendants from the original code.
That is exactly why we use it.

The difficulty is that a descendant must be brought up to date with
respect to the repository before it may be committed.  What is
wanted is the capability to manage divergent descendants in the
repository itself.  We wish to copy out an earlier version of the
code, modify it, and commit the changes to the repository:  not as
the new current source code, but as a variant, descending from the
earlier version.

This capability is analogous to RCS branches, but at the level of
CVS tags, not RCS revision numbers.

Consider code which has been released as version 1 and is now
undergoing further development for eventual release of version 2.
A problem is found in the released code.  The problem is corrected
in the current code, but that code cannot be released to customers
until development is complete.  What if it is necessary to provide
a `bug fix' release version 1.1 in the meantime?

       ------> (2)
      /
   (1)
      \
       ------> (1.1)

It is possible for a programmer to copy out version 1 by date or
by tag and fix the code, but it seems impossible to commit it to
the repository and tag it version 1.1 without recourse to `no-nos'
such as specifying explicit RCS revision numbers and using `rcs
-N' to move tags around.

I will be grateful if someone can either point out my ignorance of
an existing capability in CVS to manage divergent descendants, or
suggest approaches to extending CVS to provide this capability.
-- 
peace.  -- Ed
"Over here, Bones!  This man's dying!"
"Damn it, Jim!  I'm a doctor, not a . . .  What did you say?"
-- 
peace.  -- Ed
"Over here, Bones!  This man's dying!"
"Damn it, Jim!  I'm a doctor, not a . . .  What did you say?"

randy@m2xenix.psg.com (Randy Bush) (05/25/91)

And, to add one more level of complexity to the problem,

1.1.* is the released version
1.2.* is where we're hacking

A bug appears in the relased version.  We want to
  o fix it in 1.1
  o reissue 1.1, and
  o have the fix mergable forward to 1.2.
-- 
randy@psg.com  ..!uunet!m2xenix!randy

emcguire@ccad.uiowa.edu (Ed McGuire) (05/29/91)

In article <1991May25.011338.3040@m2xenix.psg.com> randy@m2xenix.psg.com (Randy Bush) writes:
>And, to add one more level of complexity to the problem,
>1.1.* is the released version
>1.2.* is where we're hacking
>A bug appears in the relased version.  We want to
>  o fix it in 1.1

We tagged the original released version as "1_1".  This permitted us to
copy out by tag.  We fixed the bug and committed the affected file(s)
with explicit RCS revision numbers to create branches.  Example:

     % cvs co -f -r1_1 src       [note Makefile revision is 1.9 for commit]
     % vi Makefile
     % cvs ci -r1.9.1 Makefile   [commits as 1.9.1.1]

>  o reissue 1.1, and

We tagged the fixed version as "1_1A" (version 1.1A).  This was
accomplished by applying the new tag to the same revisions identified
by "1_1", then fixing the tag in those files which we edited.  Thus
"1_1A" identified the version to be reissued.  Example:

     % cvs tag -f -r1_1 1_1A src                    [once]
     % rcs -N1_1A:1.9.1.1 $CVSROOT/src/Makefile,v   [once per changed file]

>  o have the fix mergable forward to 1.2.

We used "rcsmerge" to merge the differences between the "1_1" files
and the "1_1A" files with the current (1.2) version.  Example:

     % cvs update          [copy out current version]
     % rcsmerge -r1.9 -r1.9.1.1 $CVSROOT/src/Makefile,v Makefile
			   [merge changes into current version]
     % cvs ci Makefile     [commit version with changes]

In fine, we can get the job done but we have to go behind CVS' back
to accomplish it.
-- 
peace.  -- Ed
"Over here, Bones!  This man's dying!"
"Damn it, Jim!  I'm a doctor, not a . . .  What did you say?"

jms@unix386.Convergent.COM (John Sully) (06/04/91)

emcguire@ccad.uiowa.edu (Ed McGuire) writes:

>In article <1991May25.011338.3040@m2xenix.psg.com> randy@m2xenix.psg.com (Randy Bush) writes:
>>And, to add one more level of complexity to the problem,
>>1.1.* is the released version
>>1.2.* is where we're hacking
>>A bug appears in the relased version.  We want to
>>  o fix it in 1.1

>We tagged the original released version as "1_1".  This permitted us to
>copy out by tag.  We fixed the bug and committed the affected file(s)
>with explicit RCS revision numbers to create branches.  Example:

>     % cvs co -f -r1_1 src       [note Makefile revision is 1.9 for commit]
>     % vi Makefile
>     % cvs ci -r1.9.1 Makefile   [commits as 1.9.1.1]

>>  o reissue 1.1, and

>We tagged the fixed version as "1_1A" (version 1.1A).  This was
>accomplished by applying the new tag to the same revisions identified
>by "1_1", then fixing the tag in those files which we edited.  Thus
>"1_1A" identified the version to be reissued.  Example:

>     % cvs tag -f -r1_1 1_1A src                    [once]
>     % rcs -N1_1A:1.9.1.1 $CVSROOT/src/Makefile,v   [once per changed file]

Here you can also do:

      $ cvs tag -r1.9.1 1_1A $CVSROOT/src/Makefile,v

>>  o have the fix mergable forward to 1.2.

>We used "rcsmerge" to merge the differences between the "1_1" files
>and the "1_1A" files with the current (1.2) version.  Example:

You can also use the cvs "join" command to accomplish the same thing:

>     % cvs update          [copy out current version]
>     % rcsmerge -r1.9 -r1.9.1.1 $CVSROOT/src/Makefile,v Makefile
>			   [merge changes into current version]
      $ cvs join -r1.9.1.1 Makefile
>     % cvs ci Makefile     [commit version with changes]

>In fine, we can get the job done but we have to go behind CVS' back
>to accomplish it.

You don't really have to go behind it's back, but it is more difficult 
than it should be.  It would be nice if CVS had a way to manage branches
more easily.

Along these same lines, I have written several scripts which help with
tagging and managing what we refer to as "twigs". One walks a checked
out source tree and tags the proper revision of each file with a given
tag.  It also reports on any files which you may have forgotten to checkin,
The other will walk a checked out tree and merge "twigs" back into the
trunk in a manner similar to the above method.  This helps a little, but
the functionality of both of these scripts should be placed in the CVS
command itself.

Do other people out there using CVS have any ideas for enhancements or
pet peeves?  I've done quite a bit of work on it here and am interested
in hearing from other people who have been using it.

--
John M. Sully                      
Unisys Corporation                 
2700 N. First St.                  
San Jose, CA 95150                 
                                   
Phone : (408) 435-3129             
E-Mail: jms@unix386.convergent.com 

ivanp@mc.UUCP (Ivan Peters) (06/06/91)

In article <1991May22.200442.20734@ccad.uiowa.edu>, emcguire@ccad.uiowa.edu (Ed McGuire) writes:
|> I understand how CVS supports divergent development in the sense
|> that programmers can modify copies of the code concurrently, the
|> result being a set of divergent descendants from the original code.
|> That is exactly why we use it.
|> 
|> The difficulty is that a descendant must be brought up to date with
|> respect to the repository before it may be committed.  What is
|> wanted is the capability to manage divergent descendants in the
|> repository itself.  We wish to copy out an earlier version of the
|> code, modify it, and commit the changes to the repository:  not as
|> the new current source code, but as a variant, descending from the
|> earlier version.
|> 
|> This capability is analogous to RCS branches, but at the level of
|> CVS tags, not RCS revision numbers.
|> 
...
|>
|>I will be grateful if someone can either point out my ignorance of
|>an existing capability in CVS to manage divergent descendants, or
|>suggest approaches to extending CVS to provide this capability.
...

This sounds like the same question I posted on comp.software-eng.
(I also did a follow up clarification which I did not include here)

I have been testing CVS to try to use it for Config managment.  Currently
our place uses mainly SCCS with a scattering of RCS.  (I do have the
csh script to convert from SCCS to RCS.)  I found the same
limitation with CVS and thought I was missing something.  The
comp.software-eng group (Many thanks to them!!!) confirmed the limitations
that I encountered.  I did not know of this same thread here until
Mr Phillip Merrick informed me.  (If you find this useful, at all, you
can thank him for bringing this thread to my attention.)
I shall include (what I consider) the main messages from comp.software-eng
which show my current findings, and follow with a update/conclusion...
=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+= 
Article: 4471 of comp.software-eng
Newsgroups: comp.software-eng
Path: apertus!news
From: ivanp@mc.UUCP (Ivan Peters)
Subject: CVS-RCS
Message-ID: <1991May21.135016.3671@apertus.uucp>
Sender: news@apertus.uucp (0000-news(0000))
Reply-To: apertus!ivanp@tenfwd.uci.com
Organization: Apertus Technologies
Date: Tue, 21 May 91 13:50:16 GMT

I am looking over CVS, a system that is a add on to RCS (a configuration
management system) and I have a question I hope someone would please answer:

How does CVS support (or does CVS support) dual derivations?

example:
If someone is deveolping on release 2, of something, and someone else
is developing on release 1.  How does one make release 1.1, 1.2, etc,
(a branch) while allowing work to continue on 2.1 2.2?   These releases
contain multiple files and sub-dirs.

(assume test is the top directory in the repository)

One can tag a release.       (cvs tag -rTEST2_0 test)
One can checkout a release.  (cvs co -rTEST1_0 test)
One can update from a release.    (cvs update -rTEST1_0 test)

One can not check in a release, other than the most current. (cvs ci *)

Is there a easy process that I am missing?
How do others do it?
I would like to avoid making a new dir under the repository for each
release to be worked on if possible...

Any help would be REALLY APRECIATED!!!!!

Thanks in advance. :-)



Article: 4597 of comp.software-eng
Newsgroups: comp.software-eng
Path: apertus!news
From: ivanp@mc.UUCP (Ivan Peters)
Subject: Re: CVS-RCS
Message-ID: <1991May29.133402.6114@apertus.uucp>
Sender: news@apertus.uucp (0000-news(0000))
Reply-To: apertus!ivanp@tenfwd.uci.com
Organization: Apertus Technologies
References: <1991May21.135016.3671@apertus.uucp> <1076@isgtec.UUCP>
Date: Wed, 29 May 91 13:34:02 GMT

In article <1076@isgtec.UUCP>, robert@isgtec.UUCP (Robert Osborne) writes:
|>
|> Hmmm, seems to be correct.  I think the only way to do this is either:
|>  1)  use rcs directly
****** :-) ****
|>  2)  use the checkin script
|>  3)  change 'cvs ci' so it takes the tag just like all the
|>      other commands  (ie. change the current argument -r to -F
|>      and -rTAG would check into the branch defined at that
|>      symbol)
|>
|> I'll look into 3),  it might be fairly simple to do.  If Brian Berliner
|> is reading this maybe he has some input on this question, Brian?
|>
|> Rob.
|> Robert A. Osborne   ...uunet!utai!lsuc!isgtec!robert or robert@isgtec.uucp

(1 above), looks like the current winner (for our implementation anyways).

Thanks for the input, the four alternatives I was looking at were the
three listed above, and seperate dirs per release.  Would love to hear of
developments along 3.  I have looked for the same thing in the code as TIME
permits, and have not found it as yet. :-(   standard key word, time.

My current experimentation has lead to a config managment scheme as
follows.  Hopefully this is useful to someone else...

*************************************************************
assume taging convention of Ra_b_c relates to release a.b.c (R1_3_1 = 1.3.1)
(This means over all release of multiple files...)
===========================================================================
        for creating a development release 3.0 from 2.*
===========================================================================

cvs co test                               ; creates work environment for
                                          ; compiling

vi xx.h                                   ; change and test file(s)
vi xx2.h                                  ; change a 2nd file

cvs update                                ; a cvs ci will ask for a
                                          ; update if anything has been
                                          ; changed
cvs ci *                                  ; will checkin all updated files in
                                          ; current dir only, to top level.
                                          ; so may have to do this step mult
                                          ; times to get mult dirs
                   ----- single person from here on --------
{option, cvs ci -r3.0 *}                  ; bumps revision numbers to 3.0 on
                                          ; all files, for major release
                                          ; PLEASE NOTE: no consistency check
                                          ; so must be done in serial.
cvs tag R3_0 test                         ; freeze code, a release,R3_0 made.

===========================================================================
        for creating a support release 1.5.1 from 1.5  (.0)
===========================================================================
cvs co -rR1_5 test                        ; creates work environment for
                                          ; compiling

co -l -rR1_5 $CVSROOT/test/xx.h           ; rcs co with lock
mv $CVSROOT/test/xx.h .                   ; darn rcs dir limitation

vi xx.h                                   ; change and test the file

cp xx.h $CVSROOT/test                     ; darn rcs dir limitation
ci -nTEMPSUPPORT $CVSROOT/test/xx.h       ; rcs ci with tag TEMPSUPPORT

                     ----- single person from here on ------
cvs tag -f -r R1_5 R1_5_1 test            ; tag all R1_5 with R1_5_1
cvs tag -f -d -r TEMPSUPPORT R1_5_1 test  ; del 1_5_1 tag from all changed files
cvs tag -f -r TEMPSUPPORT R1_5_1 test     ; switch all temp tags to 1_5_1
cvs tag -d TEMPSUPPORT test               ; remove temp tag from ALL files

===========================================================================
This is just a basic procedure for implementation of CVS and RCS.
There are some other frills unused as yet, (modules) .

*************************************************
Any optimizations would be apreciated.  I have already tried to reduce the
fun and games with taging at the end, but tag will overwrite older tags with
same name.

The 'darn rcs dir limitation' can be overcome by a symbolic dir link, haven't
considered the implications as yet.

This (the support track) will curently reduce to three scripts, one for
checkout, one for checkin, and one for taging all files related to one target.
I have not generated the scripts yet, am still looking for alternatives/
researching.

If you find this helpful, I wouldn't mind knowing about it...  alternative
processes would also be appreciated.

=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+= 
My current opinion of the options, with CVS were:

1) Use a subdir under CVSROOT per release/branch...
	This was the first alternative that I found, but would involve much 
	duplicate code, and a possible divergence/merging  problem.
2) 2nd pursuit: Useage of cvs ci -rx.x.x.x....
	Was not consistent or controlable, since CVS does no consistency 
	checks.  Totally unusable except for mentioned above.
3) 3rd: Look at the CVS code, and path the ci process....
	This would be the best, if I was given the TIME to find the right
	place!  I gave the code a 30min scan, but was unable to find it
	and so I had to continue.  What my current change would be (which
	is just my opinion, and since hasn't been implemented, may not be
	the best) to have CVS check what version of all the local software
	currently here "cvs update  -rREL2_0 means 2.x revs on all software)
	and when the cvs ci * is performed, it would maintain the highest
	number of the revsion, and just add to the current branch 2.x.x.x.  This
	would be the same identical mechanisim, as currently used where
	cvs ci * goes to a.x.x.x, but would use the first digit, that is 
	already stored in ones CVS-ADM local dir.  (just my initial thought)
4) Use rcs directly....
	Was final winner, with process stated above.
5) use cvs checkin, and join, and treat branches as vendor releases....
	The way I envisioned this evolved into 1) again, with its problems,
	and the additional problem of useing some lessor used parts of CVS,
	Join and checkin, which I did not think was the intention of CVS.
	So I did not spend much time on this one...
+=+=+=+=
	I hope this is useful, good luck, and any improvements on anything 
	stated would be aprecieated, or further info also as to how you
	do it. :-) !!!