I have been tasked with researching how to improve the way my company handles version control.
Background
Currently we use Borland StarTeam, which has some issues. Apart from often being difficult to use, the number of tools (IDE support, code review, ...) which support it is very low.
Our company has something like 40 developers but we work with a lot of different projects. A given project usually has something like 3-6 software developers working together.
Our projects range from (mostly) embedded systems and FPGA development to desktop applications.
The current work flow is heavily centralized with one "view" (which is close to a branch in StarTeam language) that everyone in the project works on.
One of the projects use multiple views in the following way:
There is a platform view where no development is done. This view then has two sub views for two specific products that share most code (via the platform view) but is dissimilar enough to be kept apart.
All development is made in the two product views and sometimes code from a product view is promoted to the platform view (which is then automatically available for the other product).
Another project seems to use a main view and a feature view when there was a major feature addition.
We usually have to support software for a long time and provide software updates.
Some of our products have a large number of different versions. The different versions will share most code but some parts are and must be distinctively different.
Developers use both Windows and Linux on their development work stations.
Idea
My idea is to switch over to use a modern DVCS. The work flow I am considering is where each project has a number of public branches which each developer can clone and work on. Each project could then determine if everyone can commit freely, or if we should have some kind of gate keeper system where code needs to pass a human or automated build system before being committed to the public branch.
My idea on the branching setup is to use release and feature branches as in the following scenario:
Let's say we start with development and finally ship version 1.0 of our product. We then find that we want some more features so we aim for a 2.0 release and start a new branch for this. While working on the 2.0 release branch we can still do maintenance on the 1.0 branch leading to the release of version 1.1, and so on.
While working on the 2.0 branch we discover a security problem which is fixed. Since it is available in the 1.0 branch as well that code is backported to the 1.0 branch as well.
Sometime in the 2.0 branch it is discovered that some parts of the system really needs to be completely redone to be able to create feature X. A new public 2.0-feature-X branch is created and worked on. When done, the work in that branch is merged back into the main 2.0 branch.
Actual questions
Hopefully you are still reading at this point :)
Is the above work flow (release and feature branching) a viable option? Are there pit falls to look out for?
In the scenario where a product has a platform branch and multiple product branches, what is the best way to handle this? Would creating a master branch and the product branches work? Is there a problem when two product branches diverge? How much can they diverge?
Have I missed something? I mostly see VCS from a developer perspective so I might be missing stuff that is important from the perspective of a configuration or release manager.
For your second question, I think you can SHARE the platform related code and "most code" shared by different products, and only BRANCH the source code which makes the products "dissimilar". With Share, if an item is modified in one project, the changes will be reflected in other projects simultaneously. With Branch, the file and its counterparts are independent.
So, the two product branches can be diverged as much as you need.
Related
I work as part of a small development team (4 people).
None of us are incredibly experienced with version control, but we are required to use Perforce under our company's policies. For the most part it has been great, but we have have kept to a simple process agreed between ourselves that is starting to become less ideal. I was wondering if people could share their experiences of version control working smoothly and efficiently.
Our original setup is this:
We have a trunk, which holds production code as it is now.
Each user creates a development branch for their work, as we have
always worked on separate areas that don't really affect each other.
We develop on Redhat Linux boxes and the code is run from /var/www/html. So we sync to a workspace and copy those files to this path, change the permissions and then perform our changes there. When we want to check in, we check out the files in the workspace, overwrite them with what we have changed and submit (I think this might be our weakest part)
Any changes to trunk will be incorporated if they affect the functionality in question. The code is then deployed for testing.
When testing is complete, we merge the branch into trunk, and then create a release branch from the current trunk this is tested again and then released into production.
This worked fine previously because our projects were small and very separated. Now, however, we are all working on the same big dev branch. Changes have been released since the creation of the dev branch, and more will be made before it is finished.
We are also required to deploy the code for testing in various stages of it's development, and this code needs to be up to date with both the development changes, and any changes that have been made to production.
We have decided at this stage that we will create the release branch at the same time as the dev branch, into which we will merge current Trunk(production) and the current dev branch each time we need a testing version so that it is completely up to date. However, this merge takes a lot of time from the whole team and isn't really working out too well.
I've been told that different teams have different ways of going about things so I'm not looking for a fix for my process, but I would love to hear what setup you use of your willing to share
If you are not particularly familiar with version control and best practices I would suggest utilizing Streams in Perforce. Functionally Streams and Branches are very similar. The difference with Streams is that Perforce utilizes pre-built relationships based on the stream type and gives basic governance (i.e. you can't copy those files to the other stream until you merge).
All the commands CAN be overridden by an admin.
Once you are utilizing streams you can do things a few different ways. You have three types of streams, Release (most stable), Main (stable), and Development (least stable). You can create any hierarchy you like.
I suppose in your case I would have a Mainline, an integration development stream, and then a development stream for each developer to utilize. That way you each have your own playground and can move your changes to the integration stream once they are complete. Those completed changes can then be merged down to the other developer streams.
I'm wondering if there is any best practice for maintaining your source code under version control among different companies. In Open Source there is a maintainer, who receives patches, decides on them and applies them. But what about closed sourced projects where different companies get different workloads and just commit them to the trunk and branches? Is this maintainer concept applicable to a project on which multiple companies work on?
You can choose from a wide range of version control systems. (Not only subversion)
With the "versioning" concept you are safe that no one damages the project permanently.
So there is no need for a manual approval process, especially when there are contracts for example between the participating companies.
I'd also set up a commit mailinglist so you have some kind of peer review of changes. So no changes can be done without anyone noticing them.
If applicable set up some kind of continous integration environment to keep the quality up.
I don't understand the question about the branches. The decision whether to use them or not is IMHO not depending on the fact that the commiters are employed in the same company or not.
Its really up to you to decide which workflow works best for the companies involved. Subversion has the ability to add permissions to your trunk and branches allowing you to lock down certain parts of your repository to people who are "trusted" with merge access to trunk. You'll need good communication amongst the companies. Using the open source Trac provides a wiki, integrated RSS feeds of the commits to the project and code browser.
Usually, each site works on its dedicated branch and can import the other remote site branch, to decide what to integrate in its own work.
But if a site need to work directly on the other site branch, one possible practice is the concept of branch membership which allows only one site at a time to work on a given branch.
(not sure it is possible with SVN though)
That allows for two remote site (with a large time shift) to work on the same task in a tightly integrated manner.
My recommendation : subversion, with that configured you give away a url and then checkout, update, get things done and when you guess that the project is ready, snapshot and deliver.
Should multiple developers work within the same branch, and update - modify - commit ? Or should each developer have his/her own each branch exclusively? And how would sharing branches impact an environment where you are doing routine maintenance as opposed to unmaintained code streams? Also, how would this work if you deploy each developers work as soon as it is done and passes testing (rapidly, as opposed to putting all of their work into a single release).
In general, I have found that having developers (who are working on the same project) use the same branch is better for finding integration problems sooner. If developers are each using an individual branch, then you're just delaying possible integration problems until later, when you merge the branches.
Of course, having developers work on the same branch means you need to have actual communication between those developers, but that's a social problem and not a technical one.
Developers would work on separate branches when there is a good reason for that branch to exist in the first place (such as a patch release of a previous version of the software, or a special build for a specific customer).
Note that tools such as Git and Mercurial allow developers to easily create their own private branches to organise their own work. This is a different situation from more than one developer sharing a branch, and (usually short-lived) private branches should be encouraged.
Branches are meant as a way to version control any feature or experimental piece of code that may break the mainline/trunk.
While it is common for developers to have their own personal branches for deep experimentation, often branches center around a new feature being added. These new features often require more than one person to be committing.
For example, on a web project, two developers and a designer may be doing a facelift to their company website. They still need to keep their mainline/trunk code clean in case they need to make a quick change to it before the facelift is complete. So they create a "facelift" branch and work on that instead. While the developers are committing javascript, the designer can be committing CSS and images. Once the facelift feature is complete, they can merge it into the mainline and send it live.
The only reason any of them would need personal branches would be for experimenting. Perhaps the designer is trying to implement "sliding door" tabs and can't get the padding right in IE6, for example. If he solves the problem, he can merge it into the facelift branch, if he can't, he simply ignores it and continues with the rest of the design back in the facelift branch.
To some extent, the version control software you are using will nudge you into a particular approach. GIT is geared toward open-source contributors and resembles the "one developer" model (branching isn't even a concept in GIT. GIT is more about managing changes). Clearcase is more corporate, so you do have multiple developers on a branch, but each developer gets to play in his or her own view.
I agree with Greg's answer, this is more a social planning issue. Lots of devs on one branch will step on each other's toes. I've been on a project where there were more developers than individual source files :)
I think that merging of branches can be problematic (dropped or inconsistent functionality), regardless of how good the source control tools are. I would more readily opt for multiple developers working on a single main branch. There could be other branches for things like production bug fixes or proof-of-concepts (POCs), where merging could/should happen very soon after change (bug fixes) or good chance that merging may not need to happen (POCs).
I'm currently in charge of migrating our asp.net applications from source safe to TFS. We have three or four very similar apps (let us say e-commerce) that currently share a core library (services, business logic, entities, data access etc).
The applications are similar but not identical so one app might get a feature set the others won't get etc.
I want to stop the sharing of code and instead set up branches (if that fits) so if I change something in Application A:s core library I will need to merge the changes with the other branches instead of them getting the changes automatically. This to avoid surprises when you update from your trunk and suddenly the core has changed for another project and this project breaks in some way.
Any suggestions on how I should set this up in TFS? Should I have a "main" Core that is not directly used in any project that is the parent of all the other cores so I can push changes up to that one from one core and then distribute it to the other cores? Does that make sense and would it be easy to set up in TFS?
In response to your comment, I'd suggest you to read up on Feature branches on the CodePlex website.
Scenario 4 – Branch for Feature
In this scenario, you create a
development branch, perform work in
that branch, and then merge your work
back into your main source tree. You
organize your development branches
based on product features. The
following is a physical view showing
branching for feature development:
My Team Project
Development -> Isolated development branch container
Feature A -> Feature branch
Source
Feature B -> Feature branch
Source
Feature C -> Feature branch
Source
Main -> Main Integration branch
Source
We are alos moving from SS to TFS in the near future.
As I perceive it, we are going to keep our SS repository online and start fresh over in TFS. Our framework probably will get its own project in TFS. Project specific shared units will need to get merged from time to time.
The way you structure your repository depends on your specific situation. Every branch scenario has its specific advantages and drawbacks.
How many projects
How many developers
Are the developers dedicated
Do you need concurrent hot fixes
Do you need service packs
Take a look at the CodePlex branching guide for all the information you need to make an informed decision about your TFS structure. Print out the cheat sheets and pin them to your wall for quick reference.
Before executing on your branch plan,
pay attention to this cautionary
message - every branch you create does
have a cost so make sure you get some
value from it. The mechanics of
branching in TFS are simplified to a
single right click branch command.
However, the total cost of branching
is paid by reduced code velocity to
main, merge conflicts and additional
testing can be expensive.
I am assuming you have already investigated whether you truly need to make your "copies" seperate team projects. Remember the TFS concept of a "Team Project" is a VERY LARGE high level container. It is not the same thing as what most IT shops consider a "Project". Think of "Microsoft Vista" or "Office 2007" as a project, not, say "A new release of Company XYZ's Accounts Receivable System" as a project in the Team Project sense.
I have a client that decided on one single Team Project for TFS. There is nothing wrong with this - and it is truly the best scenario in many circumstances.
If you truly need a very strong isolation between your copies of the application (perhaps they are seperate clients and you need very strong security seperation) and must have seperate team projects.
That said - you still - as you've stated need to share code between instances of your application. The first thing I would strongly recommend is to get away from "Cut and Paste" sharing. I would truly try to isolate the shared code into a seperate Solution and generate binaries for that (perhaps you've already done this!)
This is covered in the Codeplex TFS: http://tfsguide.codeplex.com/
Another approach I've done for several clients - is to have a Team Project that contains the shared code. The "Build" creates the binaries for the shared code - and the "Deploy" simply copies those to a "known location" (ie UNC share on the build machine)
For the applications that are "Consumers" of the "Framework" we simply used the "AdditionalReferencesPath" Item group to include the location of that known location.
Furthermore - this tool: http://tfsdepreplicator.codeplex.com/ can be helpful. This would allow you to have builds automatically triggered for your "Consumer" Projects whenever the "Framework" solution is built.
My brief answer is that you should only setup one 'TFS project' and simply organize your different projects, i.e. your individual applications, and each shared library, as separate folders under that one TFS project. The alternative is to include specific (binary) builds of the shared libraries in each individual application – if you do that then you can organize each application into it's own TFS project, tho you can't merge changes or branch those projects without using the TFS command line (and some non-obvious commands to boot).
I was trying to determine the same information, this guide on codeplex is perfect
http://vsarbranchingguide.codeplex.com/releases
Includes terminology and different branching workflow approaches as well as cheat sheets.
I'm working on a project that will (soon) be branched into multiple different versions (Trial, Professional, Enterprise, etc).
I've been using Subversion since it was first released (and CVS before that), so I'm comfortable with the abstract notion of branches and tags. But in all my development experience, I've only ever really worked on trunk code. In a few rare cases, some other developer (who owned the repository) asked me to commit changes to a certain branch and I just did whatever he asked me to do. I consider "merging" a bizarre black art, and I've only ever attempted it under careful supervision.
But in this case, I'm responsible for the repository, and this kind of thing is totally new to me.
The vast majority of the code will be shared between all products, so I assume that code will always reside in trunk. I also assume I'll have a branch for each version, with tags for release builds of each product.
But beyond that, I don't know much, and I'm sure there are a thousand and one different ways to screw it up. If possible, I'd like to avoid screwing it up.
For example, let's say I want to develop a new feature, for the pro and enterprise versions, but I want to exclude that feature from the demo version. How would I accomplish that?
In my day-to-day development, I also assume I need to switch my development snapshot from branch to branch (or back to trunk) as I work. What's the best way to do that, in a way that minimizes confusion?
What other strategies, guidelines, and tips do you guys suggest?
UPDATE:
Well, all right then.
Looks like branching is not the right strategy at all. So I've changed the title of the question to remove the "branching" focus, and I'm broadening the question.
I suppose some of my other options are:
1) I could always distribute the full version of the software, with all features, and use the license to selectively enable and disable features based on authorization in the license. If I took this route, I can imagine a rat's nest of if/else blocks calling into a singleton "license manager" object of some sort. What's the best way of avoiding code-spaghettiism in a case like this?
2) I could use dependency injection. But generally, I hate it (since it moves logic from the source code into configuration files, which make the project more difficult to grok). And even then, I'm still distributing the full app and selecting features at runtime. If possible, I'd rather not distribute the enterprise version binaries to demo users.
3) If my platform supported conditional compilation, I could use #IFDEF blocks and build flags to selectively include features. That'd work well for big, chunky features like whole GUI panels. But what about for smaller, cross-cutting concerts...like logging or statistical tracking, for example?
4) I'm using ANT to build. Is there something like build-time dependency injection for ANT?
A most interesting question. I like the idea of distributing everything and then using a license key to enable and disable certain features. You have a valid concern about it being a lot of work to go through the code and continue to check if the user is licensed for a certain feature. It sounds a lot like you're working in java so what I would suggest is that you look into using an aspect weaver to insert the code for license checking at build time. There is still a going to be one object into which all calls for license checking goes but it isn't as bad of a practice if you're using an aspect, I would say that it is good practice.
For the most part you only need to read if something is licensed and you'll have a smallish number of components so the table could be kept in memory at all times and because it is just reads you shouldn't have too much trouble with threading.
As an alternative you could distribute a number of jars, one for each component which is licensed and only allow loading the classes which are licensed. You would have to tie into the class loader to achieve this.
Do you want to do this via Subversion ? I would use Subversion to maintain different releases (a branch per release e.g. v1.0, v2.0 etc.) but I would look at building different editions (trial/pro etc.) from the same codebase.
That way you're simply enabling or disabling various features via a build and you're not having to worry about synchronising different branches. If you use Subversion to manage different releases and different versions, I can see an explosion of branches/tags in the near future.
For switching, you can simply maintain a checked-out codebase, and use svn switch to checkout differing versions. It's a lot less time-consuming than performing new checkouts for each switch.
You are right not to jump on the branching and merging cart so fast. It's a PITA.
The only reason I would want to branch a subversion repository is if I want to share my code with another developer. For example, if you work on a feature together and it is not done yet, you should use a branch to communicate. Otherwise, I would stay on trunk as much as possible.
I second the recommendation of Brian to differentiate the releases on build and not on the code base.