How do I create a task branch that includes an imported stream that I must work on? (Edited) - task

The project I have to work on is imported into the mainline stream. It has the workspace root as its parent. The workspace root also has some build files needed for all projects. I created a task stream of the entire workspace expecting Perforce to "do the right thing" but it did not. Now I have changes for the project that I am working on (the project that is imported from another stream, but is a child of the parent) and I'm at a loss as to how I should approach this since what I did is not working. Perforce will not let me check these files in. I don't think I want to "force" it because I don't believe the imported stream is part of my task branch.
EDIT
Here is a hypothetical example. Suppose there are two streams, ToImport and MainLine:
ToImport
ProjectA
ProjectB
MainLine
MainProjectA
MainProjectB
MainProjectC
MainProjectD
In my situation, ToImport is imported into MainLine (apologies if my terminology is imprecise, this is what we call it at my dev shop.) So, while it is not obvious in p4v that ToImport is part of MainLine it is due to the fact that it is imported into MainLine. (ToImport is self-contained and used in multiple other streams.)
Using my workspace configured for MainLine and performing a fetch, the following shows up on my local drive:
MainLine
MainProjectA
MainProjectB
ToImport
ProjectA
ProjectB
MainProjectC
MainProjectD
This is what shows up if I fetch MainLine or if I create a task stream of MainLine and fetch that. It is the task stream of MainLine where I need to work on ToImport (add, delete, modify.) Attempting to do this does not work because ToImport is not actually part of the MainLine stream nor the MainLine task stream -- it is imported. I cannot submit files to the ToImport stream. This makes sense to me, but what I am struggling with is what is the best way to work on ToImport in this situation? I need MainLine to exercise my changes to ToImport so it seemed logical to create a task stream of the whole thing. That's clearly the wrong answer.
What is the right answer? In other words, what is the best way to arrange my task branch so I can have all the code and work on the code in the ToImport stream.

Related

Branching and Merging in TFS

In my SSIS project, I created a MAIN folder in TFS and then created 2 branches (Dev1 and Dev2) from the same package which is present in the Main.
I did some changes in the Dev1 and other changes in Dev2. Now when I am trying to merge both the SSIS Packages in the Main, it is giving error (Conflict while merging). I am able to merge only one Dev package with the MAIN package. As soon I try to merge the second Dev package with the Main, it shows conflict error.
------- Dev1
/ \
------------------------ Main
\
------------- Dev2
Conflict resolution is a common activity when doing parallel development in separate branches. It happens because changes were made to the same (set of) files and those changes have hit the same piece of code.
SSIS makes this problem larger due to the fact that it has a tendency to change the order of things in files and sometimes generates new GUIDs for activities that were already in the workflow. When this happens, it causes a lot of changes almost everywhere in the file(s).
To resolve the conflict you have to select each file that is showing conflicts and follow the conflict resolution process through Team Explorer. When you select a conflict to resolve the editor will show up with the two different versions (one showing Dev2 and one showing Main (incl the changes from Dev1)). You will need to manually select which pieces of code to retain and how the files should be merged.
Unfortunately, there is no graphical representation, so you need to be very familiar with the internal file format in order to make no mistakes. After completing the merge you can first test your changes locally. If they were merged successfully, you can check-in the changes, if you've made a mistake just undo all pending changes and perform the merge process again.
The complete steps to perform merges are documented here. The BI Developer Extensions offer additional features to Visual Studio to make working with version control easier. Especially SmartDiff can save your hide in cases where SSIS has regenerated the file structure.

TFS Branching recommendation

