here's a few comments & questions to help me get some clarification on our branching strategy ---
if we do repeated merges between branch and head we'll potentially run into cvs-conflicts since any secondary merges will try to re-merge stuff from prior merges. so i think we either have to use an intermediate tagging protocol to keep track or merge points, or just manually make the changes in both and do the commits once for the head and once for the branch. either way's fine with me, so i just wanted to get folks' preferences or feedback before proceeding, and possibly put in my 2 cents too.
if we choose to manually add changes to *both* the head and branch (i.e., two edits per change), and commit each separately, that's alright too, except that we'd probably not be taking advantage of cvs's features to their full potential (merge capabilities), and possibly be increasing the possibility for manual errors a bit too.
in any case, its best to explicitly choose a strategy now, before committing or merging after the branch point, to avoid conflicts between opposing strategies. does jboss have a standard strategy for this?
if jboss doesn't have a standard way of doing it, i may put in a vote for doing M1 bugfixes on the M1 branch and merging them into the head (tagging at each merge point with a numerically increasing tag pattern so that proper incremental merges can be done for new stuff between two versions) [or visa-versa, head->m1, doesn't matter], and doing new development on head. btw, are the features in M1 'frozen' or do we also want to add new development to M1?
My understanding is new stuff goes into HEAD, and fixes for M1 go into both M1 branch and HEAD.
I agree it would be nice if it something was put in place to merge M1 branch changes into HEAD
Actually, new devel goes in HEAD, fixes in M1 branch. When the
branch is ok, one sets a tag on the branch and merges TAG-Brachning point into HEAD. New fixes on Branch can then be identified being relative to the TAG. This process can go on as one wishes.
for instance, i just modified the file BUILDING.txt in the HEAD of jboss-mail.
so i guess i would do the following (which i'll do on the command-line as i write): [note: i realized after doing this that in general, we'll usually want to merge from M1 to HEAD instead, since i guess no new features will go in M1 yet the HEAD should get the bugfixes... sorry... steps 7+ should handle this case]
1. do a cvs commit as usual to get the change into HEAD. tag with something like 'merged-to-M1-1' to indicate that everything from the branch point to HEAD has been (will be in steps 2-5) merged into the branch from HEAD for the first ('-1') time. we may use this tag in later merges from HEAD to branch to avoid conflicts (using two 'cvs -j' options).
2. in the branch (separate checkout), do a 'cvs update -j HEAD BUILDING.txt' (since i know i only modified BUILDING.txt, otherwise i'd omit that filename). this will merge the change in HEAD since the branch point into the branch.
3. in the branch, check for conflicts and if so correct them (shouldn't be any if developers don't conflict)
4. commit the change to the branch (the big boy/gal step)
5. tag the branch with a tag like 'merge-from-head-1' to help keep track of things.
6. we're done. further steps are how one might proceed later on, with an important difference: how to avoid re-merging changes and the resulting conflicts
7. now, for instance, lets say we instead do a bugfix on the branch and go through the analogous procedure of committing, tagging, merging to HEAD, etc. in general, this will involve the whole repository and not just a single file like 'BUILDING.txt'.
8. so after doing the same procedure as before, we'll have a tag on the branch called something like 'merged-to-head-1' from step 7.
9. now we want to commit the second bugfix on the branch and merge it into the HEAD too. we commit and tag the fix on the branch as 'merged-to-head-2'.
10. now we do a merge of all the changes between tags 'merged-to-head-1' and 'merged-to-head-2' to the HEAD, thus picking up only the second bugfix. thus, in the HEAD repository, we execute a 'cvs update -j merged-to-head-1 -j merged-to-head-2'
11. this avoids re-merging the first bugfix after the branch point and the inevitable conflicts it would cause.
so basically its pretty standard stuff and folks probably already know all this. i picked it up myself from the book 'open source development with cvs, by karl fogel' (any errors here are mine). what i mainly wanted to accomplish was to informally get some kind of consensus and awareness of the coordination between developers that helps to avoid conflicts when branches are being used. the apparent answer is a common naming scheme for tags at most control points, to communicate what's been merged into what, where, when and how. don't worry --- when we move onto M2 we can then delete all those verbose tags from the repository to clean things up.
somebody probably knows a better way to do this than i do, and so i'd greatly appreciate getting educated if someone could provide some more information or references here.
one pitfall (of many?) in this procedure may be due to a deficiency of cvs itself, which is that if another developer is doing the same thing while you're in the middle of steps 2-5, you'll cause each other problems. that's because cvs doesn't use transactions and furthermore doesn't provide atomicity. but chances of this happening are quite small.
btw, it goes without saying that if we adopt the verbose-numbered-tagging scheme i just described, then right before one starts the commit/merge procedure, one would have to do a 'cvs log' to see what the next tag-sequence-number would be. and since cvs lacks atomicity across multiple command-line invocations, one should complete the procedure as quickly as possible to avoid another developer stepping in and causing a problem in the middle. (again, somebody probably knows how to do this alot better than i do, so i'm looking forward to learning something). other option is 'human-powered' transactions with explicit personalized 'start' and 'end' tags for 'locking' (like start-mike-1, end-mike-1) ... which i feel is overkill for us.
Wow Mike. I'm sure one day we'll need to do all of that. However, for now. We have 3-5 guys working on pretty short lived releases and branches. Thus I think the simplest thing that works is probably best. For now lets just do this.
Branches happen along releases (M1RC1, RC2, M1FINAL all on the same branch).
Tags are for releases (M1RC1, M1RC2, M1FINAL)
Changes which affect both releases should be made in the release branch and ALSO applied to the other branch. No merging should happen unless the FINAL release has happened. (Too big of a pain to branch/unbranch/rebranch/etc).
Rationale: Its not that much trouble to apply the few bug fixes that we'll likely apply before M1FINAL happens (and I don't expect an M1RC2) also to head. Collisions are unlikely even on large projects, they're really unlikely for us. I'm the most likely collider as I'm probably hte most cross functional, but I kind of go from Code-boy to Doc-boy to Release-boy in cycles so even then I'm predictable. Thus this is simpler. We can invoke a more robust system if problems pop up or the project grows. I'd love us to have the problem of too many coders stepping on each others toes in CVS :-)
sorry for whipping up a scare, folks :-)
am a big proponent of KISS too ('Keep It Simple Stupid') which i can agree is what reasonably applies here.
we always have the option of refering back to this post should the full-fledged procedures ever be needed.
Just to get it clear once and for all.
To checkout M1 branch:
$ cvs checkout -r JBOSS_MAILSERVICES_M1 jboss-mail
To checkout head:
$ cvs checkout jboss-mail
JBOSS_MAIL_SERVICES_RC1 is basically just a tag on M1 branch, and not a separate branch.
Is that correct?
looks like you're mostly correct:
except i believe the last tag you refer to is actually 'JBOSS_MAILSERVICES_M1_RC1', and it seems to be on the cvs HEAD at the root of the branch. so in a sense it defines what M1RC1 is, since M1RC1 originated from the cvs HEAD. you can do a 'cvs log' on any file to verify this.
i presume future M1RC's (like M1RC2, M1RC3, etc) will be tags on the branch.
It is? I wonder what I did wrong! I thought I did it on the branch...