Monday, December 2, 2013

Visual Studio and Git - handling deleted repository

I created a Git repository in TFS and then renamed it.
The problem was Visual Studio still insisted to clone with the old name! And in attempt to connect I recevied :
An error was raised by libgit2. Category = Net (Error).

Of course, the repository didn't exist any more. So I tried to refresh, restart and etc, to let Visual Studio figure out that repository has a new name. Nope, no way.

So I found where those properties are locally saved -
C:\Users\my.user\AppData\Roaming\Microsoft\VisualStudio\12.0\Team Explorer\GitTeamProjects.config

Inside it looks like:
...
<project name="Inmeta" projectUri="...">
      <repository name="OldRepositoryName" guid="896f85d7-b840-48ed-92d5-74b223b34f66" />
</project>

...

I just deleted the whole line staring with <repository... and restarted Visual Studio.
And voila - the new repository name was discovered and shown correctly to clone :)

Wednesday, November 27, 2013

TFS: Error deleting Team Project

Recently I needed to cleanup a collection, removing a number of team projects from it. Generally all went fine, but one team project refused to be deleted, saying something like that:

Error logs said not much:
Executing step: 'Delete the team project data from Version Control' VersionControl.DeleteTeamProject (2 of 11)
[Error] Violation of PRIMARY KEY constraint 'PK__#yourLoc__FEE84A3672E9B4C6'. Cannot insert duplicate key in object 'dbo.#yourLocalPendingChanges'. The duplicate key value is (51843).

What I understood from it, is that it failed to delete team project from the source control. Oh well, thought I, I can try to delete from command line. So I did and hit:
C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\IDE>tf destroy "$/MyProject" /collection:http:\\localhost:8080\tfs\defaultcollection
TF246021: An error occurred while processing your request.
Technical information (for administrator):
SQL Server Error: 2627


At this moment things started looking very dark. I tried of course deleting again from Admin console, and of course with no luck.

But indeed I found the solution :)

I used the destroy command to drop things under source control one by one. Like :
C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\IDE>tf destroy "$/MyProject/Subfolder1" /collection:http:\\localhost:8080\tfs\defaultcollection
...
C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\IDE>tf destroy "$/MyProject/Subfolder2" /collection:http:\\localhost:8080\tfs\defaultcollection
 ..etc 
At first to folders I hit the same error, but I kept going and then, after some folders got successfully deleted, all others, even those wich were giving error - also got deleted. 

So when all subfolders was deleted I ran again:
C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\IDE>tf destroy "$/MyProject" /collection:http:\\localhost:8080\tfs\defaultcollection
And it all went good!
So, back to admin console and  delete project again - voila!

I am certain I am not the only one who hit the problem and desperately googled without any result :)
So hope this solution will work for others as well!

Wednesday, November 20, 2013

TFS to Git migration: step by step

It has been some posts about migrating to Git from TFS, unfortunately none of them worked for mas expected.

So, my task was: migrate a source from TFS to Git, preserve all history, but do not include dlls or other heavy files. Last part requires naturally not only removing those files from the latest source, but also removing it from the entire history.
On my way I met some hickups, which I will mention, so the road for others after me can be smooth :)

So, lets start!
You will use GitBash and Git-tf:

1. Install Git-TF. Follow this link and download latest release:  http://gittf.codeplex.com/
 Installation instruction is very easy, I chosen not to use Chocolatey, but changed PATH environment variables, worked perfectly.

2. Start GitBash. If you do not have it - can be downloaded from here

Note! All things from now are done from under GitBash.

Check if git-tf was installed successfully - just type "git tf", it should return usage description of git tf command.

Navigate to the place where you have you Git repositories. I use C:\Git\Sources\Repos folder. So my git promt looks like this now:

3. Clone my TFS source to some temporary Git repo.
git tf clone {collection url} {team project path} {temp repo name} --deep

like this:

Note --deep - that means I want to take history as well.

4. Create Git repository which you will use later as your Git source. So far I will not link it to TFS Git repository, just create it.
git init {repo name}
like this:

get into newly create repository by simply
cd {repo name}
you can see you are in a master branch of your newly created repository:

5. Being there, now pull the source from you temp TFS git to your future Git place:
git pull ../{temp repo name} --depth=100000000

