Cross-Branch merging in TFS? - version-control

Is it possible to merge to a branch that is not a direct parent or child in TFS? I suspect that the answer is no as this is what I've experienced while using it. However, it seems that at certain times it would be really useful when there are different features being worked on that may have different approval cycles (ie. feature one might be approved before feature two). This becomes exceedingly difficult when we have production branches where we have to merge some feature into a previous branch so we can release before the next full version.
Our current branching strategy is to develop in the trunk (or mainline as we call it), and create a branch to stabilize and release to production. This branch can then be used to create hotfixes and other things while mainline can diverge for upcoming features.
What techniques can be used otherwise to mitigate a scenario such as the one(s) described above?

I agree with Harpreet that you may want to revisit how you you have setup you branching structure. However you if you really want to perform this type of merge you can through something called a baseless merge. It runs from the tfs command prompt,
Tf merge /baseless <<source path>> <<target path>> /recursive
Additional info about baseless merges can be found here
Also I found this document to be invaluable when constructing our tfs branching structure
Microsoft Team Foundation Server Branching Guidance

tf.exe merge /recursive /baseless $/TeamProject/SourceBranch $/TeamProject/TargetBranch
MSDN: How To: Perform a Baseless Merge in Visual Studio Team Foundation Server

You may want to revisit your branching strategy. How do you get production branches? Are you merging all code from development branches, regression testing and then creating a production branch for fixes? Or are you developing on the trunk and then creating production branches to stabilize and release from? The second way creates problems of the type you're describing. If you are using the first approach -- the trunk is supposed to be only for things that have been built on branches tested and then merged you will run into this much less often. Under that approach if you're still having this problem it may be because your development effort is very large and you may need a relatively complex branching strategy with layers of branching and promotion.

AFAIK you can do this as long as the branches were created off of the same original folder.
trunk/
branches/
-/feature1 (branched from trunk)
-/feature2 (branched from trunk)
If you do this then you should be able to merge between feature1 and feature2 as well.
Though my branching/merging experience with TFS leaves me wanting more. I wish we just had SVN.

Yes, you can do a baseless merge, but only from the command line (tf.exe).

TFS will allow you to merge with a branch that is not a parent/child - these are called baseless merges. See these links:
From MSDN
From the TFS Team via CodePlex
We typically do major or destabilizing changes on a development branch. If close to a major release of one of our products nearly all changes will be done on a branch.

I am far from a TFS expert, but I think you can merge siblings, and I think it is not a baseless merge.
We branched off our main branch (branch name "main") for a feature (branch name "feature"), then I needed some of the work in a branch that was also branched off the main branch (branch name "dev"). I would consider feature and dev branches to be siblings as they both came from the same parent. I merged feature to dev and all files (14000) were marked as merge, some were marked as merge,edit. I could not cancel (visual studio would just hang), so I accepted the merge. Then I merged dev to main, then I pulled main to feature, and again 14000 files were marked for merge. I was really upset, and afraid this would continue.
At this point we did a test project. We set up main, then branched dev and feature from main. We repeated the above steps with the same results. Once we completed the merge from main to feature, all future merges only showed the edited files.
After our little test I completed the merge from main to feature. And just like the test our merges now only show the edited files. We can go dev to feature, feature to main, main to dev, etc.
I did notice when branching all file dates were modified. Maybe this is an issue?

Related

Managing code in Mercurial: how to revert individual files, "tag" it and be able to maintain it