I have a Solution called "Framework" which is a C# assembly for my business logic and data transactions.
I have 4 applications that use Framework, 1 website, 1 Console app and 3 other types of applications.
$/TeamProject
/Framework
/Dev
/Main
/Release
/WebApp
/Dev
/Main
/Release
/WCFApp
/Dev
/Main
/Release
I have all these in one Team Project with each assembly/application under its own folder.
I want to use the branching feature for each of the applications that share the Framework assembly but I don't know what is the best way to branch the Application along with the Framework?
Any suggestions?
I know how Branching and merging works, but all the examples only demonstrate branching everything that is contained in 1 folder.
In light of a picture representing your source control directory, I'll make the following assumption:
$/TeamProject
/Framework
/Console
/Web
/etc.
What you need to do first is create a Folder called Main in $/TeamProject (this will be your Main - aka trunk - branch) and move all of your top level folders into it.
So then we have:
$/TeamProject
/Main
/Framework
/Console
/Web
/etc.
Now you need to convert Main to a branch, you can do this by right clicking on the Main folder and choose "Convert to Branch". TFS will now allow you to branch $/TeamProject/Main to $/TeamProject/ConsoleV2 (for example) and work on features for V2 of the Console. You can modify the Console Application and the Framework if required in this branch. When this work is complete you can Reverse Integrate (merge up) the changes back into Main.
Remember to keep performing Forward Integration merges (merge down) from Main to your feature branch and resolving any conflicts to keep the code bases synchronised.
By taking this approach you can modify any part of any of your products in a single atomic check in, say for example, you change an API on your Framework adding a new mandatory parameter to a method, you can change it in all your apps at the same time, and when you RI merge into Main everything will be updated.
Your primary question as I understand it is "What is the best branching structure to branch my applications that depend on Framework?" If you always build and version/release them together then it is simpler and less expensive to branch them all together as DaveShaw descibes; however, if each of them is developed by different teams, have different release schedules, have different versions, etc... than you will want to create a MAIN branch under each of them. In this case, it should also be clear who owns changes to Framework. It is usually a good idea to control check-in access to only those who need it for shared projects like Framework.
If the latter case is true, then I think your current graphic handles it nicely, but I would make one change; Keep your Releases at the same level in the hierarchy as the MAIN branch so that the relative path remains the same for making references; this will simplify your workspace mappings:
$/TeamProject
/Framework
/Dev
/Main
/Release1
/Release2
/Release3
...
/WebApp
/Dev
/Main
/Release
/Release1
/Release2
/Release3
...
/WCFApp
...
If you want to have branching & merging for individual projects, the only way to achieve that under TFS is to create a separate TFS project for each of the projects in your solution. Hope that makes sense. Once, you do that, then you can branch code out of each project into your working directory.
We migrated our code from VSS into TFS a short while ago. At that time, we had to decide to put all the code into 1 TFS project or break them out. So, we have a website, a business library (which is used by the website & other apps), a data layer. We created a separate TFS project for the library, website, and the data layer projects. Each project would have a trunk branch. Everyone needing the latest would branch their own copy from the trunk and merge back there.
Hope that helps.

Storing files on TFS

I am working with my co-worker on some files, that are in TFS repository. We have to share these files frequently, however, in the process of our development they are neither compilable, nor working properly. We don't want to put them in the repository, because the rest of the crew shall have problems with compiling the solution. However, the manual sharing would be rather painful. Is there a way to put files on TFS, but not inside repository? (mark as temporary, not finished or something like that).
You can use a shelveset - if you shelve your set of changes then your colleague can pick them up and the other members of the team will never see them. It is a bit of a PITA as you need to have 2 shelvesets (1 each as you can only update your own). The only other way is to branch and then merge when you have compilable code.
Another option is to branch the code into a new branch that the two of you use. When you are done working on the file, and it will no longer break the main build, you can then merge that file back down to the development branch.

TFS build-server build of branch?

