.NET Revision Tool

Injects the current VCS revision of a working directory in a custom format into a .NET assembly build or just displays it.

This application has been replaced by .NET Revision Task for MSBuild. That is available as NuGet package and integrates with MSBuild which makes it more robust and powerful. It also supports .NET Core/Standard projects.

.NET Revision Tool is a small developer’s tool that prints out the current Git or SVN revision info of a working directory. It can automatically write that revision information into your application’s code so that it's compiled right into it. This works for .NET solutions written in C# and VB.NET using the regular Visual Studio project structure.

Currently the following VCS (version control system) are supported:

  • Git
  • Subversion

More systems can easily be added in the code.

Why?

Every bigger-than-small application has a version number that the user can query in some form of About dialog window. If you release often and don’t want to manage semantic version numbers like major.minor.patch (as for .NET Revision Tool itself), you might just use the Git or SVN revision identifier or commit time as version number for your program.

By automating the copying of that revision ID into the application source code, you can avoid forgetting that update. Also, possible keyword replacing features of Git/SVN itself do not play very well with C#/VB.NET source code in creating a friendly version for that assembly. .NET Revision Tool is optimised for this scenario and can adapt to special wishes.

How can I use it?

Version format and source code

At first, you need to decide on a versioning scheme. There are plenty of possibilities, some of them depend on the VCS being used. The revision format is specified as a string with placeholders. I’d like to introduce three schemes.

  • For SVN repositories the obvious solution is the sequential revision number. It can be used as one component of the version number, e. g. 1.0.{revnum} or 4.{revnum}. When the number is growing too big it can be adjusted with an offset.
  • In Git repositories such a stable increasing number does not always exist*. Instead you can encode the commit time into a version specification. (You better only publish releases from one branch in one repository then.) To keep the numbers in a reasonable range a base year when the counting begins is required. The decimal scheme uses two numbers: The number of days since the base year, and the number of time intervals on that day (here quarter-hours). 1.{dmin:2015} for instance produces version numbers like 1.2345.67 after three years. The first number (1) can be incremented later to switch the base year or the scheme altogether.
  • The simple format {c:ymd.} directly prints the complete date of a commit (year.month.day), e. g. 2015.01.27.

*) If you regard only a single branch for releases, e. g. the master branch, and all changes are merged into it from other branches (not in the opposite direction!) then you can count the commits in this branch. This number is always provided by .NET Revision Tool in the placeholder {revnum}. You should only use it under the mentioned conditions though! Further details are explained in the article Maintaining a consistent linear history for git log --first-parent (corresponding workflow).

These schemas produce regular numeric version IDs. These can be used for the attributes Assembly­Version and Assembly­File­Version. (StackOverflow has a thorough explanation of the differences between version attributes.) .NET Revision Tool only fills out the attributes that already exist in the source code and will not add new attributes!

To include further data like the commit hash into the version ID you need the Assembly­Informational­Version attribute. Only that one can take arbitrary free text. The Windows file properties present this value separately under „product version“. There is the convention that this format should begin with a simple version number followed by any other character than a digit or dot. So the long version ID can automatically be truncated and be used in the simple attributes (defeatable). Example: 1.{dmin:2015}_{chash:6} (time-based version number followed by 6-char hash)

If you only use a short format, you can either specify it for the .NET Revision Tool call with the /format parameter, or store in the source code as the content of the Assembly­Informational­Version attribute. In the latter case the placeholder string is defined directly in the source code and won’t go lost somewhere in the build process. A long format must always be defined in this attribute because it will always be read from there for the replacing. Open your project’s AssemblyInfo.cs or .vb file in the folder “Properties” resp. “My Project”. Look for the Assembly­Informational­Version attribute or add it if it’s not there yet. Here are a few examples:

// Simply version Attributes, no matter the content
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

// Free text attribute contains format string, here SVN
[assembly: AssemblyInformationalVersion("1.0.{revnum} {c:ymd-}")]

// Alternatively, Git time code and commit hash (in the screenshot)
[assembly: AssemblyInformationalVersion("1.{dmin:2015}_{chash:6}{!}")]

.NET Revision Tool will replace it into something like the following for the compiler:

// SVN
[assembly: AssemblyVersion("1.0.627")]
[assembly: AssemblyFileVersion("1.0.627")]
[assembly: AssemblyInformationalVersion("1.0.627 2015-01-27")]

// Git
[assembly: AssemblyVersion("1.39.50")]
[assembly: AssemblyFileVersion("1.39.50")]
[assembly: AssemblyInformationalVersion("1.39.50_a34fd2")]

Build process

Then download the application and copy it to your Visual Studio solution directory. I like to put such little helpers in a subdirectory called “_scripts\bin” (see screenshot below), along with the PowerShell build framework (which already includes this program). You should include that file into your repository to keep it portable. Make sure the file is not ignored by adding a line like this to your .gitignore file, if necessary:

!_scripts/bin/

Then, open your project properties and switch to the “build events” page (see screenshot below). Add the following pre-build command:

"$(SolutionDir)_scripts\bin\NetRevisionTool.exe" /patch "$(ProjectDir)"

Adapt the path if you used a different directory. Also add the following post-build command:

"$(SolutionDir)_scripts\bin\NetRevisionTool.exe" /restore "$(ProjectDir)"

