Incorrect TFS branching strategy - how to fix - c#

It looks that eventually we moved our project to a bad branching strategy - "Cascading" (in question "TFS -- Sustainability of Cascading Branches" it was recognized viable actually). Now, after reading few articles and seeing it leads to infinite branching tree, I realized that it's bad and want to fix it. But it's not so easy as I expected. TFS allows merges only with parent branches (siblings merge isn't possible).
Here is the diagram of our current branches hierarchy:
Looks weird, but it all started from small changes in latest release branch while trunk has been suspended in the middle of 3-month work. Then we made few internediate releases one based on previous one (up to 1.1.4). But when we started release 1.2.0, the story with trunk repeated and we must have suspend 1.2.0 and implement 1.1.5 hotfix.
Now I faced the need of merging 1.1.5 changes into 1.2.0 branch which isn't possible directly. I can only merge 1.1.5 with 1.1.4 which I wanted to avoid (who knows maybe we'll need to implement 1.1.6 based on 1.1.4 tomorrow). But it seems I have no other way out. Still it will be possible to create 1.1.6 branch from non-latest revision of 1.1.4.
Is it what I must do and isn't there a better way out?
And now comes big troubles and the main question. Eventually I'll need to merge all changes into trunk. And 1.1.5-1.2.0 problem is just a miniature copy of that. That's why I'm asking an optimal and least risky way to perform this merge.
My current plan is the following:
Create branch "1.1.4 final" with the latest stable released version.
Optional: Create similar final branches for all previous numbered releases. Should I do it? Most likely I won't need that versions in the future anymore.
Merge 1.1.5 into 1.1.4
Merge 1.1.4 into 1.2.0. There wasn't much changes in 1.1.5, so I shouldn't run into problems here.
Merge 1.1.4 into 1.1.3, 1.1.2 and downto the release branch. Should I expect conflicts or problems here? I expect and hope not.
Merge release into trunk. Most scary part =)
Stabilize code in trunk.
Now it is time to create a better branching strategy... I'm very unsure about this part at the moment.
Create new "stable" (Main) branch from trunk
Reparent trunk to become child of stable. This solution is suggested in related question "How to fix TFS incorrect branching"
Should I remove current "release" and "R***" branches, or leave them as garbage?
For next comming releases do not create separate branches - instead label the final revisions in stable branch. Actually "stable" branch will consist only of final release checkins.
I'm NOT going to create the "integration" branch for QA of stable features - currently we all live in single active branch without problems.
Create "alternate" branch based on stable for paralel development in case we'll need to once more suspend current work to make some urgent fix. Should I keep single alternate branch forever, or delete it once merged and create a new one (like R125) when again needed?
The idea of this change is to have fixed limited number of branches (ideally 2, at most 3-4).
Please share your thoughts and concerns on my strategy, or propose a better one. I'm asking because not sure it all will work as I expect, don't know if it's the easiest way, and the mistake cost is huge.

Is it what I must do and isn't there a better way out?
I'd carefully perform a baseless merge of all the changes from the branches under release into trunk. I'd do this one branch at a time, and merge "All changes up to a specific version" and select all "Latest Version". That will give you a trunk that contains all of the changes from your releases.
Should I expect conflicts or problems here?
You may get conflicts, but with a bit of care and some forensic investigation of the history, you can get the changes into your trunk.
The normal process when working on release branches (even those not directly related to trunk) is to check into the release branch, then to RI (reverse integration) merge the change back to trunk. Some people prefer to check into trunk first and then merge into the release branch to avoid the situation where trunk may get forgotten about. It's six of one, half a dozen of the other IMO.
Should I remove current "release" and "R***" branches, or leave them as garbage?
I don't think it matters, you could move them into a folder called obsolete releases if you want to hide them, or just delete them - TFS deletes are soft.
Please share your thoughts and concerns on my strategy, or propose a better one
I wouldn't create a stable. Once I had everything in trunk I would be happy, the purpose of a trunk/Main branch is to be the stable releasable version of the code, if the developers cannot keep it that way (I'm not blaming them BTW), then working in feature branches and regularly FI merging into the feature branch is the best way.
Where you go next really depends on the process your company has for releases.
One option is to "label" trunk when you have a release you would like.
Start -----L:R1-----C->
If you then need to put in a bug fix before release, you can branch from the label:
Start -----L:R1-----C->
| /
B:R1 |--C/
Check the change into the R1 branch (B:R1) and merge it back to trunk.
This gives you a branch for releases if needed, but not too deep structure, you may end up with many branches, but you can use folders to keep them organised.
I hope this helps, in closing make sure you read the ALM Rangers branching guide - it covers the main TFVC branching strategies you are likely to need and when you should use them.
And finally, my question to anyone who wants to make a branch is "How will you release this code?", this helps me make branches to solve problems, instead of creating problems. If I don't know how the code will be released, I don't know the best way to structure the branches - I was once involved in a project with a hierarchy of 23 branches off Main, that all ended up coming together before been tested or released - we could have used one :).
Last thing, if you have a VSOnline account or another Team Project Collection, you could try re-creating a simpler version of your problem and experimenting with solutions.