teoretically we could push it to our TFS git already now, but first lets cleanup dlls or other unneeded files, so when we put it to TFS git it is all clean and lightweight.

In my example I had 2 installation files located in folder wix/wixDownloads. So I want to leave those behind.

git filter-branch --force --index-filter 'git rm -rf --cached --ignore-unmatch wix/wixdownloads'
Command works only from the root, so paths must be relative from there.
If I would need to delete only one file, I would type:
git filter-branch --force --index-filter 'git rm --cached --ignore-unmatch wix/wixdounloads/wix35.msi' 
It is important it says was rewritten in the end, that means stuff was actually removed. Otherwise - you probably misspell something.

If you type wrong, sometimes you get error "cannot remove directory '..../.git-rewrite" : directory is not empty. Dont panic, just remove it manually.

6. We are almost there! Now just clean up so all deleted files are physically deleted:
git reflog expire --all
git  gc --aggressive --prune
Now you can compare size og original forlder with clone from TFS, and size of cleaned up folder.
If everything is correct, the second one is much smaller!

7. And finally - push up to your TFS git:

git remote add master {your  TFS Git repository address}
git push -u master --all
like this: 

8. Now, when I compare hisoty on my original TFS source to history on my new TFS git source, I see no wixDownloads folder, and even not a corresponding checkin (well, this is because checkin contained JUST this folder, and no other files).



To the left - my new Git repo history, to the right - my original TFS history.

Hope it saves somebodys time!

Update 1: there is a possibility to hit  error when pulling source to the temp repository, if full filenames on temp repository exceed 256 symbols:

 error: unable to create file ...{verylongfullpath}... (Filename too long)

ignoring the error gets us on with being unable to do filter-branch and error:
fatal: Neeeded a single revision

To get around that make sure that the folder name for temp repo is short enough. In my case I just deleted temp repository, created a new one with a very short name and did git pull again.

Monday, November 18, 2013

TFS - customize Features backlog and board

By default Features board shows only work item type Feature. Lets say we have another work item type - Business Request, and we want it to be tretaed same way as Features.

So we need to make changes i categories definition of the process template and include Business Request in Features category.

First, download existing:
witadmin exportcategories /collection:{CollectionAddress} /p:{TeamProjectName} /f:C:\Temp\categories.xml

Now lets edit it:
 

And upload back to server:
witadmin importcategories /collection:{CollectionAddress} /p:{TeamProjectName} /f:C:\Temp\categories.xml

Ok, we can see new work item type available on our Feature backlog:


Next - configure Feature board.
By default it has only 3 columns, and only 2 states to choose from: Active and New. Which was very confusing to me, since our Business Request definitely has more states available.

To make it appear in the list of available States - we need to do changes in process config file. First,
download existing:
witadmin exportprocessconfig /collection:{CollectionAddress} /p:{TeamProjectName} /f:C:\Temp\processConfig.xml

Edit it, so it contains states we want to use:
 
Upload:
witadmin importprocessconfig /collection:{CollectionAddress} /p:{TeamProjectName} /f:C:\Temp\processConfig.xml



Now we can see more States available to map to columns in Features Board:
 

Congratulations!



Friday, October 4, 2013

TFS API 2013 - check access rights of the user

I've got a task which suppose to be really simple - check if user has an access to delete a build in  a Team project.

Seems to be easy, but no, it showed to be really poorly documented!
Therefore I put my code here, so people can find it and reuse it.

So, at first, we create a collection object, same good old way:

var tfs = TfsTeamProjectCollectionFactory.GetTeamProjectCollection(new Uri("YourCollectionAddress"));
tfs.EnsureAuthenticated();


Getting a team project object, good old way:

var versionServer = tfs.GetService<VersionControlServer>();
var teamProject = versionServer.GetAllTeamProjects(false).ToList().First(tp => tp.Name == tpName);


Getting user identity - here comes new - using IIdentityManagementService:

var identityService = tfs.GetService<IIdentityManagementService>();
var userIdentity = identityService.ReadIdentity(IdentitySearchFactor.AccountName, username, MembershipQuery.Expanded, ReadIdentityOptions.None);