Update: We ended up using a process very much like this schema (thanks to neuro for the link). We massaged out repository into a state where default is stable (and has the same code as our production environment), we have a dev branch, feature branches for new stuff and use release branches for releases. All seems to be working perfectly.
Backstory
Our team has recently switched from using SVN (using ToroiseSVN Windows client) to Mercurial (using TortoiseHg Windows client) for version control. We have successfully exported our SVN repository and imported it into a Mercurial repository.
We now have a Mercurial repository where we can see the entire history of revisions (changesets in Mercurial).
How we did it in the old days
Life was simpler in the old days; our development process was not really multi-stream like it is now. The trunk was used to hold all code - even changes that were still in-flight (as long as it didn't break the trunk). When it came to managing releases with SVN, we would checkout the trunk (which holds all code), revert the individual changes we didn't want as part of the release, and create a tag for it.
Cherrypicking the code we want with SVN was easy. Bug-fixing previous releases and ensuring it was part of the trunk was simple too.
What we are doing now
In Mercurial, we need to be able to get a snapshot of the "trunk" (default in Mercurial) with individual changes reverted out. We can do this using hg revert.
To snapshot this, we have created a "named branch" - let's call it Build-4.0.1 for now.
Where the challenge arises
Development continues on default as normal when a bug is found in Build-4.0.1. Let's assume the bug is in one of the reverted files. We change the code from the branch for Build-4.0.1, create a new "named branch" (Build-4.0.2) and want to merge it back into default without pushing the reverted code over the top of newer code. How can we accomplish this?
Alternatively, is there a better workflow for managing the releases and our code in Mercurial? I quite like the look of this wonderful SO answer on managing release branches, although I am not sure how we can transition to it from the state we are in now (with in-flight stuff in default).
Note: I have looked at the Transplant extension, but haven't used it yet - could it be part of the solution to this challenge?
Well, to begin with, your use of revert seems strange to me. Usually it is used to revert modifications done to the working copy back to the version of the repository.
The usual way to get the working copy to some point backward is to update :
hg update -r 1234
from there, you can tag, modify, commit, etc.
To merge back you only have to merge your release branch to the default branch. It will work like a charm, unless it is to different/old a release.
Transplant works fine, but do something a bit different from merge : it take your changeset as a "diff" and apply it as a new modification.
To manage your releases, you can look this other answer (by me) :
How to use mercurial for release management?
What we use is a clone / main branch that holds the most stable version, which is released at some points. On this clone : branch, we can fix critical bugs (hotfix). In parallel, we use a dev clone / branch to develop. The hotfixes are merge as soon as completed from stable to dev. When the current development is done, we merge the dev on stable / default.
This schema is pretty good to understand things :)
Good luck !
Going through all the changes and taking out the ones you don't want is not a common way of creating a release, to put it mildly. The Common Branching Patterns section in the SVN book suggest some more popular work flows:
release branches: create release branch from unstable trunk, fix bugs to stabilize it, cherry pick bug fixes between them while the branch is in maintenance mode.
feature branches: keep the trunk stable and ready for release by only merging in the feature branches that you want
The second one is probably the best fit here, because it gives you a place to put experimental or risky changes until you feel confident about them - these are the changes you would have reverted before a release in your old workflow.
Both of these branching patterns should carry over just fine to mercurial. In case you go for the first approach, note that mercurial (since 2.0) now has a graft command, you no longer need the transplant extension.

Branch-per-feature workflow using Mercurial

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.

Branching and Merging Strategies

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.

Please suggest a better workflow in Mercurial

I'm new to Mercurial and what I'm starting to realize is that my basic workflow may not be the most efficient way of working because I perform commits so frequently and for feature improvements that are so small that when I need to find some earlier step to revert to, it is extremely difficult.
Here's what I do after I have a project set up in Mercurial and have already completed my first commit.
Make some changes to a file and get it to a state where a small improvement is working
hg commit -m "improvement A works"
Make some changes to the same file and get it to a state where the next minor improvement is working.
hg commit -m "improvement B works"
Check whether all of the minor improvements add up to a single minor feature working correctly.
hg commit -m "feature A works"
If I find a mistake that was made in "improvement A", I open up history (with the Netbeans Mercurial visual plugin) and copy and paste some of the code back into my current version and start again from there.
This doesn't seem like a good system - I would appreciate any suggestions.
I agree with Jon that branches are the solution, but I would create branches for features rather than for the individual improvements that make up a feature. The workflow pattern would then be this:
Create branch for feature A.
Complete work for improvement A and commit.
Complete work for improvement B and commit.
When the feature seems to be working, merge the feature A branch back into trunk.
If you find a mistake in an improvement A of feature A, instead of starting over, you switch to the feature A branch and do the following:
Fix improvement A and commit.
Merge the feature A branch back into trunk.
You could isolate the changes for the improvements into branches maintaining a stable trunk.
Take a look at Branch wiki page.
Workflow pattern would be:
Create branch for improvement A
Complete work for improvement A and checkin
Test changes and merge back into trunk if successful
Create branch for improvement B
Complete work for improvement B and checkin
Test changes and merge back into trunk if successful
If you find a mistake you can abandon the branch (or correct the bug in the branch prior to merging back into trunk).
I disagree with the branches approach. If no parallel development is needed, why add the complexity of branches? There's nothing wrong with small 'checkpoint' commits. Tags can be used to point to important commits, which might be more clear.