We have a TFS 2008 project with two branches ("Main" and "NewFeature").
Each is a complete, independent "copy" (variant) of the source code.
By changing the workspace mappings, we can map either variant onto our local PCs and have been working with both branches with no problems.
However, if I set up the mappings to switch our build server on to the NewFeature branch (which should simply swap in the NewFeature source code without changing anything else as far as the build server is concerned) I get errors:
There is no working folder mapping for $/Main/Product.sln
i.e. when it is building from the NewFeature branch, something is still looking in the Main branch, even though there are no references anywhere in the source code to this branch. It appears to be caching some reference to Main?!
I have done a completely clean build (deleted the build folder from the server and run the build with /p:ForceGet=true to make sure the mapping is flushed through to the server, and there are no files on the server that might cache the workspace bindings), but this doesn't help.
Any suggestions?
Verify that:
$(SolutionToBuild) uses a relative path when referencing Product.sln
the relative path between $/NewFeature/.../TFSBuild.proj and $/NewFeature/Product.sln is the same as it is in the Main branch.
/ EDIT /
Note, however, it's not important that $/Main and $/Branches/Feature live at the same level in the tree hierarchy. Nor should the local path on the build server matter.* All that matters is what's underneath each branch. If the contents is internally consistent then all of your existing build scripts should work without modification.
For concrete examples of how I like to tie everything together, see my past answers, e.g.:
Modular TeamBuilds
SDLC Mangement for TFS Build Scripts
Where to put my database project in TFS?
How do you share external dependencies between Visual Studio solutions?
My way is not the only way, but I can attest that it works better than all the other variations I've encountered over the years :)
*Frankly, trying to micromanage Team Build can become a lot more painful than the proposed restructuring to your MSBuild scripts. For reliability you have to place your tfsbuildservice.exe.config customizations under version control somewhere...if you own >1 build server (or might in the future) then you have to consider a change deployment strategy...you end up needing a meta-SCM process to manage your SCM process!
I also had this problem when running a build from a branch in TFS 2010. TFS was reporting that "There is no working folder mapping for $/Main/Product.sln" The solution turned out to be to edit the build definition as follows (I am using the "Default Template" build process template—I have not tried this with a custom template):
Go to the Process section/tab of the build definition.
Expand 1. Required and look for Projects to Build. Make sure this entry is pointing to the solution file inside the branch you are building.
Expand 2. Basic and look for Automated Tests. Point this to the correct test settings file in the branch being built.
OK, the results are in - I've found a workaround.
Due to our legacy build processes (build, copy, obfuscate, build custom installers, copy to drop folder), I can't easily place the branch alongside the main branch. It needs to replace it.
So, if I have Main and NewFeature, I wish to unmap Main and map NewFeature in its place (i.e. use "c:\Main" on the build server, and simply change the source code that appears there)
Solution #1 (the most simple, obvious and logical solution) is to use these mappings:
$/NewFeature -> c:\Main
Expected result: NewFeature code structure simply replaces Main, and the build server doesn't know it's on a different branch.
Actual Result: Failure with a "you haven't mapped $/Main even though you're not using it" error.
Solution #2 is to do this:
$/Main -> c:\IgnoreThisFolder
$/NewFeature -> c:\Main
This works (it suppresses the warning and thus allows the build to proceed with MSBuild unaware that it is building in a branch). However, it's ugly and the build gets all the Main branch source code unnecessarily.
Solution #3 (untested, too expensive to try unless I know it'll work much better than #2) is:
Move all the source code (from $/Main, $/Branches/Feature) to $/Branches/Main and $/Branches/Feature to get a consistent hierarchy depth, and rewrite the MSBuild script to work with these new paths.
Hope that I can then map in only the branch I need and edit TFSBuild.proj to redirect it to build in that branch.
(Edit: Yes, this works well. We have now reorganised our entire code structure so that everything (all branches) is under a common root in a single Team Project, and branching/building is no longer a problem - it's easy to do whatever we need now. The trick is to insert a root folder into the hierarchy so that you can branch at any level you like. I've added a small tweak to the build script so that we can pass the branch to build as a parameter to MSBuild, so it's easy to build any variant now. Any branches we don't want to work on can just be cloaked and the build server remains happy.)
Summary
All these solutions (to use the technical term) suck. You have to remap the workspace (in this case, it's not simple: 9 mapping entries are required so it's an error prone and tedious thing to do), edit the TFSBuild.proj, delete all the source code, and run a build with /p:ForceGet=true to switch the build between branches. So it takes about an hour to switch branches. Unbelievable - it should take a few minutes at most!
I realise our project is far from ideally set up, but I can't believe it should be this difficult to branch in TFS (It was a piece of cake in SourceSafe, Accurev, and Perforce, so why so painful in TFS?).
How does everyone else organise their TFS branches? How do you switch developers between branches? How do you switch server builds between branches? Does it really have to be this painful?
When you Edit the build definition there are two places that need to be changed.
Source Settings - Point to your new project location
Process - (This sometimes takes a while to load so be patient) Under Required, change the "items to build" location to the new solution.
Hope this helps.
New update:
As reported in the other answer, I found a workaround that was ok for a short-lived feature branch, but it really didn't work very well. I've since come back to the problem, and the full solution is ridiculously simple:
In the TFSBuild.proj, the path was based on $(BuildProjectFolderPath). This path resolves to a server-side (source control path) like $/Main - not a local path (D:\ServerBuildFolder\Main).
Unfortunately, for historical reasons our source code is split across several team projects, which means the one "branch" is fragmented into several branched folders in Source Control (i.e. $/Main/Code and $/Libraries/Code. You can't create a branch that contains $/Main and $/Libraries). We thus have to reassemble these disparate fragments from Source Control back into a coherent hierarchy using workspace mappings.
This means that Richard was spot on - the relative path from the TFSBuild.proj file to the .sln file was incorrect, because MSBuild/TFS is assuming that the .sln lies within the same Team Project and source control hierarchy (so was looking for $/Main/Libraries.sln instead of $/Libraries/Libraries.sln).
The solution is simple: I replaced $(BuildProjectFolderPath) with a local path (e.g. D:\ServerBuildFolder\Main) for the files, so that the relative reference was resolved in "local space" (after the mappings had been applied), and MSBuild is now running sweetly.
The moral of the story:
1) NEVER use more than one Team Project if there is any chance that you will ever wish to have any kind of reference between those code-bases. Don't be fooled into thinking that a new Team Project will offer some kind of painless logical distinction between applications/libraries. Extra projects have proven to just be an administration nightmare - loads of extra problems for absolutely zero benefit. (It's all one big shared pile under the bonnet, so all the work items and source control folders are still visible in all the projects (!), but it adds a few brick walls that make inter-project links very problematic)
2) Always create a single root-level folder in your Team Project source control, and then put everything else underneath that folder. e.g. For the project "$/Main", create "$/Main/Root" and then put everything from your source hierarchy inside Root.
By following these rules, you will be able to branch the single 'Root' folder in future, and will then only need a single branch and a single extra workspace mapping. This will help you avoid premature baldness.
(In my defence, I would have done it this way to begin with - I'm working with a legacy setup. In defence of the legacy setup, it sounds good on paper but just isn't a Microsoft-supported approach!)
I got this error and all I can fathom is that the definition became corrupt or something. I just redid the process stuff (re-added the solution I was trying to build) and remapped the workspaces and it started working again. HTH.