Getting SecurityNamespace object for team project - in this object we can see which permissions generally are appliable for the target (in our case - team project). Also new - using ISecurityService (IGroupSecurity is obsolete now):

var ss = (ISecurityService)tfs.GetService(typeof(ISecurityService));
var sn = ss.GetSecurityNamespaces().First(ssn => ssn.Description.Name == "Project");

With a good usage og LINQPad I can check the following access rights for SecurityNamespace for a Team Project:
Ok, so I will check for  UPDATE_BUILD then.

Next step - getting actually access rights list for the user in the Team project:

var securityToken = "$PROJECT:" + teamProject.ArtifactUri;
var access = sn.QueryAccessControlList(securityToken, new List<IdentityDescriptor> {userIdentity.Descriptor}, true);

Almost there!

Now we just need to check if the following access list contains UPDATE_BUILD, either as inhereted or granted directly:

if (access.AccessControlEntries.Any(
      acl => ((acl.ExtendedInfo.EffectiveAllow & 128) == 128 || 
      (acl.ExtendedInfo.InheritedAllow & 128) == 128)))
{
    return true;
}
return false;

Hope that helps :)

More information
Those pages helped me a lot, and actually were only info I found about using TFS API for permissions set\check:
http://blog.johnsworkshop.net/tfs11-api-managing-team-administrators/

http://pascoal.net/2011/11/using-team-foundation-server-registrypart-i-the-concepts/
pascoal.net/2011/11/using-team-foundation-server-registrypart-ii-the-api/

Tuesday, August 13, 2013

TFS 2013 Preview and TF400917: The current configuration is not valid for this feature.

After upgrading to TFS 2013 Preview some of our team projects started to get this error when trying to access backlog:
Some of our projects were successfully upgraded though. So what is to be done in order to fix the error:

1. You need to install Visual Studio 2013. witadmin tool from Visual Studio 2012 can export process config files, but can not import. Make sure you run witadmin from C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\IDE

2. Run
witadmin exportprocessconfig /collection:http://yourTFSserver:8080/tfs/YourCollection /p:YourTeamProject /f:c:\temp\processconfig.xml 

3. Correct processconfig.xml file so for nodes :
  • FeedbackRequestWorkItems, 
  • FeedbackResponseWorkItems
  • RequirementBacklog 
  • TaskBacklog 
there exists attributes pluralName and singularName. Like this, for example:
<RequirementBacklog category="Microsoft.RequirementCategory" pluralName="Backlog items" singularName="User Story">
...
</RequirementBacklog>

4. For RequirementBacklog and TaskBacklog there should exist not empty AddPanel sub-node; like this:
<TaskBacklog category="Microsoft.TaskCategory" pluralName="Tasks" singularName="Task">
    <AddPanel>
      <Fields>
        <Field refname="System.Title" />
      </Fields>
    </AddPanel>

...
</TaskBacklog>

5. Run
witadmin importprocessconfig /collection:http://yourTFSserver:8080/tfs/YourCollection /p:YourTeamProject /f:c:\temp\processconfig.xml

6. It might complain about multiple states with the type Complete. Yes, it should be only one. Make sure that this part of processconfig.xml defines only one state as Complete:
<States>
      <State type="Proposed" value="Analysis" />
      <State type="Proposed" value="Proposed" />
      <State type="Proposed" value="Not Started" />
      <State type="InProgress" value="Active" />
      <State type="InProgress" value="Resolved" />
      <State type="Complete" value="Closed" />
</States>


7. Run witadmin importprocessconfig.... again. That should be it.


Wednesday, July 31, 2013

Hyper-V: Clone a machine with SQL Server installed

The first part of this post will describe the cloning process,
the second - how to get SQL server up again after the clone machine is ready.

Part 0 : Before all

If you use Reporting services, backup service key and store separately, preferably on another machine. Remeber the password, ofc.

Part 1 : Hyper-V - clone your virtual machine

Have to say at once - I did have a possibility to stop the original machine I was cloning. If you do not have such an optyion, this is not exactly post for you. 
Disclaimer: The described method does not pretend to be the best, it just worked for me. I have tried different ways, and that one worked all the time.

I didn't turn on the original machine untill i was completely done with cloning and fixing SQL Server.

