You need to resolve an Issue : add a new feature, fix a bug, refactor a part of the code, ... To sum up, you need to change something in the project.
If not already done, create an issue into your issue tracker
You need to choose the fix branchs :
Nguyen thanh Huu
Make a fresh checkout of the fix branch. It means in an empty directory. The following command creates a directory with a given name :
cvs checkout -r <fix branch> -d issue-<id> <cvs module>
Check you checkout the right branch (don’t smill, it happens). Performs a cvs status on one of the checkouted files :
cvs status build.xml
Don’t tag right now the module.
Fix as needed your project. But never, never, add or remove a file from cvs at this step. However, you can update your workspace (which means retrieve modifications perform by the other developers during your work).
Limit your fix to the current issue
The more your fixes are specific to the related issues, the more your work (and the team work) is simplied
Test your fix. Run the needed test suites, launch your application, etc ...
Lock the fix branch. Inform the other developers that you’are the only commiter on the branch. Communication is always better than tools. But you can use cvslock. Promise to other developpers that every wild commits during this lock period will be punished
Performs an update of your workspace to retrieve the last modifications :
cvs -q update -dP
Resolve carefully each conflit and test again your fix.
Put a before tag associated to your issue:
cvs tag issue-<id>-before
It’s a snapshot of the module before your fix.
Check (via ViewCVS for instance) that your tag appears in the right branch (it should .. but you may be in the wrong branch from the beginning). You only have to check a tagged file.
Add and remove the needed files.
Commit all this modifications. Prefix your messages with something like “[Issue <id>]”, it’s simple and usefull. It can be read by dedicated tools (to update the issue tracker for instance)
Check (via ViewCVS for instance) that your modifications are now present in the right branch. If not .. draw the alarm now !
Put an after tag associated to your issue:
cvs tag issue-<id>-after
It’s a snapshot of the module after your fix.
Check the difference between the two tags by making:
cvs -q rdiff -s -r issue-<id>-before -r issue-<id>-after <cvs module>
Unlock the fix branch. Inform other developers that they can use the branch now.
Update the issue tracker. Specify the fix branch and the issue tags.
bugs: issue-<id>-before, issue-<id>-after branch: <fix branch>
If necessary, it’s time to report the fix in the other branchs (with the help of the tags).
A branch is a powerfull tool ... which can become a deep source of problems. Don’t start to use branchs in a real situation on a real problem, you might have a real problem. Prefer performing some tests in a fake module. For instance, create a sandbox module in your cvs repository to allow users to play with cvs.
Create a branch start tag. It snapshots the module state at the branch beginning. You can use the current state of the module or a given status (like the last successful build) :
cvs rtag issue-<id>-0 <cvs module> // current status cvs rtag -r build-<nnn> issue-<id>-0 <cvs module> // use the last succesful build
Create the branch from this initial tag:
cvs rtag -r issue-<id>-0 -b issue-<id> <cvs module>
Specify into the issue tracker that a dedicated branch has been created
Checkout the branch in a dedicated directory:
cvs checkout -r issue-<id> -d issue-<id> <cvs module>
Check you checkout the right branch (don’t smill, it happens). Performs a cvs status on one of the checkouted files :
cvs status build.xml
Fix as needed your project. But never, never, add or remove a file from cvs at this step. However, you can update your workspace (which means retrieve modifications perform by the other developers during your work).
Limit your fix to the current issue
The more your fixes are specific to the related issues, the more your work (and the team work) is simplied
Add, remove, commit (update, if you working with other people) freely.
Test your fix. Run the needed test suites, launch your application, etc ...
When you think the fix is ready to be delivered into the parent branch, it’s time to tag.
Check that all modifications are committed into the issue branch.
Tag the actual status of the issue branch. It snapshoots the branch before the merge operation. It can be useful if you want to perform other modifications after the merge (for a second delivery of the fix for instance). Use a tag issue-<id>-<n> where <n> is the delivery number.
[issue-branch]$ cvs tag issue-<id>-1
Lock the parent branch (where the issue fix will be merged)
Checkout the parent branch
cvs checkout -r <parentbranch> -d <parentbranch> <module>
Check the actual state of the parent branch. For instance, make a build, run the testsuite, check the last continuous build result, etc .. If you’re fixing a bug in this issue, try to reproduce the bug.
Tag the actual state of the parent branch :
[parentbranch]$ cvs tag issue-<id>-before
Merge the fix provided by the issue branch into the parent branch. For this, use the difference between the initial branch tag and the delivery branch tag (or the two last delivery tags when it isnt the first delivery from the issue branch.
[parentbranch]$ cvs -q update -j issue-<id>-0 -j issue-<id>-1 -dP // to merge the first delivery (common case) [parentbranch]$ cvs -q update -j issue-<id>-<n-1> -j issue-<id>-<n> -dP // to merge the delivery <n>
Check the result.
[parentbranch]$ cvs -nq update
If modifications seem really strange, stop all and take time to check where is the problem
Resolve conflits
Build the application, run the testsuite. If you’re fixing a bug in this issue, check you can’t reproduce the bug. Merges are not completely safe operation, you can introduce regressions, use the logic which has been changed during your development, etc ..
Commit all your modifications. Prefix the message with something like “[Issue <id>] “.
Invent an informative message, avoid the ugly “merged branch”, “fixed bug” messages. Prefer using a small message which describe the issue : “added the missing log4j configuration”, “modified UserSessionBean to prevent an error when the authentification context is invalid”, ...
Tag the new state of the parent branch.
[parentbranch]$ cvs tag issue-<id>-after
Unlock the parent branch
Update the issue tracker. Specify the fix branch and the issue tags.
bugs: issue-<id>-before, issue-<id>-after branch: <fix branch>
If necessary, it’s time to report the fix in the other branchs (with the help of the tags).
Checkout the target branch (where the fix will be applied)
cvs checkout -r <targetbranch> -d <targetbranch> <module>
Check the actual state of the target branch. For instance, make a build, run the testsuite, check the last continuous build result, etc .. If you’re fixing a bug in this issue, try to reproduce the bug.
Lock the target branch
Tag the actual state of the parent branch :
[parentbranch]$ cvs tag <target branch>-issue-<id>-before
Merge the fix provided to the parent branch into the target branch. It’s often more usefull than use directly the modifications made into the issue branch, because the target branch is often closer of the parent branch.
[parentbranch]$ cvs -q update -j issue-<id>-before -j issue-<id>-after -dP
Like every merge, check the result, resolve conflits, build and test. If you’re fixing a bug in this issue, check you can’t reproduce the bug. Merges are not completely safe operation, you can introduce regressions, use the logic which has been changed during your development, etc ..
Commit all your modifications. Prefix the message with something like “[Issue <id>] “. Invent an informative message, avoid the ugly “merged branch”, “fixed bug” messages. Prefer using a small message which describe the issue : “added the missing log4j configuration”, “modified UserSessionBean to prevent an error when the authentification context is invalid”, ...
Tag the new state of the target branch.
[parentbranch]$ cvs tag <target branch>-issue-<id>-after
Unlock the target branch
Update the issue tracker. Specify the fix branch and the issue tags.
bugs: <target branch>-issue-<id>-before, <target branch>-issue-<id>-after branch: <target branch>
Start with a manual procedure. When everybody understand this new development process, provide helper scripts (with Ant for instance). Never mask the development process behind scripts. Scripts must only help the process .. if not you’ll understand soon what’s can be a wrong usage of a script which isn’t understand by the user.
cvs tag can be a slow operation, see Optimize a CVS server
Subversion, Arch Revision Control System, Perforce are more friendly to use branchs into your development process. The development process is the same but the operation mode of these other tools make easier the user live.
See Revision control.