Equivalent to git diff --unified=0 with libgit2sharp? - libgit2sharp

I am planning to replace the usage of git.exe from windows path by libgit2sharp for my plugin GitDiffMargin, A Visual Studio 2012 extension to display Git Diff on the margin of the current file. - https://github.com/laurentkempe/GitDiffMargin
I would like to know if there is an equivalent in libgit2sharp to get the same information as when running git diff --unified=0 on a file?

It looks like libgit2 supports changing context lines, but currently LibGit2Sharp is hard-coded to use 3: https://github.com/libgit2/libgit2sharp/blob/6a2d99ecdf35288df88c0e6fe8985969042d82a6/LibGit2Sharp/Diff.cs#L27
I've created https://github.com/libgit2/libgit2sharp/issues/423 to track the feature request.
Update:
As of v0.12 (or whatever comes after v0.11), you can do this:
var co = new CompareOptions
{
ContextLines = 0,
};
var tc = repo.Diff.Compare(new[] { filename }, co);

Related

LibGit2Sharp Cloning from a network file share

I'm having issues cloning using the file transport when the remote is hosted on a network drive.
I downloaded the project and tried adding some test cases:
[Fact]
public void CanCloneALocalRepositoryFromANetworkDriveUri()
{
var networkPath = #"file:///192.168.1.1/Share/TestRepo.git";
var uri = new Uri(networkPath);
AssertLocalClone(uri.AbsoluteUri, BareTestRepoPath);
}
That fails with:
LibGit2Sharp.LibGit2SharpException : failed to resolve path 'file://192.168.1.1/Share/TestRepo.git': The filename, directory name, or volume label syntax is incorrect.
I tried mapping a drive letter (Z:) to the share, and ran this:
[Fact]
public void CanCloneALocalRepositoryFromAMappedNetworkDrive()
{
var networkPath = #"file:///Z:/TestRepo.git";
var uri = new Uri(networkPath);
AssertLocalClone(uri.AbsoluteUri, BareTestRepoPath);
}
That fails with:
LibGit2Sharp.LibGit2SharpException : failed to resolve path 'Z:/TestRepo.git': The system cannot find the path specified.
unless I set:
HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\EnableLinkedConnections
to a DWORD value of 1, as per this TechNet article - in which case the clone succeeds. However, this is not a viable solution in my situation, as it raises deployment issues in security-conscious environments.
It appears that LibGit2Sharp is not capable of cloning from a file UNC. Have I understood correctly, and if so is there any way to work around this?
The file:/// URL syntax is not appropriate for UNC paths. Just use a UNC path, eg:
\\192.168.1.1\Share\TestRepo.git
This works in LibGit2Sharp and the git command-line client as well.

Find XML file changes in all branches

I have an XML file in my main TFS branch. I have 50 branches of the main folder. Is there a quick way to check in which branches the file is modified before merging it to the main branch?
I have found that it can be done with CodeLens for code files, but I don't know how to do it for XML files.
You can refer to these steps below:
Create a new workspace
Map these branches (Do not include other mapping)
To do work (e.g. modify files)
Open Team Explorer
Switch to this workspace
Click Pending Changes, then all changes in this workspace will be list.
If these changes are already existing in different workspace, you can check in changes through TFS API (install Microsoft Team Foundation Server Extended Client package to your project).
Simple code to iterate all workspaces in a machine and check in specified changes:
NetworkCredential cred = new NetworkCredential("[username]", "[password]", "[domain]");
TfsTeamProjectCollection tpc = new TfsTeamProjectCollection(new Uri("[collection url"), cred);
tpc.EnsureAuthenticated();
VersionControlServer versionControl = tpc.GetService<VersionControlServer>();
var spaces = versionControl.QueryWorkspaces(null, null, "[machine name, can be null]");
foreach(var currentWorkspace in spaces)
{
var libChanges= currentWorkspace.GetPendingChanges("[server or local path]",RecursionType.Full);
if (libChanges.Count() > 0)
{
currentWorkspace.CheckIn(changes: libChanges, comment: "checkInAPI");
}
}
Update:
You can compare branches.
Open Source Control Explorer
Right click a branch > Compare
Change Target path to target branch server path
Click OK.
On the other hand, there is an TFS Productivity Pack extension you can use.

