Now, in theory you only get conflicts if you've changed the same section of the file in both branches, but in practice I always get burned. It's standard practice to include a version id in your code. For instance:
static char *RCSSTRING __UNUSED__ ="$Id: tcpconn.c,v 1.22.2.2 2005/02/03 21:25:57 ekr Exp $";
When you do checkins and checkouts, CVS automatically modifies this
string to reflect the current version, date, etc. This lets you
instantly look at any code fragment and determine which
versions it corresponds to, which can be very helpful in debugging
customer problems.
Here's when
things start to go wrong. Say you've been working on file foo.c
in both branches. So, in H-O-T you've got version number 1.23. In the branch
you have version number 1.22.2.2. This means you have different
version IDs, and since the same line of code has changed, CVS
decides you've got a conflict. It marks it up in the source code like
this:
<<<<<<< tcpconn.c
static char *RCSSTRING __UNUSED__ ="$Id: tcpconn.c,v 1.23 2004/07/16 00:08:58 ekr Exp $";
=======
static char *RCSSTRING __UNUSED__ ="$Id: tcpconn.c,v 1.22.2.2 2005/02/03 21:25:5 7 ekr Exp $";
>>>>>>> 1.22.2.2
Now, here's the baffling part: CVS controls these lines. It wrote them in the first place, so you'd think it could figure out that they're not real conflicts and just fix them up. But nooooo.... You have to go in and remove the conflicts manually. Yeah, yeah, I know that I could fix this myself, but wouldn't it be nice if I didn't have to?
Subversion replaces keywords on checkout, not on checkin -- the repository stores the un-replaced keyword, and so it doesn't have these conflicts. I would highly recommend switching any CVS repos over to SVN. Another benefit of SVN is that it know about the common ancestry of 1.23 and 1.22.2.2, so it's doing a 3-way diff during a merge, and not a 2-way diff, which almost always massively reduces the number of conflicts you have to manually resolve.
As a bonus incentive, there are cvs2svn scripts out there which will automagically suck all your project history over to the new repo and everything. Plus you can do more useful access control stuff on branchs in the repo, have atomic commits, use HTTP/WebDAV as a network transport, use regular HTTP GETs to browse/fetch the latest version of any file, etc, etc. As I said, highly recommended for anyone still using CVS.
I'm still iffy on the idea of migrating to SVN, although I'm using both it and CVS regularly these days. There are a lot of nice things about it, to be sure.
Regarding the strings, CVS (well, RCS) also replaces the strings on checkout, not checkin. You can use -ko to ge tthe old string, or (more usefully for ekr's problem) use -kk to get empty strings. (The man page says "This option is useful to ignore differences due to keyword substitution when comparing different revisions of a file.")
Arguably CVS merge should do this automatically…
I'm an advocate of SVN also. Even if it doesn't fix this problem, at least you can justify a departure from CVS citing spite, and then get the features that actually *do* work better from SVN.
Remove unwanted spyware fast and easy Spyware Removal Tools - About Blank Remover.