I have been in two different teams before, both use SVN to release the production code.
The first team commit code on the trunk when developing feature, and every week the lead make a release and tag the
product and store the tagged code in another branch.
The second team branch for each big feature, and when the feature was done, the feature will be merged back to the trunk. When the code needs to be released, another branch is created and cloned from the trunk. Some test and bugfix will be done on the branch for the release. After the product is released, the brach will be closed.
Which is better?
Is there a better way to do version control?
You're near to branch per feature (aka branch-per-task pattern). You maybe want to take a look to the following articles:
This article talks about different integration (release) strategies,
with pros and cons:
This other explains branch-per-task pattern:
Related
In version control, we have a main branch and recently created a release branch. We were dicussing, where to fix an issue and where to merge it (fix in main and forward integrate to release or fix in release and reverse integrate to main).
Microsoft states in their "Branching and Merging Primer" (https://learn.microsoft.com/de-de/vsts/repos/tfvc/branching-strategies-with-tfvc?view=vsts) that one should never forward integrate from main to release. But they don't present I reason, nor can I think of one.
Is there a reason for this?
A lot depends on your particular way to use a SCM - independently of which one you use.
It makes a difference if you are a company with 1000 committers working on one single
product or if you are talking about a tiny project with just 3 people.
However in general it is indeed not a good idea to merge changes from a main line to
a release line.
Imagine your mainline frequently gets commits (either directly or merged from other branches).
Now we assume that the main branch got some bugfixes that you also want in your release branch.
If you attempt to merge the bugfixes from main to release you probably run into problems, because the bugfixes are entangled with other changes that you don't want in your release branch (possibly because they implement new features for the next release).
Also the merging process might result in new mistakes/errors and break the release which you probably do not want.
See:
This also depends on the question if you want to alter an existing release at all.
You could instead create a new release based on the previous one and then merge
the desired changes from main and subsequently fix them.
This is more or less the same, but with the difference that you never touch an existing release (which may be of importance for you or may be not).
See:
A clean way to update the existing release would be to branch off a temporary branch
from your release branch, then merge the relevant changes from main. After subsequently fixing the temporary branch you can merge it to the release which should now be a simple copy operation without the risk of breaking anything.
See:
Update:
After reading your question again I found that you're thinking about changing in the release and then merging to main.
IMHO a release branch should never ever be used for developing any changes. It should always only pick up changes that were developed and tested in other branches. After all the reason of having release branches is that they are stable and reliable. Any development ruins that.
I recently started taking an interest in using a branching model similar to Vincent Driessens Git branching model. We have multiple developers working on the same project so using different branches for different features is a big plus for us. The model states that after a feature is developed, it is merged back into the Development branch, and on a certain time a release branch will be created from it.
Now my problem is that I don't know who added what to the dev branch since the last release, but I do want to present a list of changes that will be implemented for the next one. So the question is, how do I know what features have been added to the dev branch?
We're using TFS for version control. As far as I know I have the following options:
Better labeling and commenting of versions (currently there is no labeling and little commenting)
Linking TFS tasks to versions (not sure how to create a nice list of that yet though)
Maybe I should just follow my own options above but I was curious about how you guys deal with this.
First I would suggest you take a look at the TFS Branching and Merging Guide as it will likely answer most of your questions.
how do I know what features have been added to the dev branch?
I think the "develop" branch in Driessen's model is most closely equated to the "main" branch in the TFS guidance. I would suggest that you shouldn't merge changes into main unless they are already planned to go into the next release. Then when you are ready to release you simply branch from the latest version of main.
Keeping track of what features are intended for the next release is something that would be handled by the work item tracking system.
Separately, you may find the Track Work Item feature of Team Explorer to be helpful.
We have team of 10 developers who works parallel for different features, sometimes these features use common code sometime no.
And now we're changing our process to branch-per-feature and it seems mercurial is more suitable for such development.
I see this process so:
1. make release branch (r-b) from default(trunk)
2. make feature branch (f-b) from default(trunk)
When developer thinks his feature is done he can merge f-b to r-b. When it's time to go to QA we merge all finished f-b to r-b and create release for our QAs.
Questions:
When QA finds a bug developer should modify his f-b and merge it again to r-b. Does it mean that developer just switch to his f-b and start fixing the bug and then makes simple merge f-b to r-b again?
When release is passed QA it goes to PROD - how can we freeze changes? "hg tag" is good choice but someone can update tag if he really wants it.
Thanks
If you're going to merging into specific release branches then your feature branches should be branched from the release branch, not the trunk. It is simpler to merge with the parent branch than a non-parent branch.
1) If you really want to do feature branches then each bug would have its own branch. This will help keep bug fixes separate from new features. After all, it's branch-per-feature not branch-per-developer.
2) Hg tag is what I have used. You are right that someone change move a tag if they really want to, but tags are versioned and you can install hooks on the main hg repo to throw alerts if a tag is moved. I really wouldn't worry about tags being moved unless you can't trust your developers, in which case you are screwed.
The answer to your first question is 'yes'.
The best way to freeze for release is to have a separate release clone that only the release manager can push/pull changesets to. Just because you're using branches doesn't mean multiple-clones don't have a place in your workflow. Have a clone that QA does final pre-flight testing on to which developers can't push changes makes for a great firewall.
Also, consider using bookmarks for your feature branches. Since, as I'm sure you know, Mercurial named branch names never go away the git-like bookmarks work well for sort lived concepts like features and bugs.
I have the unfortunate opportunity of source control via Borland's StarTeam. It unfortunately does very few things well, and one supreme weakness is its view management. I love SVN and come from an SVN mindset. Our issue is post production release we are spending countless hours merging changes into a "production support" environment.
Please do not harass me this was not my doing, I inherited it and am trying to present a better way of managing the repository. It is not an option to switch to a different SCM tool.
Current setup
Product.1.0 (TRUNK, current production code, and at this level are pending bug fixes)
Product.2.0(true trunk anything checked in gets tested, and then released next production cycle, a lot of changes occur in this view)
My proposal is going to be to swap them, have all development be done on the trunk (Production), tag on releases, and as needed create child views to represent production support bug fixes.
Production
Production.2.0.SP.1
I can not find any documentation to support the above proposal so I am trying to get feedback on whether or not the change is a good idea and if there is anything you would recommend doing differently.
I use an intermediate approach inspired by Henry Kniberg's article Version Control for Multiple Agile Teams. I'm quoting a small part below:
The big picture
OK, now I've gone through a fairly detailed example of how to put this pattern to use. Now let's back out a bit and look at the big picture.
In the mainline model, a branch is called a codeline (in fact, branch is considered to be an implementation of a codeline). Sometimes these are called streams.
A codeline's parent (i.e. the codeline that it originated from) is called its baseline. Mainline is the codeline that has no baseline.
So in our examples above we could conclude that:
The trunk is our mainline. It has no parent right?
All other codelines (release 1.0, team A work, team B work) have the trunk as baseline.
Here's a more complex example:
(source: infoq.com)
This picture tells us that:
The project X codeline was spawned
from the mainline. The project is now
complete, so the branch is closed.
Team A has an active work branch that
was spawned from the mainline.
Team A also has an ongoing spike that was
spawned from the work branch.
The release 2.3 branch is closed, since
2.3 is no longer in production and won't be maintained.
Each codeline has a relative firmness
level with respect to its baseline,
i.e. each codeline is either more firm
or less firm (softer) than its
baseline.
A firm codeline is stable,
thoroughly tested, changes seldom, and
is close to release.
A soft codeline is unstable, barely tested,
changes often, and is far from
release.
When drawing codelines, firm codelines
branch upwards and soft codelines
branch downwards. So looking at the
picture above, we can conclude that:
Release 2.3 is firmer than
mainline.
Team A work is softer
than mainline.
Team A spike is
softer than team A work.
To summarize:
The trunk is the DONE branch (always releasable)
Work is done in work branches (one per team) that may be less stable than the trunk
Release branches are created based on the trunk at the time of the release.
I warmly recommend reading the whole article.
Here's my general advice for structuring build streams:
+HEAD - master -> current development
+ tags
+ version1
+ version1.sp1
+ version1.sp2
+ version2
+ branches
+ version1.sp2.fixes <- at some point, this will get promoted to version1.sp3
+ version2.fixes <- at some point, this will get promoted to version2.sp1
+ version2.nix.feature1 <- this is your (nix's) private version2.feature branch
+ master.nix.feature2 <- this is your (nix's) private new development feature branch.
Basically, you NEVER commit directly to a .fixes or the master branch - only an integration process does that.
Anyhow, pretty much any source control tool will support this model.
I agree with yours and Chris Kaminski's approach. We use StarTeam and this is how we use it. The Tip or Main view in each project is the current development line (in StarTeam terms this is the default view that has the same name as the Project name). Anytime we do builds on this view our build server creates a Build Label. A release is done as of a certain build Label.
We would then create a new View as of that Label as the production release branch and then any bug fixes to the release would be applied to that view (whether bug fixes are done in the Tip view and merged to the branch or vice versa is irrelevant, as long as they do get merged into the main Development view).
Also, if we have a particular project that is going to be long running and will not be completed prior to the next normal production release, we will do a branch off of the Tip view with the Branch on Change setting. This is definitely less than ideal since much merging must be done once it is complete, but it does keep that code out of the main development line and ensures it can't accidentally end up in a production release. We do try to limit these types of projects, but sometimes the business folks dictate them.
This setup has worked very well for us and seems to be easy for new folks to understand and work with.
I have been tasked with coming up with a strategy for branching, merging and releasing over the next 6 months.
The complication comes from the fact the we will be running multiple projects all with different code changes and different release dates but approximately the same development start dates.
At present we are using VSS for code management, but are aware that it will probably cause some issues and will be migrating to TFS before new development starts.
What strategies should I be employing and what things should I be considering before setting a plan down?
Sorry if this is vague, feel free to ask questions and I will update with more information if required.
This is the single best source control pattern that I have come across. It emphasizes the importance of leaving the trunk free of any junk (no junk in the trunk). Development should be done in development branches, and regular merges (after the code has been tested) should be made back into the trunk (Pic 1), but the model also allows for source to be patched while still under development (Pic 2). I definitely recommend reading the post in its entirety, to completely understand.
Pic 1
Pic 2
Edit: The pictures are definitely confusing without words. I could explain, but I would basically be copying the original author. Having said that, I probably should have selected a better picture to describe the merge process, so hopefully this helps. I'd still recommend reading the post, however:
The simplest and most usual way I've seen branching work is off two premises. Trunk and Release. I think this is known as the "Unstable trunk, stable branch" philosophy.
Trunk is your main source. This contains the "latest and the greatest" code and is forward looking. It generally isn't always stable.
Release is a one-to-many association with trunk. There is one trunk but many releases that derive from the trunk. Releases generally start with a branch of the trunk once a particular functionality milestone has been hit so the "only" things left to go in for a particular deployment should just be bug fixes. You then branch the trunk, give it a label (e.g. 1.6 Release is our current latest Release), build and send the release to QA. We also push the version number (usually the minor number) of the trunk up at this point to ensure we don't have two releases with the same number.
Then you begin the testing cycle on your release branch. When sufficient testing has been perfomed you apply bug fixes to the release branch, merge these back to the trunk (to ensure bug fixes are carried forward!) and then re-release a build of the branch. This cycle with QA continues until you are both happy and the release is finally given to the customer(s). Any bug reports from the customer(s) that are accurate (i.e. they are a bug!) start another QA cycle with the branch in question.
As you create future releases it is a good idea to also try to move older customers onto newer branches to reduce the potential number of branches you might have to back-patch a bug fix into.
Using this technique you can deploy solutions using your technology to a variety of customers that require different levels of service (starting with least first), you can isolate your existing deployments from "dangerous" new code in the trunk and the worst merge scenario is one branch.
My first recommendation would be to read Eric Sink's Source Control HOWTO - specifically the branches and branch merge chapters.
We have 3 containers - DEV, MAIN, and RELEASE for our work. MAIN contains all our "ready-to-release" code and we tend to think of it as "basically stable." DEV/Iteration (or DEV/Feature, or DEV/RiskyFeatureThatMightBreakSomeoneElse) are branches from MAIN and are merged up when the Iteration/Feature is ready to promote up past the DEV environment. We also have TFS builds set up from the DEV/Iteration branch and the MAIN branch.
Our RELEASE container contains numbered releases (similar to the "tags" container used in many Subversion repositories). We simply take a branch from MAIN each time - I like to say we're "cutting" a RELEASE branch to signify this shouldn't have a lot of activity going on once the merge is finished.
As for VSS->TFS - Microsoft supports an upgrade path which should keep your version history, but if you don't need it the history, I would just get the latest version from VSS, check it into TFS and archive the VSS repository.
One final tip - get your team members familiar with source control. They must understand branching and merging or you will be stuck doing a lot of cleanup work :).
Good luck!
The subversion book describes some common branching patterns. Maybe you can also apply these to TFS.