Checkout using Libgit2sharp on an empty repo

By using git checkout -b <branchname> I am able to create a new branch in an empty repo and the start committing files on that branch. I am not able to achieve this via libgit2sharp. By using repo.Checkout(branchName) it throws following error:
LibGit2Sharp.NotFoundException: No valid git object identified by exists in the repository.
The current version of the native libgit2 library used by libgit2sharp requires a HEAD to exist as it is used during the branch creation. Using a empty(null) committish is valid in the official git version and thus creating a new branch and checking it out works fine on a completely bare repo. Maybe this is covered in the next release and/or an already known bug.
But either way, just create an initial commit that is empty in content and it works:
using System;
using System.IO;
using LibGit2Sharp;
namespace stackoverflow
{
class MainClass
{
public static void Main (string[] args)
{
var rPath = Path.Combine (Path.GetTempPath (), "StackOverFlow");
var rootedPath = Repository.Init (rPath, false);
var repo = new Repository (rootedPath);
repo.Commit ("Initial Commit");
repo.CreateBranch ("EmptyBranch");
repo.Checkout ("EmptyBranch");
}
}
}

How to Move TFS 2010 Build Definition between Projects?

I have some TFS 2010 build definitions that were created under ProjectX. Now the source code has moved to a folder subordinate to ProjectY. How can I move the build definitions to ProjectY so they display under the Builds node of the Team Explorer for ProjectY?
I don't think there is something out of the box to copy the build definitions from one project to another. However you should be able to do it using the TFS API. You will want to move the build process templates, which is what Pete is referring to, into the Build Process Template folder for the new project. After that you would do something like:
var server = TfsTeamProjectCollectionFactory.GetTeamProjectCollection(new Uri("<server uri>"));
IBuildServer buildServer = server.GetService<IBuildServer>();
var buildDetails = buildServer.QueryBuildDefinitions("Project X");
foreach(var build in buildDetails)
{
var buildDefinition = buildServer.CreateBuildDefinition("Project Y");
buildDefinition.Name = "Copy of " + build.Name;
buildDefinition.BuildController = build.BuildController;
// This finds the template to use
buildDefinition.Process = buildServer.QueryProcessTemplates("Project Y")[0];
buildDefinition.ProcessParameters = build.ProcessParameters;
buildDefinition.Save();
}
A couple of things to note. You will need deal with converting the workspace mappings from one project to the other. You will also need to change the buildDefinition.Process line to find the specific template.
A powershell version of Sean's answer above
# Copy some TFS build defintions from one project collection to another
[void][Reflection.Assembly]::LoadWithPartialName("Microsoft.TeamFoundation.Client")
[void][Reflection.Assembly]::LoadWithPartialName("Microsoft.TeamFoundation.VersionControl.Client")
[void][Reflection.Assembly]::LoadWithPartialName("Microsoft.TeamFoundation.Build.Client")
$tfsUrl = "http://lontfs_at:8080/tfs/XXX"
$tfs = [Microsoft.TeamFoundation.Client.TeamFoundationServerFactory]::GetServer($tfsUrl)
$vcs = $tfs.GetService([Microsoft.TeamFoundation.VersionControl.Client.VersionControlServer])
$buildServer = $tfs.GetService([Microsoft.TeamFoundation.Build.Client.IBuildServer])
$buildDetails = $buildServer.QueryBuildDefinitions("Project X");
foreach( $build in $buildDetails)
{
$buildDefinition = $buildServer.CreateBuildDefinition("Project Y");
$buildDefinition.Name = "Copy of " + $build.Name;
$buildDefinition.BuildController = $build.BuildController;
# This finds the template to use
$buildDefinition.Process = $buildServer.QueryProcessTemplates("Project Y")[0];
$buildDefinition.ProcessParameters = $build.ProcessParameters;
$buildDefinition.Save();
}
In VS2010, the TFS Power Tools can move a build definition from one project to another as demonstrated in the 2nd answer in this link: Is it possible to Export TFS 2010 Build Definitions?, and as shown below.
c:\Program Files (x86)\Microsoft Visual Studio 10.0\VC>tfpt
builddefinition /collection:"http://ServerX:8080/tfs/Collection X" /clone "Project 1\Build
Definition X" "Project 2\Copy of Build Definition X"
The TFS Power Tools for VS2010 can be downloaded from: http://visualstudiogallery.msdn.microsoft.com/c255a1e4-04ba-4f68-8f4e-cd473d6b971f
Uggly but very efficient way to move (not to duplicate) only one or two Build Definitions:
Open SQL Server Management Studio,
Open your Collection DB
Edit the table tbl_BuildDefinition
Replace the current GroupId with the target Team Project's GroupId
That's it ;)
To determine the GroupId of the target Team Project, simply find any BuildDefinition of that Team Project in tbl_BuildDefinition and take its GroupId.
For sure, you have next to update the BuildDefinition's workspace, Items to build, ... to use the server path of the new Team Project !
If you get an error like "GroupItem cannot be move accross Team Project" when updating your BuildDefinition, it was most probably already open before updating the DB. Close and reopen it.
If you don't intend to repeat this operation too often, it's IMO the fastest solution.
V.
Build definitions are just another source controled file in TFS, you should be able to open the build definition in ProjectX and save it as a new file to projectY's build definitions folder.
Edit
In the above post I am assuming ProjectX and ProjectY are TFS projects, in which case their workflow build definition(s) are simply in the builddfinitions folder of their respective source control roots.
Sean's answer helped me out, but in my case, I have only one repository for my build templates and custom activities assemblies. So I don't need to edit settings, I just want to copy one build definition from TFS Project A to TFS Project B.
Here is my 'short' version of Sean's code:
var server = TfsTeamProjectCollectionFactory.GetTeamProjectCollection(new Uri("TFS URL"));
IBuildServer buildServer = server.GetService<IBuildServer>();
var buildDetails = buildServer.QueryBuildDefinitions("Proj_A");
foreach(var build in buildDetails)
{
var buildDefinition = buildServer.CreateBuildDefinition("Proj_B");
buildDefinition.CopyFrom(build);
buildDefinition.Save();
}

