tags:

views:

953

answers:

6

Hi all!

I've been reading all the questions here on the subject of version control, but I don't think i found a scenario that looks like my own.

The scenario is:

we've got a medium/large sized web application that has (at least it should have) a core that is deployed to all clients. When we make demos of the application to the clients almost all of them request changes to the layout, or the data in the listings, or fields in the data entry forms, etc... Almost all of this changes require changes in the remaining "layers" of the application.

In our present situation we are using CVS (with tortoiseCVS) and we dont use branches, we use tags to differentiate the code changes to the application (yes I know it's pretty bad). This brings a lot of problems when we want to make a release to a specific client, and check-in changes, etc.... To prepare a release always takes around 1-2 days of work and sometimes it still breaks.

Sometimes, a request from a client also gets included into the core to be distributed to all clients.

So my question is: Are branches the best way to isolate the changes to the customized client versions of the application? Should we branch whenever a new client asks for customization? Or should we treat it as a complete different project, with a different repository?

All the different versions will have to be maintained, and as I've heard that branches are "temporary" I'm having doubts if branching is the best solution.

Thank you for the response.

Antonio Dias

+2  A: 

I don't know why you think that branches are temporary - they will exist as long as you want them to.

Your application sounds as if it could benefit from restructuring to implement more modular functionality, but in the meantime you can develop the main functionality as the trunk, with each customer version becoming it's own branch.

Modifications to the core code can then be merged into each branch as required. Customer-specific changes can be made in isolation on that branch, or merged back into the trunk at a later date.

Separate repositories for each customer sounds like completely the wrong thing to do, as it would result in duplication of common code between repositories.

IanH
I agree with this, and would add that you should probably consider adopting a more modern revision control system that does a better job of handling branching and merging -- it will make your life a lot easier in the long run.
ebneter
A: 

Branches are made to isolate a "development effort" (here some customization) that cannot be done in the same current branches.
Since tag are meant to reference an "immutable" content, you should not do any evolutions in it. A simple:

 cvs tag -r MY_TAG -b MY_BRANCH

would be enough to initialize a branch from a branch tag.

Those branches should be done for every UAT (user Acceptance Test) cycle, starting from your current development. You can then:

  • either try to merge the content of a previous branch done for a previous demo for a customer into this new branch
  • or directly re-implement the customizations in the new branch.
  • leave those branches as they are when the UAT cycle is done. They will not been modified but can serve as reference for the next branches for the next cycle.

To try and maintain a branch with customization would be harder than re-creating said evolutions in a new branch: that would require to merge the current development in that long-lived branch, and it is very possible your development introduce much more complex changes to the code than the evolutions you made for the client's demo.

VonC
+4  A: 

First of all, you may well be better off biting the bullet and refactoring your code to reduce the impact of all of this customization. There are good patterns that allow for this type of scenario (configuration-driven, plugins, software factory come to mind).

Having said that, if the application is as you describe (each client requires wide-reaching changes to the core), you may want to explore whether using compiler directives to isolate individual client changes works better for you than branching. The trouble with branching (as I'm sure you discovered) is that a fix placed in one branch often needs to be propagated to all other branches (since you never have the intention of merging the branches in the future). Additionally, you might need to fix the production version running at one client, while still developing on the next version for that client... a branch of a branch.

Things will only get worse if you continue this branch-per-client strategy as you add new clients.

Eric J.
yeah, but this is an "old" app (html/asp/vb6) and now it's impossible to refactor the "thing"..the change might be just a set of customized pages (like different images, or text labels or something "trivial"). How do i keep the standard version and this new version in the version control system?
Antonio Dias
I was responsible for a very large app that was VB6 based, and was highly configurable. There's nothing about that technology that makes it impossible to refactor, though I do understand that you probably have a very large code base to deal with. You'll need to honestly evaluate whether the (high) cost of refactoring (focusing on areas where you have the most customization) is greater than the high cost of not refactoring. Only you know your app. Just be honest about the true cost of each alternative.
Eric J.
yeah, i know, but the cost to refactor is really high, not just in terms of the work needed but also because there's only two people maintaning the app, as there's new request coming all the time and a lot of bugs to fix. The app already allows a certain dgree of customization (mainly in the design) but my problem is if someone asks for a new "module" (a group of pages and some code) where do i keep these new pages in the VCS? Along with all the other standard pages? Do i create a new repository (project) just for these changes and to integrate i pull the core modules and "add" the new one?
Antonio Dias
+3  A: 

Hello Antonio, As far as I know, what you have been doing is not what version control is supposed to do. It's only used to keep track of your source code, not your distributed product. To your question about branches, I think this little explanation may help: - trunk is the main development of the project, this is where all team members cooperate - branch is the place for temporary development (yes you heard it right). This is where you can do experiments or mess around with the code without affecting other team members - tag is nothing but "named snapshot". In version control project snapshots are everywhere, tag is the way that you can give them a more readable name If you try to get more and more branches with out dispose of them, your project would grow and grow forever. I still wonder why you have to keep track of all those anyway. May I repeat myself once more, version control is for cooperating on the source code only, not for distributing to multiple customers. Hope that help

phunehehe
yes, i know version control is not for distribution. the application is web-based, and customization might be changes to web pages, or the bussiness logic, or new tables in the db..how can i manage all this changes, int the version control system, making sure that a change made for one client does not propagate to another client (unless it's meant to be.) ?
Antonio Dias
Well, in that case I think each of them would be a separated project itself (however tiny it can be), and should have its own set of trunk, branch and tag.You can create directories for each of those projects.
phunehehe
A: 

First of all, embrace branches and learn how to use your version control system properly.

I worked on a project where they tried to manage versions the way you described, through tags. It was someone's job to manually add/merge changes against a tag and then apply a new tag. It makes it very hard for everyone to stay in synch and almost always leads to broken builds because of simple mistakes(forgotten files, stomping on changes, etc). You are basically manually doing what branches do for you.

As for how to manage the divergent client customizations. Aside from managing a branching strategy for each client release, you should take a look at the architecture and think about how you want to manage the customizations/differences.

Is is possible to break out components and have sub-projects? Some of the core areas may not change frequently and could be added to the build(kind of like third party jars).

Or you could have your basic build/install and then layer on the customizations. Overlay the custom files and/or modify base files.

Mads Hansen
+2  A: 
Feature Branching is a poor man's modular architecture, instead of building systems with the ability to easy swap in and out features at runtime/deploytime they couple themselves to the source control providing this mechanism through manual merging.

--Dan Bodart -- via Martin Fowler

Version control is very much not the right tool for this, as you want to use it to manage versions, not customers.

soru
"[U]sing if statements instead of branches... is a work around [for] the fact that your version control tool is not doing what it’s meant to do." - Joel Spolsky http://www.joelonsoftware.com/items/2010/03/17.html
jammycakes
Yes: but this seems to be an example of the opposite case. Or do you think all if statements in source code should be replaced by branches?
soru
No I don't think all if statements should be replaced by branches. I'm only talking about the case where you're using if statements and configuration settings as a workaround for the fact that you're not branching and merging: ie, to swap out modules depending on whether you're running in development, test or production.
jammycakes