Branching Strategies [closed]

As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 11 years ago.
The company I work for is starting to have issues with their current branching model and I was wondering what different kinds of branching strategies the community has been exposed to?
Are there any good ones for different situations? What does your company use? What are the advantages and disadvantages of them??
Here is the method I've used in the past with good success:
/trunk - bleeding edge. Next major release of the code. May or may not work at any given time.
/branches/1.0, 1.1, etc. Stable maintenance branches of the code. Used to fix bugs, stabilize new releases. If a maintenance branch, it should compile (if applicable) and be ready for QA/shipping at any given time. If a stabilization branch, it should compile and be feature complete. No new features should be added, no refactoring, and no code cleanups. You can add a pre- prefix to indicate stabilization branches vs maintenance branches.
/branches/cool_feature. Used for highly experimental or destructive work that may or may not make it into trunk (or a maintenance branch). No guarantees about code compiling, working, or otherwise behaving sanely. Should last the minimum time as possible before merging into the mainline branch.
/tags/1.0.1, 1.0.2, 1.1.3a, etc. Used for tagging a packaged & shipped release. Never EVER changes. Make as many tags as you want, but they're immutable.
Our repository looks like:
/trunk
/branches
/sandbox
/vendor
/ccnet
/trunk is your standard, bleeding edge development. We use CI so this must always build and pass tests.
/branches this is where we put 'sanctioned' large changes, ie something we KNOW will make it into trunk but may need some work and would break CI. Also where we work on maintenance releases, which have their own CI projects.
/sandbox each developer has their own sandbox, plus a shared sandbox. This is for things like "Lets add a LINQ provider to our product" type of tasks that you do when you are not doing your real work. It may eventually go into trunk, it may not, but it is there and under version control. No CI here.
/vendor standard vendor branch for projects where we compile but it is not code that we maintain.
/ccnet this is our CI tags, only the CI server can write in here. Hindsight would have told us to rename this to something more generic such as CI, BUILDS, etc.
One branch for the active development (/main or master, depending on the jargon)
One branch for each maintenance release -> it will receive only really small fixes, while all major development goes to /main
One branch for each new task: create a new branch to work on every new entry on your Bugzilla/Jira/Rally. Commit often, self document the change using inch pebble checkins, and merge it back to its "parent" branch only when it's finished and well tested.
Take a look at this http://codicesoftware.blogspot.com/2010/03/branching-strategies.html for a better explanation
The first thing: KISS (Keep it simple stupid!)
/branches
/RB-1.0 (*1)
/RB-1.1 (*1)
/RB-2.0 (*1)
/tags
/REL-1.0 (or whatever your version look like e.g. 1.0.0.123 *2)
/REL-1.1
/REL-2.0
/trunk
current development with cool new features ;-)
*1) Keep version maintainable - e.g. Service Packs, Hotfixes, Bugfixes which may be merged to trunk if necessary and/or needed)
*2) major.minor.build.revision
Rules of the thumb:
The Tags folder need not to be checked out
Only few coding in release branches (makes merging simpler) - no code cleanup etc.
Never to coding in tags folder
Never put concrete version information into source files. Use Place-holders or 0.0.0.0 which the build mechanism will replace by the version number you're building
Never put third party libraries into your source control (also no one will add STL, MFC etc. libraries to SVN ;-))
Only commit code that compiles
Prefer using environment variables instead of hard-coded paths (absolute and relative paths)
--hfrmobile
We branch when a release is ready for final QA. If any issues are discovered during the QA process, the bugs are fixed in the branch, validated and then merged to the trunk. Once the branch passes QA we tag it as a release. Any hotfixes for that release are also done to the branch, validated, merged to the trunk and then tagged as a separate release.
The folder structure would look like this (1 QA line, 2 hotfix releases, and the trunk):
/branches
/REL-1.0
/tags
/REL-1.0
/REL-1.0.1
/REL-1.0.2
/trunk
We use the wild, wild, west style of git-branches. We have some branches that have well-known names defined by convention, but in our case, tags are actually more important for us to meet our corporate process policy requirements.
I saw below that you use Subversion, so I'm thinking you probably should check out the section on branching in the Subversion Book. Specifically, look at the "repository layout" section in Branch Maintenance and Common Branch Patterns.
The alternative I'm not seeing here is a "Branch on Change" philosophy.
Instead of having your trunk the "Wild West", what if the trunk is the "Current Release"? This works well when there is only one version of the application released at a time - such as a web site. When a new feature or bug fix is necessary a branch is made to hold that change. Often this allows the fixes to be migrated to release individually and prevents your cowboy coders from accidentally adding a feature to release that you didn't intend. (Often it's a backdoor - "Just for development/testing")
The pointers from Ben Collins are quite useful in determining what style would work well for your situation.
Gnat has written this excellent break down on the various bits of advice your can find on branching strategies.
There's not one branching strategy, it's what works for:
Your team size
Your product and the lifecycle periods
The technology you're using (web, embedded, windows apps)
Your source control, e.g. Git, TFS, Hg
Jeff Atwood's post breaks down a lot of possibilities. Another to add is the concept of promotion (from Ryan Duffield's link). In this setup you have a dev branch, test bracnh and release branch. You promote your code up until it reaches the release branch and is deployed.
We currently have one branch for ongoing maintenance, one branch for "new initiatives" which just means "stuff that will come out sometime in the future; we're not sure when." We have also occasionally had two maintenance branches going on: one to provide fixes for what is currently in production and one that is still in QA.
The main advantage we've seen is the ability to react to user requests and emergencies more rapidly. We can do the fix on the branch that is in production and release it without releasing anything extra that may have already been checked in.
The main disadvantage is that we end up doing a lot of merging between branches, which increases the chance that something will get missed or merged incorrectly. So far, that hasn't been a problem, but it is definitely something to keep in mind.
Before we instituted this policy, we generally did all development in the trunk and only branched when we released code. We then did fixes against that branch as needed. It was simpler, but not as flexible.
The philosophy that we follow at work is to keep the trunk in a state where you can push at any time without drastic harm to the site. This is not to say that the trunk will always be in a perfect state. There will of course be bugs in it. But the point is to never, ever leave it broken drastically.
If you have a feature to add, branch. A design change, branch. There have been so many times where I thought, "oh I can just do this in the trunk it isn't going to take that long", and then 5 hours later when I can't figure out the bug that is breaking things I really wished that I had branched.
When you keep the trunk clean you allow the opportunity to quickly apply and push out bug fixes. You don't have to worry about the broken code you have that you conveniently branched off.
For Subversion, I agree with Ryan Duffield's comment. The chapter he refers to provides a good analyses on which system to use.
The reason I asked is that Perforce provides a completely different way to create branches from SVN or CVS. Plus, there are all the DVCSs that give it's own philosophy on branching. Your branching strategy would be dictated by which tool(s) you're using.
FYI, Svnmerge.py is a tool to assist with merging branches in SVN. It works very well as long as you use it frequently ( every 10-30 ) commits, otherwise the tool can get confused.
No matter which branching pattern chosen, you should try to keep your branches in a binary tree form like this:
trunk - tags
|
next
/ \ \
bugfix f1 f2
/ \ \
f11 f21 f22
Child nodes should only merge with the direct parent.
Try ur best to merge only the whole branch with the parent branch. never merge subfolders within a branch.
You may cherry pick commits when needed as long as you only merge and pick from whole branch.
The next branch in the above figure is only for illustration, you may not need it.