Monthly Archives: March 2019

Working out when something broke using Git Bisect and Git Log

On 5th Feb, I attended DDD North. There were many excellent talks on the day, but in this post, I’m delving into something that I saw in one of the grok talks (I gave one myself). It concerns a feature of git that I’d never heard about until then, and it’s proved to be enormously useful. This post is, as all of my posts are, really for myself.

Something has broken

You’re giving the app a quick test, and suddenly you realise that something in the application has stopped working (or maybe it’s started, but it shouldn’t have). You remember that two days ago, this particular thing was working fine. This post is going to cover manually using git bisect to determine when your code was broken.

Get the good commit

To use git bisect, you need a good commit and a bad commit. Obviously, git doesn’t know what’s good or bad, so you could use it to determine when something was changed, added, or removed. Providing the behaviour is different, you can identify it.

If you know the date of the ‘good’ commit, you can ask git for the logs after that date. To list commits after a given date:

git log --after="2019-03-19T00:00:00-00:00"

This will give you all the commits (you can add a ‘–before’, too if you’re dealing with a long time ago. When you get the git Commit Id, make a note of it; for example:

Bc1afa359dc98b899cc4194ec8130a6229643172

Let’s do some bisecting

You start the bisect process by:

git bisect start

At all times through this process, git does precisely nothing to help you along, so if you even get an acknowledgement of your command you should consider yourself lucky!

The next step is to tell git that the current release is bad:

git bisect bad

You can give it a commit here that isn’t the current release, if you so choose.

The final step to start the process is to tell it where to start – i.e. what was the last known good release. This is your commit Id from earlier:

git bisect good Bc1afa359dc98b899cc4194ec8130a6229643172

What git does here is a binary chop. So the first code it will check out will be halfway between the two commits. It then tells you nothing (as usual). Now that it’s checked out the code for you, run your application with the code and see whether it is ‘good’ or ‘bad’. Once you’ve determined that, go back to git and tell it:

git bisect good

Or:

git bisect bad

Each time you tell it it’s good or bad, it will check out new code, and you need to test again:

(apologies for all the redacting)

Finally, it will determine which commit was the first bad one, and report back:

$ git bisect bad
Eea8e3d72fcb26cdebb2dbf2c13fdd88d7f3782a is the first bad commit
commit Eea8e3d72fcb26cdebb2dbf2c13fdd88d7f3782a
Author: Ian Kilmister <[email protected]>
Date:   Wed Mar 20 11:49:18 2019 +0100

    New lyrics

Once you’re done, you need to reset – this will book out the code you had out before you started:

git bisect reset

Read a Document in a .Net Core Application Baked into the Project File

This isn’t a difficult thing to achieve, but it is one that frequently has me reaching for Google to get the exact syntax. By creating this post (I create all my posts on OneNote first), it’s now offline for me.

There’s more than one way to do this; I’ve covered two. All the examples here are using a CSV file from an Assets folder:

Embedded Resource

These are embedded into the compiled assembly; which means in order to change them, you would need to recompile your code. This works well for images, but less well for data files.

First, you need to add your resource to your project, and set the properties to be an embedded resource:

Because it’s embedded, copying makes no sense. To read the file:

public string GetResourceTextFile(string filename)
{
    using Stream stream = this.GetType().Assembly.
                       GetManifestResourceStream($"SalesOrder.Generate.{filename}");
    using StreamReader sr = new StreamReader(stream);                           
            
    return sr.ReadToEnd();
}

Content

This allows you to include a file within your project; however, content files are not compiled. Combined with the “Copy To Output Directory” they place files in the binary directory of your project. The advantage here is that you can change this file after compilation:

Because this just copies the file to the executing directory, it’s easier to read the file:

public string GetContentTextFile(string filename)
{
    return File.ReadAllText($"Assets/{filename}");
}

References

https://stackoverflow.com/questions/145752/what-are-the-various-build-action-settings-in-visual-studio-project-properties

My XUnit Tests won’t run in a .Net Standard 2.0 Class Library

Firstly, this isn’t a bug, or something that you might have done wrong; it’s intentional. Essentially, you can’t run a .Net Standard Library, so your tests aren’t runnable.

Okay – so I want to convert to .Net Core 3.0!

Yep – that’s exactly what you want, and it’s this easy; open up the csproj file – it’ll look like this:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>netstandard2.0</TargetFramework>
  </PropertyGroup>

And replace it with this:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>netcoreapp3.0</TargetFramework>
  </PropertyGroup>

And that’s it – your tests should now run!