Restructure branches in a multiple tream project environment - tfs

We want to restructure our code which is splitted in many team projects.
The idea is to create a new team project and move all branches to this new Repository dedicated to store code (TFVC not Git).
We need to only move source code, workitems are not concerned.
Old Tree structure:
-TeamProject1
-ProductX
-Dev
-Main
-Release 1.0
-ProductY
-Dev
-Main
-Release 1.0
-Release 2.0
-TeamProject2
-ProductZ
-Dev
-Main
-Release 1.0
Desired Tree Structure :
-NewTeamProjectForCode
-ProductX
-Dev
-Main
-Release 1.0
-ProductY
-Dev
-Main
-Release 1.0
-Release 2.0
-ProductZ
-Dev
-Main
-Release 1.0
How can we achieve this without loosing history and current not merged changeset between branches.
We have tried to move branches between team projects but folder history is lost too. Relation between branches are strange because we cannot perform merges between branch (dev>main or release>main) only the move changeset is present.
Thanks,
Eric

So basically you want to keep all 3 products in a single Team project. I would follow below approach.
Create branch from ProductZ-TeamProject2 to Productz-TeamProject1
Convert ProductZ into a Folder. You can easily do this by right clicking the branch
Rename TeamProject1 to NewTeamProjectForCode
Delete TeamProject2 TP

Related

Is it possible to move folders from one set of TFS branches into another and preserve pending changes?

