Display git branch in Windows command prompt

David's post "Displaying the Git branch in the terminal prompt with and without Perl" reminded me of a batch file I use for the same purpose. Of course, vanilla cmd.exe does not allow dynamic updating of the prompt, so it is rather more limited, but it can still be useful if you spend most of your session within one repo.

Here is the batch file:

@echo off
git.exe %*
set GITBRANCH=
for /f "tokens=2" %%I in ('git.exe branch 2^> NUL ^| findstr /b "* "') do set GITBRANCH=%%I

if "%GITBRANCH%" == "" (
    prompt $P$G 
) else (
    prompt $P $C$E[1;7;32;47m%GITBRANCH%$E[0m$F $G 
)
[ Command prompt showing current git branch ]

git.exe %* invokes the actual git binary with all the arguments that were passed to the batch file. Then, we clear the variable GITBRANCH. In the for statement, we pipe git's output through findstr to pick the line that begins with * which indicates the current branch. The tokens=2 parameter to the for statement causes GITBRANCH to be set twice: First for the * character, and then for the actual branch name, overwriting the * (by default, for /f splits at space and tab characters). When running git to set the branch name, we redirect STDERR to NUL (which is like /dev/null). Both the redirection symbol ">" and the pipe "|" have to be escaped using "^" here.

If GITBRANCH was not set (presumably because we are not in a git repo), prompt is set to my preferred prompt string. Otherwise, we add the current branch name, surrounded by parentheses and highlighted, to the current prompt.

Update: I just had a "d-uh!" moment: David's post has a section called "Bash only" which uses git rev-parse --abbrev-rev HEAD to get the current branch. It is the shell function that is Bash only (obviously, in hindsight). So, we can modify the batch file above to avoid invoking a findstr:

@echo off
git.exe %*
set GITBRANCH=
for /f %%I in ('git.exe rev-parse --abbrev-ref HEAD 2^> NUL') do set GITBRANCH=%%I

if "%GITBRANCH%" == "" (
    prompt $P$G 
) else (
    prompt $P $C$E[1;7;32;47m%GITBRANCH%$E[0m$F $G 
)

It is still useful to know about findstr and the enhanced features of cmd.exe builtins, especially if you find yourself on an isolated Windows system.

Color highlighting will not work unless you are in a console that understands ANSI escapes. AFAIK, cmd.exe versions that came with Vista through early releases of Windows 10 did not. Recent versions of cmd.exe on Windows 10 do. Of course, if you use ConEmu, you don't have to worry about this.

There are several shortcomings to using a wrapper script to set the prompt. The most important one is that the branch name is only updated when you run a git command. If you move to a different repo, you must remember to start with a harmless git command to update the prompt first. In practice, this is not a huge deal, as I tend to just open a tab or pane per repo in ConEmu.

If you use ConEmu exclusively, you can also use the Addons/git_sample.cmd script that comes with it.

For PowerShell, see the answers to the question "How can I display my current git branch name in my PowerShell prompt?" on Stackoverflow or just take a look at posh-git.

Notes

  • More documentation on for is available by running for /? on the command line

  • findstr is the poor person's grep on Windows

  • Incidentally, you can use where to locate all executables in your %PATH% with a given prefix.

PS: You can discuss this post on HN.