Your merge stratigics looks ok to me but i will try to finish with three branches diagram.
We are using three branches Dev,Test,Release.
most of the builds are from dev and are labeled. (same as trunk at your diagram).
Then we move it to qa and continue development.
If there is an issue \bug and Dev branch is in future development we set test branch to the label and fix the issue on test branch and merge it to dev and again and take label.
If we have an issue with production we use the label on release branch fix the issue, label it and ofcourse merge it to dev.
This how it all done using three branches.
Ofcourse you can always use feature branches for long and defacult features.

Finally, I preformed that merge! Thanks #DaveShaw for recommendations, I mostly used them. But want to publicate my invention which I believe significantly saved time.
Instead of performing a baseless merge from R120 directly into trunk, I created an internediate branch dev, from the common root revision of R120 and trunk and preformed a baseless merge from R120 into dev. That generated more than 600 files with conflicts! But it was easy to resolve them - Take everything from the R120.
Then, since branches dev and trunk have common root, I could merge them with regular merge (not baseless). That performed much-much better than a baseless one and generated only 11 files with conflicts and I could resolve them in only 1 day - all those were real conflicts needing manual resolution and code editing to merge. So that saved me time to distinguish real 11 conflicting files from 600 those which are not a real conflicts and can be resolved automatically.
Next, I will stabilize both branches and switch their roles (it appeared that currently dev plays role of main (stable) and trunk is broken). So I decided to use branching strategy "Development isolation" which will evolve soon to "Development, Feature and Release isolation".
For most of my remaining questions, #DaveShaw provided good explanative answers I have nothing to add to.

Related

How to prevent Git (Bitbucket) from merging big files?

A few months ago a developer pushed and merged a feature branch into our main branch (develop) that contained test files (800MB). I deleted these files from Bitbucket and everything (it was a pain). Now I am looking for a solution that could prevent this from happening in the future.
Is there some kind of process/script that I could run before performing a merge to my main branch? I would like this process to check every single file in the solution and verify that every file is less than 2.00MB.
Not sure if this will help or not, but the solution consists of various C# projects, including unit tests.
Use one of the git hooks to prevent this, either on receiving a push in the central repo, or before merging.

Need suggestion on process/architecture for multiple releases simultaneously for a single product

