Forum OpenACS Q&A: CVS

1: CVS
Posted by Richard Hamilton on
I am spending hours and hours becoming terribly frustrated trying to get to know cvs. I would be very grateful if someone could point out where I am going wrong.

I have an instance of openacs-4.6 which has customised alterations in .tcl and .adp files all over the place. I want to upgrade it to 4.6.3 so that I can upgrade my database to Postgres 7.4.2.

To achieve this I did a cvs import of my openacs-4.6 like this:

cvs import -m "Service on OpenACS 4.6" service OpenACS openacs-4-6

I then unpacked a tar of openacs-4.6.3 and did:

cvs import -m "update Service to OpenACS 4.6.3" service OpenACS openacs-4-6-3

I can see that there are two revisions of lots of files but if I do this:

cvs checkout -j openacs-4-6-3 service > logfile 2>&1

I just get the updated files without any of my customisations.

I want to be able to reconcile my customisations with something like:

cvs checkout -d testservice -jopenacs-4-6 -jopenacs-4-6-3 > cvs.txt 2>&1

but in the docs the use og the -j flag is with -jOpenACS:yesterday which is no good because I cannot make that assumption, and it also seems to be referring to the vendor tag OpenACS rather than the branch openacs-4-6 or openacs-4-6-3.

So basically I am REALLY confused about the use of revisions, tags, branches in the checkout command.

How do I get cvs to give me a list of filenames with the conflicting changes? I don't want it deleting files, I want it to merge my changes from openacs-4-6 into the new openacs-4-6-3.

{Blood pressure 160/108!!}


2: Re: CVS (response to 1)
Posted by Nis Jørgensen on
Clarification: Is the "my openacs-4.6" you talk about here:

  > To achieve this I did a cvs import of my openacs-4.6 like this:

  > cvs import -m "Service on OpenACS 4.6" service OpenACS openacs-4-6

your "modified" version or a clean 4-6 from tarball/CVS?

If it is indeed a clean version, then I believe your approach should work, using the "-j openacs-4-6 -j openacs-4-6-3" variation (the spaces was lost in your posting, but I believe they are needed)

If not, then you miss a "common ancestor" for the two versions you have. The merge involves THREE versions of the code. You want to merge the changes from 4.6 -> 4.6.3 into your version, so all these three versions need to be in CVS.

3: Re: CVS (response to 1)
Posted by Richard Hamilton on
Fantastic, thank you. When I said 'my openacs-4.6', I meant my modified version - I have not added the original 4.6 tarball to cvs.

I will try again then like this:

1)  Untar a virgin openacs-4.6 tarball and add to cvs with 'cvs import' as 'service0' with release tag openacs-4-6 and checkout.

2)  Copy my modified openacs-4.6 over the top of the virgin 4.6 in the file system.

3)  Commit the changes.

4)  Untar virgin openacs-4.6.3 tarball to a new directory and add to cvs with 'cvs import' with release tag openacs-4-6-3 to 'service0'.

5)  Now do the : 'cvs checkout -d service0 -j openacs-4-6 -j openacs-4-6-3 > cvs.txt 2>&1

I will post my result.

(The docs in the OpenACS installation section have no space between the '-j' and the 'OpenACS'. I concluded that you put a space in for a branch tag but no space for a revision - but what confused me was that the instructions said '-jOpenACS' which is the vendor tag. I am not clear about the interchangeability of the various tags in the checkout command.)

Thank you for your help - what a good job the various releases are still available!


4: Re: CVS (response to 1)
Posted by Richard Hamilton on
No - still no luck.

All I get is a new version 4.6.3 with all my content repository files but all of my modified .tcl files are overwritten with the version 4.6.3 updates with none of my mods merged.

What on earth am I doing wrong?


5: Re: CVS (response to 4)
Posted by Nis Jørgensen on
Could you post a cvs log of one of the files that gets clobbered?


Don't forget that you don't _have_ to do everything in CVS. You could just do an offline diff/patch. But I understand why you want this to work ...

6: Re: CVS (response to 1)
Posted by Richard Hamilton on
Still no joy.

Following the reading of yet more documentation I see that this should work:

1) 'import' openacs-4-6 to a blank repository and tag it openacs-4-6
2) change some files and commit the changes
3) 'import' openacs-4-6-3
4) do 'cvs checkout -j etc...'

