Thursday, 7 March 2013

Seeing an NGit Diff by using reflection to access the internal Sharpen.ByteArrayOutputStream Class

I was trying to get the NGif diff output stream, but hit on an issue that the Sharpen.ByteArrayOutputStream class is internal


Here is an example from NGit UnitTests on how to use the NGI Diff Command:

image

The key part is:

image

Note how the Sharpen.ByteArrayOutputStream was created and used on Diff.SetOutputStream , but (as we will see below), we will have a problem because  this class is internal:

image

On an O2 Platform C# REPL script, lets create a quick repo and a valid Diff result:

image

Our objective is to get the Diff formatted output shown in the NGit Unit test.

A quick look at the Diff class, shows no public fields, properties or methods that expose it:

image

And by default the out field is null:

image

Basically what we need to do is this:

image

But as you can see, we can’t create an instance of the Sharpen.ByteArrayOutputStream

Well, we can’t create it directly, but we can easily create it using reflection :)

To do that, lets start by getting an reference to the Sharpen.dll assembly

image

then add a reference to the ByteArrayOutputStream  type

image

invoke its constructor to create a live instance of it:

image

since the Sharpen.OutputStream class is public, we can cast our ByteArrayOutputStream  object into it:

image

we then assign it to the NGit command, which will give us the diff log we wanted

image

Note that the out field is now not null:

image

Here is the Source code of the C# code snippet created:
var outputStream = "Sharpen.dll".assembly()
                                .type("ByteArrayOutputStream")
                                .ctor()
                                .cast<OutputStream>();


var tempRepo    = "tempRepo".tempDir();
var nGit        =  tempRepo.git_Init();

var file        = "testFile.txt";
nGit.writeFile (file, "some content\naaaa\n");
nGit.add       (".",false).commit_using_Status();
nGit.writeFile (file, "some content\naa Change\n");

var diff      = nGit.Git.Diff();

diff.SetOutputStream(outputStream).Call();
return outputStream.str();

//using Sharpen
//O2Ref:FluentSharp.NGit.DLL
//O2Ref:NGit.dll
//O2Ref:Sharpen.dll