Important: Set the post-build event to be executed always to ensure the modified source file is always restored correctly, also when your project doesn’t build correctly.

The PowerShell build framework (psbuild) always uses .NET Revision Tool in multi-project mode where all projects in a solution are processed in a single run. For many (like > 20) projects, this is much faster than calling it for each project separately. psbuild and NetRevisionRool will automatically coordinate in this case. If you only need .NET Revision Tool within psbuild, like on a build server, then you can leave it out in the project configurations.

Additional documentation

See the program’s output for the /help parameter for all the details. There’s more placeholders to create compact, sortable version IDs, the option to require an unmodified working directory and other useful things waiting for you.

How does it do what it does?

.NET Revision Tool is called in the pre-build event with the parameter /patch. This is every time you build the project, before the compiler starts off. It will find your AssemblyInfo.cs or .vb file and replace all your placeholders in the version attributes to the actual revision data. Then Visual Studio includes that file in the compilation process. In the end, the /restore parameter restores the previously backed up file so that you (and the VCS) won’t see any changes to commit.

Compatibility: .NET Version 4.0 or newer Windows 10 Windows 8 Windows 7 Windows XP Mono 64 bit

This tool is based on the two older programs GitRevisionTool and SvnRevisionTool and unifies and extends their features.

Images

Image
Tools im bin-Verzeichnis
Image
Build-Ereignisse im Projekt
Image
Versionsangabe in den Dateieigenschaften

Download

NetRevisionTool.exe64 KiBProgram file, version 2.5.1

master.zipLatest source code directly from GitHub

There’s a public Git repository of .NET Revision Tool on GitHub.

It doesn’t work?

Important: For this to work, the AssemblyInfo file must not be opened in the Visual Studio editor during build, or the things that .NET Revision Tool writes into the file will be ignored for that build (only up to Visual Studio 2013, it doesn’t matter from 2015 on). So always close that file as long as you are tweaking your version string and test-building the project.

For Git: .NET Revision Tool needs Git for Windows installed on the system. It goes looking for bin\git.exe in directories it finds from its uninstaller entry or scans your Program Files directory. If it can’t find Git, it can’t help you either. You should be good to get msysGit and just install it with default settings. See Github’s nice documentation for help on that.

For Subversion: .NET Revision Tool needs an installed SVN program. This will be searched automatically in several locations, among them the installation directory of the Apache SVN client as well as TortoiseSVN (with selected CLI option).

.NET Revision Tool can only modify your C# or VB.NET project files. It won’t do anything but print the revision information (albeit formatted the way you want) for other project types. You may need to create a CMD script to hack files on your own. Set the format string to something like SET revid={chash:8}, redirect the output to a temporary batch file (outside of the working directory, or that will always be unclean!), call that, and edit source files using the %revid% environment variable with sed or another tool. Be sure to backup and restore the code file.

This is a .NET application itself. It is targeted on the .NET 4.0 framework, so you should not have any problems on Windows 7 (with automatic updates) or later. If you use Visual Studio 2010 or later, you already have the .NET framework installed anyway.

Changes

2018Feb3
Version 2.6.3
  • Fixed #20: ConsoleHelper Unicode detection throws an exception; Some code cleanup
2017Apr6
Version 2.6.2
  • Updated environment variables for GitLab CI runner v9.0
2017Jan4
Version 2.6.1
  • Finding git.exe from SmartGit local installations
2016Dec2
Version 2.6
  • Finding git.exe from SourceTree and Tower local installations
  • Added {mname} placeholder resolving to the machine name
  • Added /echo option to display the resolved informational version string
2016Aug10
Version 2.5.2
  • Detect GitLab CI runner and try to determine branch name from environment variables if necessary
2016Jun14
Version 2.5.1
  • Fixed console redirection detection for "nul"
2016May16
Version 2.5
  • Added /removetagv option to make version number tag names useful
  • Added copyright year resolving, opt-out with /nocopyright option
2015Dec21
Version 2.4
  • Added Git tag support
2015Dec1
Version 2.3.3
  • Optimised detection of Git for Windows 2.x
2015Jul28
Version 2.3.2
  • Added global exception handler
  • Retrying to write file on IOException (observed if VS2015 is still open with the project)
2015Apr21
Version 2.3.1
  • Fix: All Git directories are considered modified
2015Apr14
Version 2.3
  • Revision number generation for Git repositories using --first-parent
  • Removed unused shared code to reduce executable file size
2015Apr2
Version 2.2
  • /revonly can be used with a revision format that produces an integer number
2015Mar11
Version 2.1
  • New revision data fields (author time/name/mail, committer name/mail, repo URL, branch)
  • Truncated version number check
  • New hours time scheme
  • Added /root and /rejectmix parameters
2015Feb9
Version 2.0.1
  • Fixes for relative paths and SVN
2015Feb8
Version 2.0
  • First release based on GitRevisionTool and SvnRevisionTool 1.8

Licence and terms of use

This software is released under the terms of the GNU GPL licence, version 3. You can find the detailed terms and conditions in the download or on the GNU website.

Statistic data

  • Created on 2015-02-08, updated on 2018-02-03.
  • Ca. 2 160 lines of code, estimated development costs: 2 200 - 8 600 €