The power of git is its CLI and scripting abilities. That of course means it is less-than-friendly for a Windows GUI guy.
Or is it?
I was recently trying to automate a simple git script in Windows to automatically do a fetch and merge (I know this is a bad idea, but I had my reasons) for all git repositories on my local machine. Basically I have a folder tree where I keep my source code with subfolders for each remote repository I connect to...something like the structure on the right. Most of these repos I use solely for code review purposes and rarely change any of the code, hence why I'm cool with fetch and merge (or pull if you will). Even in the rare cases where I do want to make changes it is almost always master branch.
Anytime I want to automate something in Windows I use Powershell. To manipulate git on Windows requires loading Git Bash from within Powershell using some variant of loading a Bash shell in a DOS shell in a Powershell shell. Kludgey. it also makes error-handling unreliable.
Some simple googling turned up the posh-git Powershell module.
F'ing awesome module.
If you ever longed for the day where git used more normal DOS style-syntax, this is the day. The author was very ingenious. Instead of creating PoSH commands that wrap git commands (for instance, invoke-gitfetch, or something stupid like that), which would require us to learn another set of git CLI commands, posh-git actually uses the standard git commands. With tab-completion of commands too.
When you "cd" into a git-enabled folder your Posh prompt even tells you what branch you are currently on without any extra intervention. Note the screenshot on the right. Ignore the error, that's totally unrelated to posh-git...it's something I'm experimenting with.
Note the extra "stuff" in brackets. master is the branch. It's in cyan meaning it's in sync with its remote. The other options in burgundy indicate the number of files that you have added/modified/removed/conflicted. It basically did a git status without you having to.
In any case, I could rave about posh-git for a long time. Just note that it helps you automate git on Windows.
Installing posh-git (or any module) Automatically -- Best Practice Pattern
When writing an automation routine it is best to never assume that the host running the script has all of the requisite software installed and environment configured correctly. You never know when someone will run the script on an environment that isn't up-to-snuff. In the Linux world (Ubuntu and equivalents, really) you can code your scripts to perform an apt-get which will get the required software if it isn't present. Under the covers these things are using curl and wget to download and install what is needed.
We have no concept of this natively in Windows but that doesn't make it right. gitFetchAll.ps1 is a Posh script that I will use for the remainder of this blog post. I wrote a function called loadPoshGit that will load the module regardless of whether it is even currently installed. The code to do that is very simple. I really like using this pattern in all of my code where I have a dependency on some small utility that may not be available. This helps out an Ops Guy that may not know or remember where that certain utility can be found. This pattern will work for any piece of code that is downloadable from your machine.
Automating git on Windows
Now that we can guarantee we have posh-git installed and loaded into our profile we can run some git commands. gitFetchAll.ps1 is the script I wrote that takes a folder structure of git repositories and remotely fetches and merges any new changes. Here isthe guts of the script:
$RootFolder is declared by you. We find every $subfolder in that $RootFolder and traverse it, calling
git pull (fetch and merge) in every folder.
That is ridiculously easy.
Let's see what this looks like:
- I first perform a cd to get to my script location
- Then I launch powershell and call gitFetchAll.ps1 in a single command
- Ignore the WARNING...that's an artifact of some other testing I'm doing with git (my ssh is currently broken on my laptop)
- You can see that I then cd into each folder and call
- ...which gets me the latest code on the remote repo if it can
- ...or simply notifies me that the code is "Already up-to-date"
One last pattern: pushd and popd
One last pattern I like to do is on Line 62 above. The
popd command. Whenever I have a Posh script that does a "cd" I ensure that I first capture the user's pwd (print working directory) using
pushd. I then ensure that I exit the script in the same folder, using
popd. It's obnoxious to find scripts that don't do that and it makes automation routines difficult when a script has "side-effects" such as changing your working folder.
I use this script every morning to get the latest from my remote repos. It illustrates how to automate git on Windows using Powershell which is much less kludgey than cygwin. The script is lacking good error-handling but I don't require it for my needs and I just wanted to demonstrate some useful git automation routines. I also outlined two other patterns I like to use in my Posh scripts...auto-installing helper utilities if they are mising and using pushd and popd to ensure your scripts have no side-effects.
You have just read git and Powershell Integration on davewentzel.com. If you found this useful please feel free to subscribe to the RSS feed.