At present, our TFS (TFVC, not git) project contains a folder that hosts the entirety of our product. This folder contains three branches (Dev, Main and Release) each of which in turn contains many different sub projects. We are attempting to restructure so that distinct components are contained within their own branching structure.
Question: Is it possible to move a folder that is contained under a branch (not the branch itself), along with its corresponding folder in the other branches into a new TFS project while maintaining the relationship and status of any unmerged changesets?
Here is a diagram of our desired end result:
We want to move each of the "Project 1" folders (left side) into their own branching structure (right side), but we need any unmerged changesets to "come along". That is to say that if we attempt to Merge from Dev to Main in the new structure we are presented with a list of the (pertinent) changesets that were not merged in the old structure.
Is this possible? If so, what series of tf/tfvc commands would we need to pull this off? I've gone deep into google, but came up short--either because I don't know how to describe this in a search friendly way, or its simply impossible.
What I've tried:
Direct Move/Rename each of the folders into the new project (pre-creating each of the target Dev/Main/Release branches)
The unmerged changesets were lost.
All I get is a single "move/rename" changeset that appears in the unmerged list for the new branches. Merging that causes everything in the target branch to be overwritten (ie. release branch's files are now the same as dev).
On the +side, pending shelvesets "auto-follow" when unshelved
Branch each folder, into the new structure (this time without pre-creating the target branch folders)
This created three branches that weren't related to each other.
I was able to solve that by doing a baseless merge between them (tf merge /baseless /recursive) and taking target branch files when conflicted; followed by re-parenting the branches. (As explained here)
Unlike the above, the files themselves ended up correct (nothing was overwritten).
The unmerged changesets were lost.
Shelvesets get unshelved to the original location
If it matters, we are willing to lose overall history if that's the only way to solve this. Preferably we'd keep it, even if it meant storing a 'deprecated' copy of the original somewhere. I'm not so concerned about shelvesets "following" their source either... we only have two that would be impacted and we can handle those manually if needed. We are using on-prem TFS 2018.
Edit: in response to an answer that was posted and then deleted:
I'm not looking to move the branches, but to extract folders deep inside them into their own corresponding branch structure without losing pending changes. I only show two levels above, but in reality they are a lot deeper. I am able to tf rename an entire branch in a sandbox and get expected results... but renaming branches is not what I'm trying to do, and moving the folders gives unexpected results.
It seems like you can achieve what you are wanting by having merge relationships from both the new Dev, Main, Release branches and the old project folders. I think you can do a variation of the second "route" you tried above.
Branch the old Release > Project[x] folder into the new Project[x] > Release branch
Branch the new Project[x] > Release Branch into the new Project[x] > Main branch
Merge (baseless) the old Main > Project[x] folder (specifying the changeset that
the old Release was branched from) into the new Project[x] > Main branch
Branch the new Project[x] > Main Branch into the new Project[x] > Dev branch
Merge (baseless) the old Dev > Project[x] folder (specifying the changeset that
old Main was branched from) into the new Project[x] > Dev branch
Repeat for the other Projects
The goal is to create the new branch merge relationships (by branching [new] Release to [New] Main and then [New] Main to [New] Dev. At this point the merge relationship has been established and all branches are in the same state. Then we baseless merge the [old] to the [new] for main and Dev. For Main we want to dot he baseless merge on the state where Main and Release are the same (in the old). For Dev we want to do the baseless merge on the state where Dev and Main are the same (in the old). Then additional merges may occur from [old] to [new] and these should be detected as merge-able changes from [new] to [new] similar to how they are in [old] to [old]
You will loose the shelve sets (but can always unshelve in the old location, checkin, and merge to the new) but history should be retained as long as the old project isn't destroyed.

In TFS, Cannot Reparent a folder that was converted to a branch

We have a TFS branch structure like Main > Integration > Several Branches under this.
The problem is that I created a folder 'feat-IIS6toIIS7Migration'outside the above hierarchy when I started coding. After finishing coding I converted the folder to a branch.
But the new branch has no parent and I want to put it under Integration. It seems that its impossible to do this in TFS, since when I try to re-parent I get an empty list of possible parents. Is there a way to put the new branch under Integration?
If you want the folder to appear under the integration branch then you can just move it (right click in Source Control explorer and select move).
$/Root/Integration
$/Root/feat-IIS6toIIS7Migration
becomes
$/Root/Integration/feat-IIS6toIIS7Migration
When the integration branch gets merged with either main or your development branches the folder will be added to those branches as part of the merge.
If you want to give the feat-IIS6toIIS7Migration folder a branching relationship with integration then you need to perform a baseless merge. Note you should only do this if the feat-IIS6toIIS7Migration folder is a full replication of the integration branch.
In TFS / VS 2012 you can perform a baseless merge from the GUI.
Right click on the integration branch in Source control explorer and
select merge. This will be your source branch.
In the target branch dropdown you won't be able to see the
feat-IIS6toIIS7Migration folder.
Select "Browse" and then navigate to the location of the
'feat-IIS6toIIS7Migration' folder.
Keep hitting next until VS performs the merge.
I would expect there to be a fair few merge conflicts and you'll need to resolve a lot of them manually.
In the future it would be better to create the branch for your development before you start work, then you can take regular merges so you don't have a big merge at the end of your development.

TFS Branch Merge on different branches

I've the following structure on TFS:
$Base
- $Dev Branch 1
- $Integration Branch 2
I would like to merge the changes on Dev Branch 1 to Integration Branch 2 so that build guys can kickoff Hudson build of this Integration Branch.
I'm using Visual Studio 2008 Team, and when I try to merch Dev Branch1 I can only see Base on Target Branch drop down.
Could anyone please advise how and if it's possible to merge between Dev and Integration branches above.
Thanks
There are a couple of ways to do this but neither are that great. For the first method you will need to install the TFS 2010 power tools
Use a shelve set. Start the merge from dev to base, resolve any conflicts. Do not check in the merge, instead shelve the changes. Then from the command line use tfpt unshelve "my shelve set" /migrate /source:$/teamProject/dev /target:$/teamProject/integration. This will migrate the shelved changes to the integration branch without having to commit the changes to the base branch.
Perform a baseless merge between dev and integration. You can do this by using the command tf merge $/teamProject/dev $/teamProject/integration /baseless /recursive once the baseless merge has established a branching relationship then you can do further merges through the UI. Be warned though that a baseless merge won't know about any files or folders that have been renamed or moved so you will need to make sure you take this in to account.
Personally I'd go for option 1 if it's a one time thing. If it's going to be something you think you'll need to do regularly then I'd do the baseless merge when all 3 branches are in sync I.e. just after you've merged from dev to base to integration. This should minimise any issues with the baseless merge.
You might also want to take a look at your branching strategy so that you don't need to perform complex merging operations very often. If you use an integration branch then it should have a direct relationship with any branches you need to integrate. Check out the ALM rangers branching guidance.
You can only merge to where the branch was created from. You would have to merge from Dev to Base and then again from Base to Integration.
If you want to merge from Dev to Integration directly then your Integration branch should be created as a branch from Dev not Base.

Is there an easy way to create a patch in one branch and then apply it to another branch in TFS 2010?

I have two service pack branches coming out of one ‘main’ branch in TFS 2010. I want to ‘transport’ a change set from one service pack branch to another without promoting it through the main branch and without doing baseless merge.
The ‘main’ branch contains a conflicting change set that I don’t want to merge with the change set from the first service pack branch. I want the second service pack branch to receive that change set in unmodified form.
The baseless merge will create a link between two branches. I don’t want such link to appear in the merge dialog.
Is there an easy way to create a patch in one branch and then apply it to another branch? Something like in Subversion.
P.S. I’m not going to change branching structure to accommodate this one scenario. The overall structure is way more complex that what I described and it accommodates a number of releases, service packs, sub-releses, and etc. It follows the well-known branching guideline.
So you have something like this:
------------------------------------> MAIN
\ \
\ \
A B
You can make a B' branch out of B:
------------------------------------> MAIN
\ \
\ \
A B
\
\
B'
Then make a baseless merge from A->B'. After that make a merge B'->B. Go ahead & destroy B'. Though I haven't ever done this, it should work.
One approach:
Map both branches (A and B) into separate folders on your PC.
Locate the changes in A that you want to merge into B (look at source control history for the branch, locate the changeset(s) and double click them to list the chnaged files), and check them out in the destination branch. (Alternatives: Check out all the files - TFS will discard unchanged files when you check in. Or unplug your network cable and then run VS and it'll go offline. After merging use File>Source Control>Go online to go back online and check out any changed files)
Use a merge tool (I'd recommend Beyond Compare, Araxis, but anything aside from the terrible ones that ship with VS should do) to merge from each file in branch A to the eqiuivalent file in branch B
Build and test branch B
Check in
This avoids using TFS to do any of the merging, so it won't know that it's a merge. It will just think you've written a lot of code in branch B rather fast :-)
Another approach:
Merge the changeset into your main branch from A. During the merge, include both variants of the code and add #if commands around the new and old code blocks so that they coexist side by side, and the service pack is "enabled" in the main trunk by a simple define. By default this define should not be defined, so the binary output by the main branch code is unaffected. i.e.
#if SERVICE_PACK_A
...ServicePackA code...
#else
...original Main branch code...
#endif
Now merge the change down into branch B
My answer is similar to Jason Williams's. If you want to stay "inside" TFS then you only have 2 options. Perform the baseless merge, or merge from A to Main and then from Main to B.
As you don't want to do either of these, then you'll need to perform the merge "outside" of TFS.
Tools you'll need:
Team Explorer, Team Foundation Power Tools, a 3rd party merge tool. I like Sourcegear DiffMerge (cos it's free) but Araxis, Beyond Compare and Winmerge will all work just as well. (as an aside you can configure TFS to use a 3rd party merge tool(Thanks again Jason!))
Get Latest on both service pack branches
Check out the target branch
Use the merge tool to do a folder comparison between the 2 local folders
Merge the appropriate changes from A to B
On the command line run tfpt uu against the local copy of B, this will undo the checkout of any files that haven't changed as part of the merge. (this requires that the TFS Power tools are installed.)
Check in the pending changes in B
It's not great but I think it's the only way to do what you're trying to achieve
Actually I was pointed to another solution that I like too.
http://geekswithblogs.net/TarunArora/archive/2011/06/06/unshelve-shelveset-created-from-one-branch-to-another.aspx

Creating a TFS branch with same initial code base as second branch

Here is my current setup. (TFS2008)
I have a TRUNK with latest.
I have BRANCH-A off of TRUNK with only the production ready code merged in.
I would like to create a new BRANCH-B off of TRUNK but I don't want all the latest code, I only want what is currently in BRANCH-A.
After this is done I will be merging into both BRANCH-A and BRANCH-B from the TRUNK (so I don't want to branch BRANCH-B off of BRANCH-A.)
Thanks.
You need to perform a baseless merge. This sibling situation that you want to achieve is exactly what is described in How To: Perform a Baseless Merge in Visual Studio Team Foundation Server:
The process of merging items that are not directly branched from each
other is called a baseless merge. For example, you might want to merge
a change between two release branches, which are siblings of each
other, without merging up to the parent branch. You can only perform a
baseless merge by using the Tf merge command. You cannot perform a
baseless merge from within the Visual Studio IDE.
When you perform a baseless merge, TFS does not have any information
about the relationship of the files in the branches. For example, if
you have renamed a file, this will be viewed as a deleted file and a
new file will be added in the branch. For this reason you have to
perform more manual conflict resolutions than when you perform a
normal merge. However, you only have to perform this conflict
resolution once. After you have performed the baseless merge, TFS
records merge history and establishes a relationship between the
folders and files.
When you create BRANCH-B, you can either choose latest or a specific date/changeset/label. Take a look when you created BRANCH-A and create the BRANCH-B from the same date/changeset/label. As long as you haven't made any changes to BRANCH-A, you can create B to match.
Also, if you haven't already, take a look at the TFS 2008 Branching guidance. There is some great information and uses a pragmatic approach.
For TRUNK
On Create Branch you have option as a "Branch from Version" - by default By Latest Version is selected.
Select By changeSet or By Date

Resources