How to branch and merge in TFS

This question is a derivative of a previous question: How to version resources that are shared across projects
I have a project that contains code that is consumed by many other projects. Specifically, one folder in this parent project has been branched to dependent child projects.
We have since made changes in the parent project and checked them in. In Source Control Explorer, I right click on the branched folder in the parent project and select "Merge", intending to push the changes to a dependent project. I select the child project as a destination and then select "Latest Version". The wizard informs me "There are no changes to merge."
From my perspective, this isn't true, since the recently updated files are clearly different.
Is there a fundamental misunderstanding of the merge process in TFS here? What do I need to do differently?
The TFS merge engine relies almost entirely on history, not file contents. This makes it efficient for very large trees, and flexible for tasks like safely cherry-picking changes -- but it also makes answering your question difficult.
The first step is to understand the diagnostic commands tf history, tf merges, and tf merge /candidate. Here is a good introduction: http://blogs.msdn.com/dstfs/archive/2009/04/15/a-note-on-merging-and-the-use-of-tf-merges-tf-merge.aspx
If you are new to branching & merging in TFS then your history is probably not very complex. I think it's likely you'll find your answer with one quick call to tf merges. However, tracing merge history can become extremely convoluted in the general case, so if you have trouble feel free to post back with more details.
Go to one specific file you know has changed in your "parent" project. Try merging just that file. Don't check anything in; just see what happens.
Something to watch for: The merge tools will not include files that have been added after you branch. You have to branch new files explicitly before you can merge any further changes. If a file is added to both parent and child folders without using a branch operation, the merge tools don't treat them as versions of the same file (and you can't merge changes between them).

Resources