I'll preface this question with the statement that we are likely using TFS incorrectly based on some early misunderstandings on how TFS works, versus how GIT works.
Background:
We have a main branch which is where we do all of our development.
When we are ready to release, we create a branch off of the main branch and name it by the version (ex, "v8.10.0").
We compile and release from this new branch.
We then proceed with development back on the main branch.
If a critical issue is discovered with the previous release, and we are mid-stream in a sprint on the development branch, then we need to create a patch for the previous version. In this case, we create a new branch off of the release branch and start fixing the problem on that new branch (ex "v8.10.1").
Then we want to get the fix(es) we applied on the 8.10.1 branch into the main branch, and so we perform a merge from 8.10.1 to dev, and that is where the problems start to happen. This merge is a baseless merge and without fail that merge takes hours to complete, involves a lot of manual merging, and at the end of the process there are usually a handful of files that got botched in the merge process. Even worse, TFS usually decides that it can auto-merge some of the files and it tends to do this completely wrong and we wind up with completely ruined code.
There seems to be a flaw in our basic understanding of how to accomplish this task, and though it does not happen often, it always bites us, so what are we missing, and what is the correct way to do what I have outlined above?
Well there are many strategies of branching and only you can decide which is most suitable for you. What I see from the question is that you have main development branch and release branches. You have no branch for testing. You have no branches for parallel development. You have branches for hotfixes. One way to organize branches is:
O----------------main dev branch------------------>
| ^
V |
O---------------release branch---------------->
| ^
V |
O--------------hotfix branch------------->
So you have 1 branch for main work in development. Branch for realese from main(one branch not per release). And branch for hotfix from release. For versioning you can apply labling on release branch(https://msdn.microsoft.com/en-us/library/ms181439.aspx). Now you can merge without problems from main to release, from release to hotfix and back from hotfix to realese and from release to main.
In reality things get a little complicated with testing branch and parallel development branches. In my project we use something like this:
O--------parallel dev2---------------------------->
^ |
| V
| O---parallel dev1---------------------------->
| ^ |
| | V
O------------------main dev branch---------------->
| ^
V |
O--------------test branch------------------->
| ^
V |
O--------------relese branch------------->
But without all this, your design should also work. The main reason you have problems is that you are doing a baseless merge when you could merge hotfix branch back to release branch and from release back to main branch.
Related
We have a simple branch process where we have a Main branch which is meant to be the source code used in production. We also have one or more branches from Main which are development branches.
We have emergency fixes that go into Main but may not be in one or more of the development branches. From time to time, and especially just before we promote a development branch to Main we merge from Main to the development branch to make sure everything from Main is in the branch. This time it was all there so no action was necessary.
We then merged from the development branch to Main, naturally it identified all the files we had changed in the development branch, but it also came up with a small number of conflicts. Now as we had just successfully merged from Main to the branch I did not expect this.
Investigation showed the following history for one of the files that had a conflict.
In Main
In development branch
It seemed a fix was made in the development branch (10917) and then merged to Main (11090).
For some reason when we merge down to the branch the previous merge up (11090) is not detected and so is shown as a conflict when we try and merge to Main.
In practice the code in both branches is the same but it causes extra work with us having to investigate changes that are not there.
Can not see why this did not merge down? Is our process at fault?
I think this is caused by you didn't get latest of main branch before you try to merge to development branch. Make sure you have get latest both of main and development branch before the merge.
Next time, you can directly merge specific changest, you can select selected changesets then choose 11090.
We are trying to implement the "Basic Dual Branch Plan" as described by the ALM Rangers in the latest Visual Studio TFS Branching and Merging Guide. From the guidance:
The basic branch plan with a MAIN, DEV, and RELEASE branch enables concurrent development for your next release, a stable MAIN branch for testing and a RELEASE branch for any ship blocking bug fixes. Multiple development areas are supported by creating additional development branches from MAIN. These are peers to each other and children of MAIN.
Additional releases are supported by creating release branches for each product release. Each release branch is a child of MAIN and a peer to each other (e.g. release 2.0 branch is peer to release 3.0 and both are children of MAIN). If supporting only a single release in production at a time, you may consider a single release branch, and make bug fixes directly on this branch. Once the RELEASE branch is created MAIN and the development branches can start taking changes approved for the next product release.
We are undecided as to whether we want to use a single Release branch (and label releases), or create a new release branch per release. However, there are some questions that apply either way, that don't seem to be addressed by the guidance.
My main question is: At what point in time should we create a RELEASE branch (or move tested code to the single RELEASE branch if that's the way we go)?
My first reaction was to create it only when ready to do the release, but then you have the problem of creating a deadlock for development and testing of the next sprint's work; you cannot check these changes into MAIN until the RELEASE branch has been created (if you do, it's more difficult to separate out the changes you only want to go to RELEASE).
Second idea is to create the RELEASE branch at the beginning of the sprint, and as changes pass testing in MAIN, merge them down to the current RELEASE branch. Once we reach the end of the sprint, we can lock that RELEASE branch down, and create a new one for the next sprint. This sounds like it would work, but I see no discussion of it anywhere, so I just wanted to see what people are doing.
I would give the same advice as Adarsh Shah in that 2 branches (MAIN, RELEASE) are sufficient in most cases, and using feature branches for things that you don't want to commit into MAIN immediately because it would take a while to be fully ready for testing. And by RELEASE I mean a branch per actual release.
Keep in mind though that, in theory, MAIN should in a release-ready state at any moment. This means using feature branches for a lot of small changes too and not merging things into MAIN as long as the feature is not considered ready. Now, this is something that you should experiment with and see what works best in your environment. If you find that it is too hard to keep MAIN into a release-ready state, by all means, create a separate DEV branch to commit the daily work. In my experience however, with some good guidelines, automated and manual testing you quickly can get into a flow where MAIN can be considered quite stable. I've worked in environments where we had a DEV branch which was highly unstable and a stable MAIN branch, and environments where we didn't have a DEV branch. Sometimes the DEV branch was needed, sometimes it became a burden to keep them in sync as both DEV and MAIN were fairly stable and essentially just a copy of each other.
Now, when should you create the release branch. It depends on the type of development you are doing. For small desktop projects or websites which have a fairly steady release cycle (a single release per sprint, for example) I find it easiest to create a release branch at the end of a sprint, and only pushing it to production the sprint after.
S1 - - S2 - - S3 - - S4 // Each sprint
\ R1 - \ R2 - \ R3 // Release branch created at the end of a sprint
\ P1 - \ P2 // Pushed to production at the start of the next sprint
So, at the end of S1 I create the release branch R1 from MAIN but it's not pushed to production just yet. During S2 both new features are implemented on MAIN and critical bugs are fixed on R1. If a fix on R1 is approved, it gets merged back into MAIN too, if it's required. At the end of S2, a new R2 is created, and R1 is pushed into production. I have found this approach to work quite well. You basically have a full sprint to work out the last issues in a release branch.
Of course, if a serious critical bug appears on production this bug gets priority above all else. An RXa, RXb, ... branch can then be created of the existing R-branch that's in production, implement the hot-fix and push that hot-fix into production. You can then consider whether it's needed to merge the changes from the hot-fix into your MAIN branch. Don't create a hot-fix on the MAIN branch and merge it down though, you'll find that it quickly becomes too complex because on MAIN a lot of the surrounding code might have already changed.
Here is what I would suggest:
1) Do all development on the Main branch until Code Complete. Code complete is the time when developers stop working on new features for that sprint but can fix regression bugs. Code complete can be few days before the release or up to a week based on how long is your sprint).
2) Create a new RELEASE branch from the MAIN at that point . Deploy the branch to QA/Staging environment to do a smoke test. After that point QA team will use RELEASE branch to do the testing for the release.
3) Developers can start working on the new features for next sprint at that point and start checking-in changes to MAIN branch. Any regression issues found during testing will be fixed in RELEASE branch first and then merged back to MAIN.
4) Any changes to code in RELEASE branch will then be pushed to QA/Staging for further testing.
5) One the Release is done any bug found in production will be fixed in RELEASE branch and hot-fixed to Prod and also merged back to MAIN.
No. 1 will be too late and no. 2 will be too early IMO.
I would suggest to create a new branch for every RELEASE and then get rid of old RELEASE branches periodically instead of using labels.
Also, I prefer having only 2 branches MAIN(which is also DEV) and RELEASE except any branch developers need to any specific feature/framework change etc. Under the root folder I usually create MAIN, RELEASES(all release branches) and BRANCHES(all branches specific to a feature/framework changes etc. but these are created only in special cases not always)
I am new to TFS and trying to figure out how to get my new rewrite of an existing application into TFS properly with Branching...
I have a project where I have three branches Dev Main and Prod
I just created a new branch off the Dev called Dev-branch-Rewrite I was able to get my code into the Dev-branch-rewrite but it doesnt show the main as being a branch I can merge to. I have done something incorrectly. Not sure what I am doing wrong
TFS forces a strict branch hierarchy, so you need to plan ahead. Currently I suspect that main is the parent of both dev and prod so in effect to go from dev to prod you have to merge via main.
The best practice would be to take the new branch for your rewrite from main this way you have a clear path to prod once the rewrite is done, but you can still support your users in the existing dev branch.
I.e
Prod
|
Main
| |
Dev Dev2.0
As a side note, I'd try to keep your branch names as short as possible as you may start to hit the windows 260 character path limit.
For more information on branching strategies, read the ALM rangers guidance on codeplex.
When making a deployment to production, should I mark my code with a label or create a branch for the code that's in production?
In TFS, I would have a Release branch with a label identifying the specific version being released to production.
Which would imply you have other branches may I suggest the following
Three major branches: Main, Develop, & Release.
One Hotfix branch for your current fire.
0 to N Major-Feature branches to contain the disruption of development.
Details
Main Branch
Contains the latest stable builds
Tag/Label each release
Develop Branch
Branched from the Main
Where most of the work is done
Merge back to Main before release
Release Branch
Branched from one of the following:
The Develop branch
OR the Main branch (this may be better since it is "stable")
Bug fixes are done here
After fixes are tested and released,
merge to Develop branch
OR merge to Main branch and then forward integrate (FI - which is a merge from parent to child) to Develop
Tag/Label each release or bug fix
Hotfix Branch
Branched from Main
Merged back into Main
Forward integrate merge to Develop
Used to allow Main to remain "stable"
Major Feature Branches
Branched from Develop
Merged back into Develop
Used for major features that would possibly disrupt the regular development path
References:
another stack overflow question: when-to-use-a-tag-label-and-when-to-branch especially Martin Woodward's answer
Source Control How To by Eric Sink
A successful Git branching model by Vincent Driessen
This contains a very good graphic of a branching model
Ideally, both.
You probably want to have a label so that you know exactly what you delivered for a specific release. However, you probably also want to create a branch so that you can perform minor bug fixing to what was released and create a new release.
In practice, you could approach it in one of two ways:
Have a continuous developmental timeline that gets branched for each of your production releases:
example:
------------------------->dev
| | |
| | |
| | |
v1.0 v2.0 v3.0
Have your production releases "cascade" off of one another:
example:
---->v1.0---->v2.0---->v3.0
Ultimately, up to you in deciding what architecture to adopt, as long as it's consistent and makes sense to you.
You can use a combination of both. Here is how we do this internally for all projects.
We have structure with folder Branches and sub folder for each minor and major version. We also use labels that we set on individual sub folders so we can easily rebuild any specific version any time in the future.
$\Branches
\2012.01
\2012.02 (branched from 2012.01)
\2012.03 (branched from 2012.02)
\2013.01 (branched from 2012.03)
You can also check out Visual Studio Team Foundation Server Branching and Merging Guide for more details.
I have seen both done, Labeling is more lightweight and to me easier. But, it has been pointed out that labels can be deleted rather easily. A branch protects against this by not actually being deleted unless "destroyed". The reason I prefer not use branches is I hate having to cloak them as I tend to do get latest from the root and don't want all those branches filling up my hard drive
For the record, since it was pointed out to me about label's being deleted I have removed permissions for Labeling from everyone but Admins and the build service accounts to help mitigate this.
I have a release branch (RB, starting at C5) and a changeset on trunk (C10) that I now want to merge onto RB.
The file has changes at C3 (common to both), one in CS 7 on RB, and one in C9 (trunk) and one in C10). So the history for my changed file looks like this:
RB: C5 -> C7
Trunk: C3 -> C9 -> C10
When I merge C10 from trunk to RB, I'd expect to see a merge window showing me
C10 | C3 | C7 since C3 is the common ancestor revision and C10 and C7 are the tips of my two branches respectively. However, my merge tool shows me C10 | C9 | C7.
My merge tool is configured to show %1(OriginalFile)|%3(BaseFile)|%2(Modified File), so this tells me TFS chose C9 as the base revision.
This is totally unexpected and completely contrary to the way I'm used to merges working in Mercurial or Git. Did I get something wrong or is TFS trying to drive me nuts with merging?
Is this the default TFS Merge behavior? If so, can you provide insight into why they chose to implement it this way?
I'm using TFS 2008 with VS2010 as a Client.
I had some similar initial struggles with TFS branching and merging (We have dev, integration, and main branches).
Short version is that you cannot merge directly back from a tip to a common ancestor.
So if C3 was branched to C5, then C7 was branched to C9, what the tool is providing makes sense within the context of how TFS works. You essentially need to go from C10/C9 to C7 then from C7 to C3.
To put it a different way with a more concrete example, here's how we handle multi-level branching and merging in our projects.
We start with trunk/main.
We then branch to an integration branch.
We then (and this is key) branch from integration into our individual dev branches so we can work on upcoming releases.
As changes are complete in a dev branch, we first reverse integrate by merging from integration to our dev branch (so we pick up everyone else's changes). We then forward integrate by going from our individual dev branch to the shared integration branch.
Once integration passes QA, we then reverse integrate by merging trunk to integration (just in case there are any hotfixes in main), then forward integrate all of the combined changes in integration down to main.
On release day, we do one last branch from main into a new release branch which we then deploy.
Basically, in TFS you always have to go up and down the branching/merging tree from trunk to limb to branch to leaf - you cannot at any time bypass any step in the branch heirarchy.
Metaphorically, TFS branch and merge is more like as sloth crawling up a tree and slowly down to the end of a branch without ever letting lose it's grip vs. a monkey hopping between branches ;)
Takes a bit of getting used to, but once done (and especially once you're used to the forward integrate/reverse integrate paradigm) it works a treat, especially when you have several folks all doing development and you need to wrap up everyone's changes without having things stomped over.
Hope that helps!
i was looking around this site before and came across to this page, is this helpful?
How to branch and merge in TFS
I think you might have a wrong merge methodology, because what you describe is completely possible, and it works for me. But you always have to remember when you start branching off the main branch is to do proper RI (Reverse Integration), and FI (forward integration). Have a search on codeplex for branching guidelines and best practices.
In essence, any changes that is dropped back to the main branch have to be RI'd back onto your other branches before merging it back. This is best practice and works every time, after that, you can continue to FI from branch back to main trunk.