TFS: Overwrite a branch with another - tfs

Is it possible overwrite a branch with another?
Or is the only solution to delete branch B and make a new branch from Branch A?

Unless you're running TFS 2010, I'd recommend using Merge + Resolve to bring the two branches back in sync.
# cancel out of conflict dialog
tf merge A B -r -force -version:T
tf resolve B -r -auto:acceptTheirs
That should equalize everything, except for files that were only created in B and never merged back. Use Folder Diff to find & reconcile them.
Delete + rebranch in 2005/2008 runs the risk of nightmarish-to-debug namespace conflicts in the future. The other option, if you have 2008, is to Destroy + rebranch. Obviously that assumes you are ok with losing all the history from the original copy of B.

In Visual Studio 2010, I just used the baseless merge to achieve this:
Tf merge /baseless [source path] [target path] /recursive
When the resolve conflicts window popup, select 'Take source version' option. Note, the files only exist in target will not be deleted by using baseless merge, but you can compare the 2 branches to identify the difference and delete them manually.
Refer to: http://msdn.microsoft.com/en-us/library/bb668976.aspx

I had success using Richard Berg's answer but felt like there were a few details that were missing. This is how I was able to eliminate differences related to conflict resolutions and changesets that had not been merged back to the source and make the target identical to the source. Note that this is how I will be referring to the branches - source is the one that should not be changed while target is the one that should be made identical to source.
Make sure that you have the latest version of both the source and target branches in your workspace. Also make sure that you do not have any pending changes.
Discard all of the candidates for merges from the target branch to the source branch. This is to prevent any of these differences from being unintentionally merged back into the source branch later on.
tf merge $/target $/source /recursive /discard
Note: Make sure that you have set the working folder to a path within your workspace so that the tf tool knows which workspace and TFS server to use.
Check that there are differences between the branches that should be addressed - if not, no further action is required.
3.1. View history on the target branch and find the last complete merge from the source to the target (ignore any cherry picking merges as that will result in lots of false positives) - note the changeset number. An easier alternative would be to perform a merge from the source branch into the target branch to get the lastest version from the source branch into the target branch.
3.2. Right click on the source branch in the Source Control Explorer and select Compare from the context menu. Only take the latest version for the source if you merged the source branch into the target branch in step 2.1. Otherwise select Changeset from the Source Version | Type combo box and then enter the changeset number from step 2.1.
3.3. Use the drop down arrow on the Browse button next to the Target Path field to select Server Path. Then select the target branch in the dialog that opens.
3.4. Click OK on the Compare dialog to perform the comparison.
Perform a merge from the source branch to the target branch and pass the force option. This will ignore the merge history and merge changesets even if they have been merged in the past.
tf merge $/source $/target /recursive /force /version:T
Note: the T version specification indicates the latest version.
Close the merge conflicts dialog.
Automatically resolve all conflicts by choosing the source branch.
tf resolve $/target /recursive -auto:TakeTheirs
Check in.
Confirm that there are no longer any candidates for merges from the target to the source and that there are no differences between the two branches (this time just using the latest versions as we did a forced merge of the latest version in step 4.).
See MSDN for more details on the tf merge and resolve commands.

Delete the branch B and create a new one from branch A.
Is there a reason why you do not want to do this?

Related

TFS Create branches from Main - selected changeset

I have an issue; we have a Main branch, and we have few changesets (that belong to 3 different features).
I created three DEV branches By Date (and selected a date that is prior any of the changesets).
I cherry picked the changesets from Main, and merged them to appropriate DEV branches.
I RolledBack all these changesets from Main so that, the main becomes clean.
Now I want to merge one of DEV branch to Main and deploy for testing,
The problem is; it doesn't pick all the changesets, and even for the ones that it picks, it doesn't pick all the modified files.
How can I merge from DEV to Main? Please help.
Thanks
When TFS does a merge, it bases the merge on prior merge history, not on the actual contents of the source and target files.
You could try the /force option with the tf merge command. The /force flag ignores merge history that indicates a particular changeset was previously merged from source to target (perhaps incorrectly), and merges the changeset again. You can do a /force merge for a single changeset or for a range of changesets. For just changeset #123456 the command would be:
tf merge /force $/Source/File.cs;C123456~123456 $/Target/file.cs
Check the following blog for more details:
https://blogs.msdn.microsoft.com/billheys/2011/03/16/my-source-and-target-files-are-different-but-merge-tells-me-there-are-no-changes-to-merge/