I think that my problem is that I am trying to:

1) 'import' openacs-4-6 to a blank repository and tag it openacs-4-6
2) 'import' openacs-modified and tag it openacs-mod
3) 'import' openacs-4-6-3 and tag it openacs-4-6-3
4) merge it with 'cvs checkout -j ....etc

So I never actually commit any changes - but surely there must be a way to reconcile two branches after having imported them!?

I am going to try creating a branch based at my openacs-4-6 import point :

cvs rtag -r openacs-4-6 -b openacs-modified openacs

and then update the main trunk, and then merge the branch back in - but I don't yet know how to specify where I want the import to go (trunk or branch).

I will post a log output next time I have the three revisions in the cvs.

Many thanks for your help - I really appreciate it.


7: Re: CVS (response to 1)
Posted by Richard Hamilton on
Here is the result of a 'cvs status -v' on a file I have modified and want merged.

To get to this point I:

1) Imported a blank un-altered openacs-4-6
2) Imported my modified openacs-4-6 with a different vendor tag (Milex)and release tag (openacs-4-6-mod)
3) Created a branch with 'cvs rtag -r openacs-4-6-mod -b milex openacs'
4) Imported a blank un-altered openacs-4-6-3

I now seem to have the openacs-4-6-3 stuff in the wrong branch.

I would be most grateful for some guidance on what do I do now to merge my changes so that I get both the openacs-4-6-3 updates and my own mods?

File: navigation-procs.tcl	Status: Up-to-date

   Working revision:	Tue Apr 27 10:42:54 2004
   Repository revision:	/web/cvsroot/openacs/packages/acs-tcl/tcl/navigation-procs.tcl,v
   Sticky Tag:		openacs-4-6 (revision:
   Sticky Date:		(none)
   Sticky Options:	(none)

   Existing Tags:
	openacs-4-6-3            	(revision:
	milex                    	(branch:
	openacs-4-6-mod          	(revision:
	Milex                    	(branch: 1.1.1)
	openacs-4-6              	(revision:
	OpenACS                  	(branch: 1.1.1)
8: Re: CVS (response to 1)
Posted by Richard Hamilton on
OK, well I tried about 100 different ways until I did this:

'cvs checkout -r milex -j openacs-4-6 -j openacs-4-6-3 openacs'

and then nothing SEEMED to happen.

But then I did a:

'cvs checkout milex'

...and wonder of wonders - C's in my output file at long last.

Now the long trudge through the conflicts!

I have an idea why this worked - but depressingly no idea whatsoever why all my other attempts failed.

Thank you very much for your help.


9: Re: CVS (response to 7)
Posted by Nis Jørgensen on
At least now it is clear to me why your attempts don't work. You imported all three versions of the code on the SAME vendor branch.  (I believe the vendor tag being different doesn't matter for the branch creation - but would have to look into cvs documentation for that)

This is indeed different than what you described in an earlier post:

  1)  Untar a virgin openacs-4.6 tarball and add to cvs with 'cvs import' as 'service0' with release tag openacs-4-6 and checkout.
  2)  Copy my modified openacs-4.6 over the top of the virgin 4.6 in the file system.
  3)  Commit the changes.

If you had done this, your commands should give the result needed.

With your current setup,

  cvs co -r milex -j openacs-4-6 -j openacs-4-6-3


  take revision (milex)
  apply the changes from 1.1.1 -> 1.1.2
  apply the changes from 1.1.2 -> 1.1.3

The first set of changes have been applied already, so CVS just ignores them (apparently).

At this point, your working copy is sticky-tagged as being milex, but really is 4.6.3.

I assume you misprinted the last command - and it really is

  cvs co -j milex

This will merge your current working copy (which is 4-6-3) with the changes between the TRUNK (4-6) and milex. Voila.

Not the easiest way to the goal, but one of them. Don't forget to commit your work 😊

10: Re: CVS (response to 1)
Posted by Richard Hamilton on
Finally - the fog has lifted. Thank you Nis for your helpful guidance, the penny has finally dropped.

So for the benefit of anyone else just starting out to learn to use CVS (and so that I can refer back to it later!!) here are the precise misconceptions that caused me to have problems with this.


You have built a web service on a previous version of openacs (say openacs-4-6). In doing so you have modified various .adp pages, hacked a plethora of .tcl files and you have a load of stuff in the content repository. You have been careful enough to comment ALL of your changes (you think(!)) - but then again - you can't be absolutely sure.

You now need to upgrade to openacs-4-6-3 because otherwise you will stuck running an outdated version of PostgreSQL (with a buggy pg_dump, or an obsolete date format for instance), and therefore unable to share in the delights of future releases of OpenACS.

You didn't bother to learn to use CVS before you modified the code.


For anyone new to CVS, in addition to reading the basics about the main development 'trunk' of revisions in a repository and the idea of 'branches' of revisions, you need to know the following if you are to avoid days of frustration not understanding why the wretched thing won't do what you've told it to do:

1) CVS will only 'merge' changes in source code files that have been developed in parallel if they exist on different branches.
2) If you have three tarballs, openacs-4-6, openacs-4-6-yourversion and openacs-4-6-3 you will need to use 'cvs import' to import the source files.
3) You will need to merge your changes into the main trunk which means that you must 'cvs import' into a 'yourversion' branch. Contrary to my misunderstanding you do not have to create that branch with an 'rtag' command. The 'cvs import' command will set up the branch for you if you use the '-b branch_number' option. So don't use 'rtag' for this otherwise you will end up with extra tags and extra confusion.
4) When you specify the branch in the 'cvs import' command you must do so as a revision number. This is not done for you. The first 'cvs import' will be revision 1.1.1, you must therefore specify revision 1.1.2 for your branch. What I did wrong was to create a branch using 'cvs rtag' and wonder how to import source files to it because it had a 5 digit revision number and 'cvs import' only supports a three digit revision number. The reason for this is that new 'outside' sources are always stored in first level branches (see page 113 of Any revisions are then stored as leaves on these branches with 4 and 5 digit revision numbers.
5) You have to be telepathic to know that the only way to determine a valid branch number for your imported source is to import openacs-4-6 into the your repository (the trunk by default and revision 1.1.1 in an new, empty repository) and then check it out and run a 'cvs status -v file' on any file in the openacs. This way you can look up the most recent three digit branch revision number and add one to it for your import.