I'm working with a product development firm having multiple releases simultaneously for same product.
We have around 4 environments with their own copy of SQL database and TFS branches.
Now the problem is we spend lot of time on merging code, resolving conflicts and merging within various branches to make sure we do not mess with deployment.
We are taking help of Redgate tool(new for this) for sql db side management but still feel like we are not in good condition.
Can you please suggest me best architecture/solution or set of tools that can be implemented ?
If you are concerned about the number of merging related activities that are going on then we need to reduce the number of merging activities. This is not going to be an easy thing to change as the culture and expectation within your organisation is currently tuned to produce this result.
You need to move towards a single line, or single branching model. If you are using Git then you can still use many short lived activity branches for Hotfixes or Releases as laid down in GitFlow, but your source line where you add all new code (DEV, MASTER, TRUNK, Main, whatever) should be a single line. As soon as you have feature or version branches you are in the world of merging.
There are a number of engineering activities and practices that you can use to support much of what you are physically doing now in the new model:
Feature toggles - This is your primary engineering solution for merging. If you are working on a single code line, and always have coders check in working code, then feature toggles allow you to ship features that are half done and you don't want folks to see. You hide them.... Now the first thing that you are going to throw out is "but we do database work and you can't do that there", and you would be wrong. Many organisations practice feature toggles and include database work. You need to have a solid and consistent practice of 'additive only' so that you don't break existing work and actually do work to make sure that both a new feature and an old one can coexist. There is work in that, but not as much as merging (in my experience) and not as error or bug prone. One key to remember is to think of them as Feature toggle and not code toggles. If you add a new feature then hide it till its ready. If you are incrementally improving an existing feature then just ship the new functionality. Achieving this WILL be hard and will require courage to implement major cultural changes at your organisation from coders and testers, all the way up to sales and management.
Definition of Done - Which leads to the question of how do we maintain quality in this new world of feature toggles? Think about this: if you have 3 feature teams all working on different functionality and one team decided to reduce their quality but what they have is buggy but good enough, what would be the impact? You are protected from this in a branching model until then end when you make all sorts of compromises to make everyone's mediocre (or just plane crap) code work together. Now we have to have this on every check-in and every release. So what do you need? You need a shared and agreed Definition of Done that represents the quality bar that must be met to ship. Without it you will have chaos. The cultural issue here is that you need everyone, every coder, and every tester, on board with the sacrosanct nature of the DOD. No you cant just compromise just this once as it will have a knock on effect.
Reduce cycle time - Which leads to our ship cycle. You need to 'ship' more regularly. Or more specifically you need to create potentially shippable increments of working software on a regular basis. This support the above in a number of ways, but first and foremost it reduces the amount of work that is under way. This will help reduce the complexity and help teams focus. With what is in effect shorter batch sizes we can get a much more regular adherence to the definition of done and have those touch points of "working software with no further work required to ship it". The side advantages here is that you increase your business ability to change as they can change at the end of each cycle sure in the knowledge that unfinished features are not going to in fact introduce complexity. You also gain the ability to inspect and adapt more frequently. Most companies, on gathering the evidence, find that more than 60% of their software is used little if ever. Lets use the reduced cycle time to get users in front of the software and only focus on building the 40% that they care about. (whoa! did we just get a 60% efficiency gain there?)
There are a number of other supporting practices that it would make a lot of sense for you to adopt to get there and I would probably recommend that you read the Scrum Guide (http://www.scrumguides.org/) and think about how you might start moving towards the goals above.

Parallel Development Branching Strategy

I am faced with with the challenge of needing to maintain two versions of the same product for an unknown period of time. I think I have come up with a workable solution, but I wanted to bounce it off the community for a "sanity check". Currently when a new feature is requested, a branch is cut from trunk, the development is completed in that branch, and that branch is merged back to the trunk. This has been the typical strategy for most places I have worked.
Recently a new branch was cut for a major feature overhaul which will result in changes not compatible with trunk. All of our users will eventually be forced onto this new version but, for a period of time, both versions will exist in the wild. Before I get to in depth, here is a diagram of what my current plan is for branching
Version:Current is what is currently released from. As Version:New is developed, bug fixes will continue to be shipped for Version:Current that will (in all likelihood) need to be merged into Version:New Obviously any new feature / bug fix for Version:New will only need to be merged down into Version:New. Once Version:Current is no longer in the field, Version:New will become the singular trunk. While I think this is workable, I think it can quickly balloon into a management nightmare. My question is: is there a "better" branching strategy that could be followed in my given case, or is this pretty much it?
You should choose a branching strategy that best fits your team and how they work. But what you described is a pretty common way of doing things. I would add that you might want to merge bug fixes from the current version more often than just after the current version isn't being used. If that period is long the branches could stray far enough from each other to cause headaches.
Here's a nice post about common branching patterns

How to backup updated source code files

I am using svn as source control with AnkhSVN 2 for Visual Studio 2010. Very often I am working on one ticket than switching to work on another ticket without completing first one. Is there any quick way to backup updated files for first ticket? This will simplify coding by managing only related changes.
You could
create a patch file for the svn branch you are working on
then revert your changes
work on new ticket and commit
reapply patch
The question I'd be asking is "Does the software build". If it does, check it in to source control. If it doesn't, get it into a state where it does, and check it in to source control.
You don't have to check into the trunk, you can always have a branch that you use for intermediate code which then gets checked into the trunk when you've completed the tickets.
You should use a feature branch for each ticket, and reintegrate each branch into trunk once finished. Just make sure to read the SVN book to understand the best practices when working with feature branches, and particularly to regularly merge from trunk to the feature branch, before finally reintegrate the feature branch into trunk with the --reintegrate option.
You could also create a patch, save it somewhere, revert everything, then start working on ticket2. But it's fragile: you'll forget where your patches are, lose them, or have a hard time applying them because of conflicts caused by the work on the second ticket. And it's also harder to switch from one ticket to another. Feature branches are the most appropriate solution for this, IMHO.

subversion branches with multiple Scrum teams [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 5 years ago.
Improve this question
So we have varying opinions on how to deal with our source in regard to parallel Scrum teams sprints. The background info is we have two 7 man teams working on the same baseline of code in 2 week iterations towards the same product release.
Team A: In one camp we have the preferred approach being: Each team work in its own branch and at the end of each sprint if the changes are acceptable then merge to the trunk. The reason is team A doesn't want to risk having bad code introduced from team B.
Team B: In the other camp we have the preferred approach being: Both teams work in the trunk, check in small working changesets early and often and rely on the continuous integration build to prevent and identify broken builds early. Team B does not want to perform large merges every few weeks.
Thoughts? Is either approach more valid than the other? Is there a 3rd approach neither team has recommended?
Edit: Just to clarify both teams want CI, but Team A would have a multiple nightly builds, one for each branch. Team B is in favor of a single build on the single branch.
Thanks~
In any normal case with people involved the merging will soon be postponed "until we've stabilized this one thing". This one thing rarely gets stabilized very soon, so the branches start diverging. It's not bad in the beginning, but soon you'll notice that you'll have merging and stabilizing sprints going on. This is what's happened in all projects I've seen branches being used for something like this.
Of the two options above, I would suggest biting the bullet right away, and using option B. It will generate some overhead, but at least people end up merging their changes immediately when they still remember what and why they are doing things. In a couple of weeks, it'll be much harder.
Solution C could be to extract a third project with the common code for both teams, leaving the actively developed parts for each team to modify at will. The shared code base should hopefully be more stable. Don't know if such a solution would work in your case.
Team B. You're introducing overhead -- the large merges -- for the purpose of avoiding a hypothetical situation ("bad code") that won't occur often, and if it does, will cause less work to correct than all of the merges will accumulate. Also, these merges themselves may introduce errors.
In short, you're adding more work to deal with an unproven problem which in the end might cause yet more work.
On the other hand, if team B (or A for that matter) is checking in bad code, the place to catch it is in the CI, and if they are introducing bad code, that's a management problem, not a procedural problem.
Why not let Team B work on the trunk and Team A on a branch? Everyone gets what they want! (just kidding: this is really no different from approach A)
Seriously, though, you are trying to choose between "work in silos" and "have only one huge team" (or more diplomatically: "stable workspaces" and "proactive collaboration"). I would suggest a hybrid approach. But I also agree with Kai Inkinen's idea to refactor the codebase into shared vs team-specific code. Your teams are large enough that the code they generate will be significant: more components makes sense and might avoid this issue altogether. Assuming you don't have that option:
Some disadvantages of A:
(think: what's the trunk going to look like at the end of week 2? How confident will you feel about that code?)
encourages "big crunch" merges near the end of a sprint (in fact you are planning on it!). Expect conflicts, duplicated effort, and sub-optimal code structure after the merge.
prevents a team from taking advantage of good changes made by the other team
at the end of the sprint: who gets to merge to trunk first? That team might as well have been on the trunk all along!
Some disadvantages of B:
(think: Team B wants to share changes among themselves that aren't good enough for the trunk yet. You know this will happen, or else why are there two teams at all?)
discourages frequent checkins
encourages "working copy transfers"
whenever someone from Team B "breaks" the codebase, Team A will say "I told you so"
My suggested approach:
have both teams use separate branches, to encourage frequent checkins for each team. Checkins are good. (If a team (A) wants to keep their code protected, they will find ways to achieve the same ends even if you don't give them a branch, i.e., working copy transfers: "hey Kim, I know it's not perfect, and you haven't checked it in yet, but can you send me your fix for that file?")
have both teams "deliver" to trunk often: not just at the end of a sprint. Deliver each "story" as it is completed.
have both teams "sync" from the trunk often (ideally after every "delivery" from the other team). This, in conjunction with the action above, keeps merges as small as possible and should make the end of the sprint completely painless. Team A may resist this; they should be encouraged to "respond to change" in the code -- they'll have to merge eventually.
http://svnbook.red-bean.com/nightly/en/svn.branchmerge.basicmerging.html#svn.branchemerge.basicmerging.stayinsync
With this approach, teams will be rewarded (with comparatively easy merges) for checking in often and for delivering changes to the trunk as soon as possible. Both of these are good things.
I should also point out that with something like git/Mercurial, you have a bit more flexibility.
I'd go for continuous Integration. There are very few reasons to do otherwise. Check this link by Martin Fowler for an excellent explanation of the advantages of it.

Categories

Resources