Merging feature branches for QA with TFS (part 2)

In my previous post, we had a look at the problem : how to merge sibling branches with TFS, minimizing the number of conflicts. Yes, the number of conflicts you’ll get depends on the “technique” you’ll be using :

  • TFS baseless
  • Shelvesets
  • Other tools?

All your base are belong to TFS

But first, let’s answer the real question : what should be the base exactly for our 3-way merge?

Let me recap the scenario:

  • branch dev A from Main
  • Main evolves
  • branch dev B from Main
  • Main evolves
  • Both dev A and dev B have evolved as well
  • As a best practice, we integrate latest Main content into dev A and dev B
  • Now we want to test dev A and dev B with a single test campaign, we want to merge them all together, but leave Main intact
  • branch QA from Main, from the version that as been merge to dev A and dev B

     

    SNAGHTML9efd54_thumb

    The base we need is the latest version of Main that has been merged into dev A and dev B. You must have merged the same version of Main into both branches, of course. The QA branch needs to be branched from the same version of Main as well. These conditions are common practice and should not be a problem.

    Here the base is not the most recent common ancestor, or it depends on what you call an ancestor. It is easy to understand : I want to merge “the diff between latest Main and dev B” into dev A. And dev A evolutions must be compare to the latest Main version that has been merged as well.

    External tools

    It is not possible to choose your base when you merge with TFS – btw, I’d be curious to know which VCS let you choose a custom base when merging.

    So let’s perform our merge “outside of TFS”. Is that bad? In the end, you won’t have any merge history between those branches, but you we really need that? What looks important to me is to keep the dev history on the dev branches for a little while, for reference, and that the QA branch future merge into Main remains easy.

    3-way folder merge procedure

    Use a local Workspace that maps the QA branch. Map also in any workspace dev A, dev B, and the Main branch (the version your merged into dev A and dev B if ever Main has further evolved).

    Merge dev A into QA with a baseless merge (easy when using VS 2012 and TFS 2012 remember last post?). Take the Source version for every conflict (easy merge isn’t it?), you can select all conflicts and choose the option.

    Let’s now use KDiff3, and its wonderful folder 3-way merge feature :

    image_thumb

    KDiff3 is ugly, but the best merge tool I know at the moment. It is just quite clever and has nice features:

    SNAGHTMLface99_thumb

    Note that you will also loose the renames during the process, which will break the history of the renamed files. You can perform the renames in the Source Control Explorer if you like (do this before resolving the merge, and rescan afterwards).

    When finished, the local workspace (new with TFS 2012) is your friend, it will detect what has been changed, added and deleted in the Pending Changes window:

    image_thumb1

    The final tradeoff is :

    • You have less conflicts than when using TFS (even with baseless merge as explained in the previous post)
    • You break the chain of history, partially
      • In my eyes dev history is not very important, I’d be glad to debate on this. I mean not as important as maintenance history!

    If you have a large code base to merge, that should be worth it! Happy merging Smile

  • Merging feature branches for QA with TFS (part 1)

    or How to merge sibling branches with the least conflicts as possible

    In this post series I’ll propose a simple procedure to merge feature branches among them without merging into Main. This is particularly useful when you want to test the features altogether (or by groups of features) without bringing yet all the content onto the Main branch. If you have a large code base, you also want to avoid conflicts as much as possible.

    image_thumb3

    Team Foundation Version Control (TFVC) is a great version control system as long as your respect the branching and merging guide produced by the ALM Rangers. You can handle pretty complex situations and have branching trees such as this:

    image_thumb

    © Visual Studio ALM Rangers

    All is well under control as long as you merge between branches that have parent-child relationship. Should you need to merge between any pair of branches, you can always :

    • Use a TFS “baseless” merge
    • Use a Shelveset (code stored at server side in a separated storage that you merge onto anything)

    TFS baseless merges (really baseless?)

    To achieve a baseless merge you have to type a command like:

    tf merge /baseless $/Project/SourceBranch $/Project/DestBranch /recursive

    More on the merge command here. That will create a merge relationship between two branches with no obvious connection (read parent-child). Now the merge relationship is established, subsequent merges are then managed by TFS UI (Visual Studio) and history engine. Good.

    But still, this king of merge is not very satisfactory because TFS is not very good at picking the most recent common ancestor “in a clever way”. Don’t laugh too fast, Git is not very clever either at picking up the best base.

    Here is the best scenario you can get with TFS when merging sibling branches: the base is the origin of the branch you are merging from. When merging with the command line, you should use the /version parameter to select only wanted changesets, don’t take the changeset that created the branch, or the whole branch will be a conflict. Take only the changesets your are interested in, as explained by Buck Hodges here. In this precise case (schema below), I selected all the changesets but the one that created the branch dev B, in order to merge its contents into dev A.

    SNAGHTML2ce926_thumb

    I’m lying, the UI can do it!

    Ok, sorry, but since this feature is new in TFS 2012, don’t blame me too much if put in my article a bit of TFS history!

    So with TFS 2012, it is now very easy to perform baseless merges in the UI. You can edit manually the target branch in the merge wizard. Then choose to pick the changesets you want:

    image_thumb6

    Then select the changesets you want to merge (without the branch creation):

    image_thumb9

    Made with Brien Keller VS 2012 VM Smile

    Using Shelvesets

    The trick is to use the TFS power tools to unshelve your content to a different branch. The command will “translate” server paths to another location (that you must have mapped in your Workspace):

    tfpt unshelve /migrate /source:$/Project/SourceBranch /target:$/Project/TargetBranch

    They are very handy but don’t expect a top notch merging experience regarding to the conflicts that are generated. Before TFS 2010 SP1 baseless merges improvements, they were kings for moving fixes from branch to branch. Now, that baseless have improved, I’m not so sure, I go “baseless” more and more.

     

    Next post I’ll talk about a solution, there is no magic, we’ll use external tools to achieve our goal. Till then, just think, what base is the best in such a case?

    Stay tuned!

    A small guide to editing your TFS 2012 build templates

    TFS 2010 and later versions use Workflows (WF) at the core of their mechanics. Workflows are intuitive to edit, and powerful as any high level scripting language can be. However, in the context of Team Foundation Build, they need a particular set up with Visual Studio if you want a smooth editing experience. This post will hopefully help you in setting up a cohesive environment in order to edit your build process templates. This is just a proposal, this is the way I prefer setting it up, feel free to keep whatever you want here.

    Team Project organization

    I advise to use a “test” Team Project and edit your templates there. Why?

    • Test your build in the test Team Project and when it’s operational, copy the file(s) into your production Team Project. You don’t mess with a renamed or temporary template , nor produce unwanted changeset noise in the production Team Project. Very simple.
    • Because you may need to use another build controller, but we’ll discuss that later.

    So we’ll need a Visual Studio solution and project in order to edit the Xaml template properly. Where shall we store that Solution?

    Solution setup

    Answer: not far from the build process templates : in a subfolder!

    SNAGHTML1632c6bc_thumb

    All you need actually is a regular class library project, target Framework 4.5 for TFS 2012 builds:

    clip_image002_thumb

    Notice there is no Xaml file at the project level, this is because they are added into the project « As Links », directly from the parent folder :

    SNAGHTML16363cd5_thumb

    You can distinguish linked files from other in your projects because a of the tiny arrow on their file icon:

    SNAGHTML16389cee_thumb

    When I checkout the the Xaml template file, it is checked-out from its original location, this is fine.

    We want to use a project for multiple reasons :

    • Compiling will help us to removing errors in the workflow file and it checks the references
    • It is necessary if you have custom assemblies, and frankly, you *will* have some at some stage. If you don’t go grab the latest Community TFS Build Extensions and you’ll have *very* helpful activities for your builds
    • We want “drag and drop” editing, if we have custom assemblies, this is the best way to do it

    In order to compile nicely, you’ll need to add several references, this is where it gets not that obvious, nearly tedious, but you’ll need to do this only once in your life, so that’s ok 😉

    References setup

    clip_image005_thumb

    Some of the are not easy to locate, here they are:

    • Microsoft.TeamFoundation.TestImpact.BuildIntegration : %ProgramFiles%\Microsoft Visual Studio 11.0\Common7\IDE\PrivateAssemblies\Microsoft.TeamFoundation.TestImpact.BuildIntegration.dll
    • Microsoft.TeamFoundation.TestImpact.Client : %windir%\assembly\GAC_MSIL\Microsoft.TeamFoundation.TestImpact.Client\11.0.0.0__b03f5f7f11d50a3a\Microsoft.TeamFoundation.TestImpact.Client.dll (this is bad, we should *never* *ever* have to reference something in the GAC, hope this will be solved in next version)

    Now you can edit the worfklow and compile it.

    clip_image007_thumb1

    The development cycle of builds (aka the everyday life of the build master) consists in:

    • Check-out the workflow template file
    • Modify the workflow file
    • Check-in the worfklow file
    • Launch a build that you have set up with *this* workflow file

    Adding custom assemblies

    We are now set up for throwing in some custom assemblies. First, add the assemblies (and their associated .pdb) in an “Assemblies” folder, create it if necessary, just under the BuildProcessTemplates folder. What is important here is that this folder is configured in the properties of your Team Project build controller (Builds -> Actions -> Manage Build controllers…)

    clip_image008_thumb

    I’ve added my custom activities assemblies and their dependencies, and the Community TFS Build Extensions assemblies:

    image

    Simply add the assemblies that contain the activities you’ll need as regular references in your class library project. For a starter you’ll want TfsBuildExtensions.Activities.dll. I also added my custom activities library (no need to reference the dependencies).

    The need for a separate build controller

    If you are serious with builds (if you have many production builds you can’t afford to interrupt for with your developments), you’ll want a separate build controller. It is easy to deploy.

    When you check-in some assemblies in the custom assemblies folder, the build controller restarts, and cancels the builds in progress. This is where it gets handy to have a separate controller for testing purposes. And be aware of your production build deployment timing.

    NB : checking-in the Xaml files does not restart the controller.

    Toolbox setup

    In order to drag and drop custom activities from the Toolbox, you can do the following:

    • Create a new Tab in the Toolbox
    • “Choose items” and browse up to the assembly that contains the activities you want
    • They now appear in the Toolbox, you can drag them into your build workflows

    Without the project references to the corresponding assemblies, drag and drop would not work…

    Finally, all is set up, you should be able to edit your builds the easy way. Enjoy! Smile