1. Shut down the original machine and export it to some location.

2. Copy exported machine where you want to have your clone and rename the folder accordingly. (it is absolutely safe to do that, your original machine is not influenced)

3. In your exported folder delete all files except for hard drives, which have extension .hvdx

4. Create new virtual machine at your host, giving it a new name and attch existing hard drive - the one which is exported. IMPORTANT: do not turn on the original machine yet!

5. Start your new machine. Start command line tool and run the following:
c:\windows\system32\sysprep\sysprep
in the window check Generalize.
Wait until the process is done and machine rebooted. This takes time, so fetch coffeee or smth :)

6. When the machine is restarted it asks for windows settings, since they were nuked. Provide them. Details of what sysprep does with machine is here - very nice post, helped me to understand a lot!

7. Change machine name to something meaningfull, reboot. Add it to domain if needed, reboot.

8. If you have static ip configuration, do not forget to change that as well.

9. That's it , you have a clone up and running!

And now, lets get SQL server up.

Part 2 : Reconfigure SQL Server on a cloned machine
 
The problem is that the cloned machine after renaming has old SQL server instance name (from the original machine), so we need to change that. Analysis services doesn't look happy and, naturally, Reporting services also needs to be reconfigured.

1. Start SQL Server Management Studio, try to connect to the instance with the new machine name. If it works - lucky, the process was taken care off during machine rename.

1a. If connecting with machine name as SQL Server name didn't work - provide . or localhost as a server name and connect. Create new query as:
 
sp_dropserver <old_machine_name>;
GO
sp_addserver <new_machine_name>, local;
GO
 
Restart SQL server. 

Now - Reporting services.

2. Start Reporting Services Configuration Manager. Navigate to Database tab and click Change Database. As you can see it has the name of the old machine, put the new name in, and on Next page select correct Report Server Database (ReportServer). Finish.

3. Restore Encryption Key. Go to Encryption Keys tab and click Restore. Find the key file you saved before (see Part 0 : Before all) and restore the key from there.
 
4. That should be it. Navigate to Report Manager URL to make sure it works.

Now - Analysis services.

1. After all that, my analysis service still was not happy. The only thing that helped was to start installation again and repair (just next next next - repair). If somebody knows how to do it the correct\better way - drop me a note, I will be really thankfull!

2. When repairing done, restart the machine. Make sure you can connect to Analysis services, SQL Server instance and Reporting Services.

3. Start your original image.

Monday, April 29, 2013

Backlog board TF400898: An Internal Error Occurred.

After upgrading to TFS 2012 Update2 our customer start getting "TF400898: An Internal Error Occurred" when trying to view a product backlog board.