How do you SetMaxAttachmentSize in TFS 2010?

I want to set the maximum work item attachment size. From old blogs I have found that it is possible by calling SetMaxAttachmentSize, but the blogs are for older versions of TFS. I have found the new webservice path for TFS 2010.
http://localhost:8080/tfs/_tfs_resources/WorkItemTracking/v1.0/ConfigurationSettingsService.asmx/SetMaxAttachmentSize
Unfortunately when I call it like that I receive this error: This request can only be made against a project collection. The (.asmx) file should be located in the project directory (usually _tfs_resources under the application root).
I don't know how to format the call via a browser to target a specific project collection. Any thoughts?
Apparently SetMaxAttachmentSize web service was not leveraged on TFS 2010 therefore you need to do this programmatically, try running the following code:
TeamFoundationServer tfs = TeamFoundationServerFactory.GetServer(#"http://yourtfsserver:8080/tfs/DefaultCollection");
ITeamFoundationRegistry rw = tfs.GetService<ITeamFoundationRegistry>();
RegistryEntryCollection rc = rw.ReadEntries(#"/Service/WorkItemTracking/Settings/MaxAttachmentSize");
RegistryEntry re = new RegistryEntry(#"/Service/WorkItemTracking/Settings/MaxAttachmentSize", "20971520"); //20MB
if (rc.Count != 0)
{
re = rc.First();
re.Value = "20971520";
}
rw.WriteEntries(new List<RegistryEntry>() { re });
I hope it works for you
Regards,
Randall Rosales
I have found that this works. It is easier than writing code.
Go to this url replacing <Collection> with your project collection: http://localhost:8080/tfs/<Collection>/WorkItemTracking/v1.0/ConfigurationSettingsService.asmx
Choose SetMaxAttachmentSize
You can test to make sure you set it correctly by going to the same url above and then selecting GetMaxAttachmentSize.

Resources