1) untar openacs-4-6, openacs-4-6-yourversion and openacs-4-6-3 into their respective directories.

2) Import the original common ancestor (required for merging)
'cd openacs-4-6'
'cvs import -ko -m "openacs-4-6" openacs OpenACS openacs-4-6'
'cvs checkout openacs'
'cd openacs'
'cvs commit' - (not certain if required but doesn't hurt.)
'cvs status -v somefile' - (observe the last used branch revision number)
'cd ..'

3) Import openacs-4-6-yourversion into its own development branch
'cd openacs-4-6-yourversion'
'cvs import -ko -b 1.1.2 -m "openacs-4-6-yourversion" openacs YOUASVENDOR openacs-4-6-yourversion'
'cvs checkout -r openacs-4-6-yourversion openacs'
'cvs commit'
'cd ..'

4) Import openacs-4-6-3 into the same 'trunk' of revisions as openacs-4-6 was imported into
'cd openacs-4-6-3'
'cvs import -ko -m "openacs-4-6-3" openacs OpenACS openacs-4-6-3'
'cvs checkout -r openacs-4-6-3 openacs' - (check you get an openacs-4-6-3 checked out. Do a 'cvs status v somefile' in the checked out directory if you like)
'cd ..'

5) Merge the wretched thing
'cvs checkout -j YOUASVENDOR openacs' > somefile 2>&1

Hopefully - Hey Presto!

Some tidying up:

-ko means don't substitute keywords. If you leave this out you will get conflicts in every merged file because of the CVS entries in the OpenACS remarks block at the top of every file.

-j means 'join'. I found some apparently helpful docs on the internet that turned out to be misleading over this. In the situation we have here only one join is needed. The command in step 5 says:

"Checkout openacs from the repository having joined it with the YOUASVENDOR branch."

CVS replies:

"OK, I will compare the most recent committed revision of YOUASVENDOR with the most recent ancestor that it shares with OpenACS (the main trunk) and I will incorporate any differences between them into the main trunk.

I hope this helps someone.

And many thanks Nis for your support.


11: Re: CVS (response to 1)
Posted by Richard Hamilton on
P.S. After clearing this up I heard this playing which seemed curiously appropriate! :)