Event log at tfs application tier said:
Exception Message: The given key was not present in the dictionary. (type KeyNotFoundException)
Exception Stack Trace:    at System.Collections.Generic.Dictionary`2.get_Item(TKey key)
   at Microsoft.TeamFoundation.Server.WebAccess.Agile.Models.WorkItemSource.<>c__DisplayClassa.<GetCompleteWorkItemData>b__6(IDataRecord dataRecord)
   at Microsoft.TeamFoundation.Server.WebAccess.Agile.Utility.WorkItemServiceUtils.<GetWorkItems>d__c.MoveNext()...

...etc ..etc

As this is a known issue, solution is described here:
http://blogs.msdn.com/b/visualstudioalm/archive/2013/03/19/how-to-fix-tf400898-an-internal-error-occurred-on-your-kanban-board-in-tfs-2012-update-2.aspx

But... it didn't help. Yes, there was inconsistency and 2 possible work items states mapped to Complete board state, but after fixing CommonProcessConfig.xml and leaving only User Story work item in Requirements categories - error still kept coming.

It looks like if there are work items which have the "invalid" state, the board is not getting rebuilt. So, in this unlucky case the fastest fix is to create a new area, and make it the only and default area for backlog.Which practically makes the backlog (and the board) empty.

So, this time the board gets rebuilt successfully. Go to the board page and verify it. After that, just set default area(s) for the backlog the way it was before. Most likely you will need to correct columns for the board, but the annoying TF400898 will be gone.
Just click on Correct this now, and assign relevant states for the board columns.


Neat!

Wednesday, April 24, 2013

MSSQL: Shrink transaction log

Common issue, right. Let's do it.

1. Go to your database in Management Studio.
2. Right click on the database and select Tasks -> Backup. Choose Transaction Log as Backup type.

3. When backup is taken, right click on database, select Tasks -> Shrink -> Files. Choose File type Log.
In 95% of cases that will do the trick.

In 5% of unlucky events, log file is not getting less, but there is no error displayed. If you have that, click Script on the previous screenshot (Shrinking log file). And then run script to do the job, and click on Messages at Output window.
You will see smth like this: 
Cannot shrink log file 2 because the logical log file located at the end of the file is in use.

Then you need some extra steps.
2a. Right-click your database and select Properties. At Options tab set Recovery model to Simple.
Do Step 3.
3a. Set recovery model back to Full. 

Good luck!

Tuesday, April 9, 2013

Some features of Team Web Access are not visible to you

Installing TFS, going to Team Web Access and observing something lilke this?
And there is no Backlog and Sprint Planning Tools and neither can you see Request Feedback feature.

You need to enable all features. Somehow by default they are set to "Standard" level, not "Full".
Enter administration page and go to Control Panel:

Select Full and make it default.


That will do!

Thursday, April 4, 2013

Configure SSL in IIS :The process cannot access the file because it is being used by another process.

Tja... annoying! Obviously someone else is listening on 443, let's find out who.

Command prompt: netstat -ano
Looking for port 443 and memorizing PID.

Troublesome PID = 8952. Open Task manager -> Processes - sort by PID.
Ah, here it is. Skype! Kill it, and you will be able to successfully configure your web site to work over SSL.

TFS 2012 Velocity chart

Here I will explain what is it the velocity chart in TFS 2012 shows. Generally - velocity shows how much a team can do during a sprint.

So it comes to - how do you estimate effort. IN TFS 2012 we use User Stories, and for estimates - Story Points. This is essential to remember. Look here, an example of velocity chart:
First of all, on X-axis - iteration ordered by time. This means you have to set timeframe for your iterations. For this go to admin page and Iterations tab.

Y-axis. See numbers? Those are story points. If your work items do not have story points - they will not appear on this chart.

Now about colours. Green shows work items in Resolved\Completed\Done state. Blue - Active. Other states are not shown.

Hope that clarifies some things.

Tuesday, March 12, 2013

CodeMetrics and VS 2012 workaround

As it is for now, running metrics.exe on a machine which doesn't have VS 2010 gives you an error:

Could not locate C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\metrics.exe. Please download Visual Studio Code Metrics PowerTool 10.0 at http://www.microsoft.com/downloads/en/details.aspx?FamilyID=edd1dfb0-b9fe-4e90-b6a6-5ed6f6f6e615

Downloading and installing as it says - doesn't really help, it gives yet another error about missing dll or one of its dependencies.

So, to be able to run code metrics tool on a machine without VS 2010 installed, do the following:

1. Create folder C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools
2. Copy over the whole Static Analysis Tools folder there from the machine with VS2010.
3. Copy Microsoft.VisualC.dll version 10.0.0.0 to the FxCop subfolder of Static Analysis Tools folder.

This made the trick.

UPDATE: It's finally there! See CodeMetrics for VisualStudio 2012.

Saturday, March 2, 2013

Best tools ever: LINQPad

I thought to make serie of posts about tools I use daily, and can't imagine life without.
And I start with my very favourite - LINQPad.

So often there is a code snippet we just want to try, and starting all the hussle with opening Visual Studio, creating project, etc etc... uff, it is just too much. Life should be easy - write & run!

And that is exactly what LINQPad allowes me to do.

So start LINQPad - and you get a window to write your code:

 
Select a C# statement, and - write your code. In this particular example I query for build definitions, and if I press Run, it will show me the result in nice format:


Of course, there are dlls I need to reference. To add references required by your code - right click on the code field and choose Query Properties.


And look - there is even NuGet there.

 Best news ever - you can get it for free. If you would like to have code autocompletion - it will cost you some, otherwise - totally free of charge.

I have to add that LINQPad can do much more than what I mostly use it for, so - try it and I am 100% sure you will love it.

Official site, download and examples here: http://www.linqpad.net/