dotnet-gitmoji for .NET

Clean git history,
from your next commit

dotnet-gitmoji brings the gitmoji commit convention to .NET projects. It installs a prepare-commit-msg hook through Husky.Net, so the hook travels with the repo and is ready on every teammate's first commit.

dotnet tool install dotnet-gitmoji

then 5 quick steps to wire the hook β†’

Get started GitHub

Two minutes, from an empty repo to a teammate's first gitmoji commit.

Before and after

Your old history stays the way it was. Every commit from the setup onward follows the gitmoji convention.

dotnet-gitmoji-demo
❯ git log --oneline
75cef59 (HEAD -> main) πŸ“ Document auth endpoints
22f1b0b ♻️ Extract auth service
2a6c8a6 ✨ Add password reset endpoint
d5bdbdc πŸ› Fix login redirect
62849bc πŸ”§ Add dotnet-gitmoji hook
9e79328 fix for real this time
3fba982 final fix
b9d9153 wip 2
d2c6acd Update appsettings.json
f6c8590 fix build
7afe3cf changes
3d45706 asdf
ee9a912 fix
0bcc0d1 wip
66ae352 Update Program.cs
51b4882 Initial commit

Set it up once

One developer runs these steps and commits the result. After that, every teammate gets the hook automatically.

Requires the .NET 10 SDK or later. On Windows, also Git for Windows: the hook runs under Git Bash.

  1. Add both tools to the local tool manifest

    Pins Husky.Net and dotnet-gitmoji to the same versions for the whole team.

    dotnet new tool-manifest   # skip if the repo already has a dotnet-tools.json
    dotnet tool install Husky
    dotnet tool install dotnet-gitmoji

    Creates dotnet-tools.json at the repo root. SDKs before .NET 10 create .config/dotnet-tools.json; both work.

  2. Initialize Husky.Net

    Points git's hooks path at .husky/ and adds the Husky.Net helper scripts.

    dotnet tool run husky install
  3. Install the gitmoji hook

    Adds a prepare-commit-msg hook to .husky/. It's plain text and safe to commit.

    dotnet tool run dotnet-gitmoji init --mode shell
  4. Add the MSBuild target

    Create Directory.Build.targets at the repo root. It runs dotnet tool restore and dotnet husky install whenever a teammate restores, builds, or opens the project in Visual Studio or Rider. Set HUSKY=0 in CI to skip it.

    Directory.Build.targets
    <Project>
      <PropertyGroup>
        <HuskyRoot Condition="'$(HuskyRoot)' == ''">$(MSBuildThisFileDirectory)</HuskyRoot>
        <HuskyToolManifest Condition="'$(HuskyToolManifest)' == '' and Exists('$(HuskyRoot)dotnet-tools.json')">$(HuskyRoot)dotnet-tools.json</HuskyToolManifest>
        <HuskyToolManifest Condition="'$(HuskyToolManifest)' == ''">$(HuskyRoot).config/dotnet-tools.json</HuskyToolManifest>
      </PropertyGroup>
      <Target Name="Husky" BeforeTargets="Restore;CollectPackageReferences" Condition="'$(HUSKY)' != 0"
              Inputs="$(HuskyToolManifest)"
              Outputs="$(HuskyRoot).husky/_/install.stamp">
        <Exec Command="dotnet tool restore"
              StandardOutputImportance="Low" StandardErrorImportance="High" />
        <Exec Command="dotnet husky install"
              StandardOutputImportance="Low" StandardErrorImportance="High"
              WorkingDirectory="$(HuskyRoot)" />
        <Touch Files="$(HuskyRoot).husky/_/install.stamp" AlwaysCreate="true"
               Condition="Exists('$(HuskyRoot).husky/_')" />
        <ItemGroup>
          <FileWrites Include="$(HuskyRoot).husky/_/install.stamp" />
        </ItemGroup>
      </Target>
    </Project>

    Don't use husky attach instead. Husky.Net 0.9.1 writes a target that doesn't fire on a solution-level dotnet restore and hardcodes .config/dotnet-tools.json, which .NET 10 no longer creates. Why, and a caveat for private feeds

  5. Commit everything

    The hook is already active, so this commit gets a gitmoji too.

    git add dotnet-tools.json .husky/ Directory.Build.targets   # or .config/dotnet-tools.json on older SDKs
    git commit -m "chore: add dotnet-gitmoji hook"

Joining a repo? Just restore

If the repo already has a .husky/ folder and Directory.Build.targets, one command is all it takes. Opening the project in Visual Studio or Rider works too.

dotnet restore

Use dotnet restore, not dotnet tool restore. The latter only installs tools and never runs MSBuild, so the hooks path is never set and the gitmoji prompt silently doesn't appear.

No project file to trigger a restore? Run the two steps by hand:

dotnet tool restore
dotnet tool run husky install

To remove the hook, run dotnet tool run dotnet-gitmoji remove and follow the cleanup steps it prints.

Commit like always

After setup, commit normally. The gitmoji picker opens: type to search, press Enter to pick.

git commit
git commit -m "fix login redirect"   # message pre-filled as the title suggestion

The hook skips itself during merges, squash merges, amends, and interactive rebases.

Make it yours

Run the wizard. It walks through every option and saves your answers to .gitmojirc.json at the repo root, except the color theme, which goes to your personal config. Commit that file so every contributor follows the same convention.

dotnet tool run dotnet-gitmoji config
{
  "emojiFormat": "Emoji",
  "scopePrompt": true,
  "maxTitleLength": 48,
  "normalizeCommitFormat": false,
  "enforceConvention": true
}
emojiFormat
Prefix with the emoji (πŸ›) or its shortcode (:bug:).
scopePrompt
Also ask for a scope, like feat(auth): ....
maxTitleLength
Longest allowed title; null turns the check off.
normalizeCommitFormat
Write emoji: title with a colon, conventional-commit style.
enforceConvention
Reject commits without a gitmoji when there's no interactive terminal, such as IDE commits.

Themes are personal. The color theme is never read from .gitmojirc.json; set it with DOTNET_GITMOJI_THEME or in ~/.dotnet-gitmoji/config.json.

Every option and theme in the README β†’

Credits

dotnet-gitmoji builds on these open-source projects, all under the MIT License.