Ignoring 2 changesets

I'm using TFS 2010. I have 2 changesets in child branch that I do not want to merge in the parent branch.
e.g
(1002) Rolled back changeset
(1001) Changeset checked in by mistake
I don't want these changesets from appearing in the merge menu when you attempt to merge into the parent branch.
If I have understood correctly that I can use the following TFS command to ignore these 2 particular changesets or will the rollback changeset interfere?
tf merge childbranch parentbranch /r /version:1001~1002 /discard
You can do a discard
merge.
This has to be done from the command line. Open up the Developer
command
prompt,
then navigate to a folder under either of your branches (i.e. navigate
to one of the affected
workspaces).
Then type:
tf merge /r /discard "$/Project/B1" "$/Project/B2" /v:C12345~C12345
This will take the changeset identified (in this case it was changeset
#12345), and update it as merged to the target branch (branch B2). The target files will be checked out, but they will not be changed - you
can simply check them in to complete the operation. After that the
changeset will no longer appear as a merge candidate. You can specify
a range of changesets to merge at the same time, but they should be
contiguous.
Note that after doing this a changeset will occasionally still show up
as a merge candidate - this is rather uncommon with the latest
versions of TFS, and it is virtually impossible to fix (unless you are
running your own local install of TFS and want to get your hands very
dirty in the database). If you end up with one of these marooned
changesets, just ignore it.
Source:
Finding merge candidates in TFS
Note: When the command has finished, you still need to check in the merge.
For more tutorials, you could also refer below blogs:
TFS: Discard changesets when merging to branches
DISCARDING CHANGESETS IN TFS

Teamfoundationserver branching not working in any form

I have tried branching in a very simple sample project and it worked. Now I want to branch a real life project and it is simply not working.
When I try to branch the whole team project, tfs tells ask for a destination. If I choose a new destination it tells me, that the destination does not exist. If I create a new one and point to it, it tells me that the folder already exists.
When I try to branch the team project into a sub-folder within the team project it tells me that this procedure cant be done, fair enough.
But when I try to branch a single project within the team project to another sub-folder it tells me that there was no correct mapping ('keine passende Zuordnung', in German I don't know the exact English error message).
Any help on this is very appreciated. I fail to see, what I do differently here, then I did before in my test project.
Edit: As suggested I post an image of my project structure. The upper folder is my actuall project which I have converted from a teamproject to a branch. The second on is the destination folder which is empty.
When branching a whole team project ($/ProjectName), you either need to use the New Project Wizard to create a new project and specify that it should branch from your current project.
When branching a sub-folder of your team project, that should work, unless a parent of that sub-folder is marked as a branch root, in which case there is no location to branch to.
Any folder that either holds a branch root as a child, or has abranch root as a parent cannot be used to create a new branch:
On the commandline try running tf branches . from the folder that you want to branch (to see if it is part of a branch) and from the folder you want to branch to. If the target folder is already under a branch, you can't branch to it. You might need to use the Convert to Folder option in the Source control explorer to allow branches to be created there.
It looks like you've already created the target folder, and the target folder is already a branch. You haven't described how that came to be, if it's a result from a Branch action on the source folder, then instead of choosing Branch pick Merge instead.
If there is no relationship between the two folders then it won't be pre-populated in the list of possible merge targets. If you're using Visual Studio 2013 you can enter the path manually and TFS will create the relationship by doing a baseless merge. If you're using an older version of Visual Studio you may need to create this relationship from the commandline:
tf merge "$/TeamProject/Machinenzustandsanzeige" "$/teamproject/Machinenzustandsanzeige NC-Prä" /baseless /recursive /collection:{uri}
You can also destroy the target branch that you've created using the commandline and then re-attempt the branch, which should then succeed.
tf destroy "$/teamproject/Machinenzustandsanzeige NC-Prä" /recursive /collection:{uri}
tf branch "$/teamproject/Machinenzustandsanzeige;T" "$/teamproject/Machinenzustandsanzeige NC-Prä" /recursive /collection:{uri}
tf checkin "$/teamproject/Machinenzustandsanzeige NC-Prä" /recursive /collection:{uri}
In case the workspace isn't setup correctly yet you can either do it through the UI using the steps outlined here or from the commandline using:
tf workfold /map "$/teamproject/Machinenzustandsanzeige NC-Prä" c:\path\where\you\want\it
followed by:
tf get "$/teamproject/Machinenzustandsanzeige NC-Prä" /recursive
to effectuate the addition of the folder.
There is a very slim chance that the a-umlaut is causing the issue. Have you tried a path without special characters?
What you want to achieve is a standard operation and TFVC supports it, but somehow you ended up in a situation that is non-default. Even in such a situation you can get it fixed, but you might need to resort to advanced features such as /baseless or /force or tf destroy which are not available from the UI.

Is there a way to associate a new TFS changeset with an old changeset?

So I fixed a bug on our main branch some months back, let's say some old changeset 555. Recently, I manually copied these changes to a child branch for a recently approved hotfix, changeset 999. I would like to do a Track Changeset on 999 and see this it has been merged to main as 555. But, I've done this backwards according to the TFS rules, you can't merge down to a child branch.
Is there a way to tell TFS "accept my old changeset 555 as the merge of 999 to the main branch"?
This is analogous to the ClearCase version tree workflow, using the "don't perform merge, just draw arrow". Thus the Track Changeset for either 555 or 999 would show that they are related.
I'm not sure what you mean by
But, I've done this backwards according to the TFS rules, you can't merge down to a child branch.
There shouldn't be anything preventing you merging this change to a child branch, you might have some merge conflicts to resolve. However if that really isn't a possibility and you want to merge "999" in to the main branch without actually merging the code (i.e. adjust the merge history) then you can using the tf merge command line.
Open a visual studio command prompt and use the command
tf merge $/TeamProject/childBranch $/TeamProject/MainBranch /version:C999~C999 /recursive /discard
This will tell TFS to update its history to say that the merge occured even though it hasn't. You might want to use the /preview switch before you do the merge "for real" to make sure you are discarding the files you expect.

Why are all files marked with 'merge' in TFS?

I am merging my development branch into the main branch. There is only a subset of files that I have changed in my development branch, all other files should remain unchanged. Logically, I only want to merge files which I've changed. I would not check in a file which I did not change.
But when I do the merge operation in TFS, it marks every single file in the tree with change type 'merge'. It looks like I must checkin every single file in the whole source code tree! I really do not want to do this becasue then it becomes impossible to look at the changeset and see what files I acctually changed as part of my project.
At first, I thought I could use the tfpt.exe Undo Unchanged command to undo all the 'merge' changes, but this won't undo those changes.
Anyone have any ideas on this? thanks.
This also happens with a baseless merge. A baseless merge occurs when TFS doesn't have an existing merge relationship between the branches you're merging. As a result, it considers every file 'new' in both branches, so it 'merges' every file.
To create a merge relationship, so that future merges only list the files that you've actually changed, you need to do a baseless merge of all changes up to a specified version so that TFS knows what the common baseline should be. You should do this after merging these changes - it's too late to correct the baseline for this branch now.
If you don't actually want to take any changes from the other branch, but just tell TFS that these are logically at the same version, you can do a merge 'giving credit' for the changesets: tf merge /discard.
There are a number of possible reasons. This is not a complete list:
You performed a namespace operation (delete, undelete, rename) on a parent folder of the
files marked "merge"
You performed a namespace operation (delete, undelete, rename) that had already been performed in the target branch
You performed a sequence of namespace operations that collapsed into a no-op (eg delete + undelete, or rename a -> b -> a)
There are unresolved conflicts
You performing a discard
Note: all of these apply equally to 2005 & 2008.
In Visual Studio 2008 and TFS 2008, this does not occur. Only files that have changed will be marked as merge. If you do a compare of a file between the branch and the trunk are there any changes? Changes such as encoding will still make TFS merge this file back.

Resources