Dealing with changes to git default branches

As you may have heard by now, the default git branch name is changing from master to main in most git software (GitHub, BitBucket, GitLab, etc.) to drive out some divisive terminology. A lot of tutorials I see include scripts and aliases that depend on the default branch name being master, and those tools may be broken now, leaving you and your users with some issues after the migration is completed server-side.

The good news is that the default branch isn’t just a “thing you know”, it can be extracted dynamically from a git repo. Doing so is a very simple piece of code:

git symbolic-ref refs/remotes/origin/HEAD | sed 's@^refs/remotes/origin/@@'

You can integrate this into any other aliases or scripts you have. For example, in my .bashrc, I’ve replaced these branch-specific aliases:

alias updatemaster='git checkout master && git fetch origin --prune && git fetch origin --tags && git pull origin master'
alias updateprod='git checkout production && git fetch origin --prune && git fetch origin --tags && git pull origin production'

with this single non-specific alias:

alias updateorigin='git checkout $(git symbolic-ref refs/remotes/origin/HEAD | sed 's@^refs/remotes/origin/@@') && git fetch origin --prune && git fetch origin --tags && git pull origin $(git symbolic-ref refs/remotes/origin/HEAD | sed 's@^refs/remotes/origin/@@')'

And for my VS Code setup on Windows, where I use a PowerShell terminal instead of WSL/bash, my .gitconfig contains an alias for git up:

up = !"git checkout $(git symbolic-ref refs/remotes/origin/HEAD | sed 's@^refs/remotes/origin/@@'); git fetch --prune; git pull"

Regardless of whatever system you use, now is a good time to start replacing any hardcoded instances of master and replace it with a more dynamic reference so that changes to the default branch are transparent to you. Share this information with your coworkers and update your training and new hire documents and your whole company can make the transition smooth, too.

Announcement: Github repo for common vCenter roles

Last week, I was installing some of the vRealize Suite components and was creating accounts for each component using the Principle of Least Privilege. I was sometimes able to find vendor documentation on the required permissions, sometimes I found a few blog posts where people guessed at the required permissions, but in almost no cases was I able to find automated role creation. Perhaps my google-fu is poor! Regardless, I thought it would be nice to have documented and automated role creation in a single place.

To that end, I created a repo on GitHub called vCenter-roles. I use PowerCLI to create a role with the correct permissions, and only the correct permissions. Each cmdlet will allow you to specify the role name or it will use a default. For instance, to create a role for Log Insight, just run the attached ps1 script followed by the command:


It’s that easy!

I will be adding some other vRealize Suite roles as I work my way through the installation, but there are tons of other common applications out there that require their own role, and not just VMware’s own applications! I encourage you to open an issue or submit a Pull Request (PR) for any applications you use. The more roles we can collect in one place, the more helpful it is for the greater community. Thanks!

Getting a fresh start in a Git repository

Sometimes, the software in a git repository you work with starts to act wonky, especially when running tests, and for no particular reason that you can discern! I saw this recently when I was playing with bundler in some puppet module repos I was setting up to use Travis CI. My rspec tests started failing with nonsensical errors, such as saying it couldn’t find a class that was very much present on disk. What’s worse is that I did a fresh clone of the repo from GitHub into another directory and it worked flawlessly! What the hell? Thankfully, a little kvetching on twitter led to some help from David Schmitt:


David dropped some great wisdom here (thanks!). Let’s unpack it and understand it.

Continue reading

Commitmas 2015 Is Coming!

Last year, Matt Brender created the 12 Days of Commitmas, a short series of goals and articles on how to get started with Git and make it part of your daily workflow. This year, with the help of the vBrownBag crew, we’re making it bigger and better and calling it the 30 Days of Commitmas! Every workday between 12/1 and 12/30, excepting the 24th and 25th, there will be a new lesson paired with a recorded webinar. The lessons will be focused on a small goal and in the webinar, the presenter will run through the lesson plan and answer any questions presented. I’ll be presenting Rebasing with Git on 12/11.

If you’re relatively new to Git, or know it but haven’t made it part of your daily routine, I encourage you to jump in! We’ll have a little something for people of all skill levels. If you can’t participate in real time, the lessons and recorded webinars will also be available afterward.

If you know Git well, or at least well enough to give a 30-60 minute presentation to others, we could use your help! We need 8 more presenters, as of hitting publish on this post. For those interested in presenting, find an opening on the schedule (webinars are scheduled for 9pm Eastern, we may be able to make some exceptions) and reach out to me, Matt Brender, Cody Bunch, or Jonathan Frappier – or create a fork and submit a PR!

I hope to “see” you all there!

Customizing bash and vim for better git and puppet use

Welcome back to our Puppet series. I apologize for the extended hiatus and thank you for sticking around! As an added bonus, in addition to inlining files, I’m including links to the corresponding files and commits in my PuppetInABox project so you can easily review the files and browse around as needed. I hope this is helpful!

Today, we will look at improving our build server. The build role is a centralized server where we can do our software development, including work on our puppet code and creating packages with FPM. When we work with git, we have to run git branch to see what branch we’re in. If you’re like me, this has led to a few uses of git stash and in some cases having to redo the work entirely once you start committing on the long branch. To help, we’re going to add the currently-active branch name of any git directory we are in to the PS1 prompt. We also are doing a lot of edits of *.pp files and we don’t have any syntax highlighting or auto-indenting going on. We can fix that with a few modifications, and we’ll discuss where additional customizations can be made.

Continue reading

Preventing Git-astrophe – Judicious use of the force flag

I’d like to tell a tale of a git-astrophe that I caused in the hope that others can learn from my mistakes. Git is awesome but also very feature-ful, which can lead to learning about some of those features at the worst times. In this episode, I abused my knowledge of git rebase, learned how the -f flag to git push works, and narrowly avoided learning about git reflog/fsck in any great detail.

Often times, you will need to rebase your feature branch against master (or production, in this case, it was a puppet controlrepo) before submitting a pull request for someone else to review. This isn’t just a chance to rewrite your commit history to be tidy, but to re-apply the changes in your branch against an updated main branch.

For instance, you created branch A from production on Monday morning, at the same time as your coworker created a branch B. Your coworker finished up her work on the branch quickly and submitted a PR that was merged on Monday afternoon. It took you until Tuesday morning to have your PR ready. At this time, it is generally adviseable to rebase against the updated production to ensure your branch behaves as desired after applying B‘s changes. Atlassian has a great tutorial on rebasing, if you are not familiar with the concept.

Continue reading

Improved r10k deployment patterns

In previous articles, I’ve written a lot about r10k (again, again, and again), the role/profile pattern, and hiera (refactoring modules and rspec test data). I have kept each of these in a separate repository (to wit: controlrepo, role, profile, and hiera). This can also make for an awkward workflow. On the other hand, there is great separation between the various components. In some shops, granular permissions are required: the Puppet admins have access to the controlrepo and all developers have access to role/profile/hiera repos. There may even be multiple repos for different orgs. If you have a great reason to keep your repositories separate, you should continue to do so. If not, let’s take a look at how we can improve our r10k workflow by combining at least these four repositories into a single controlrepo.

Starting Point

To ensure we are all on the same page, here are the relevant portions of my Puppetfile:

Continue reading

Updating your git fork from the original repo

Over the 12 days of #Commitmas, you may have submitted a Pull Request (PR) to Matt Brender’s 12-days-of-commitmas repository. I’ve done the same thing. Once the PR is merged, your fork is out of sync with the main repository. If you do more development on your fork, you may start to run into conflicts when you submit the next PR.

Adding additional remotes

When you set up your fork, github (bitbucket, etc.) helpfully provides you with the repository’s remote information in HTTPS or SSH format (see Jonathan Frappier’s article on forking for more information). After you clone your fork’s repo, you’ll have a single remote called origin. You can see your remotes with git remote -v.

git remotes fig 1

We can handle PRs through the github interface, but that doesn’t help us keep things in sync (well, you could delete your fork and make a new one, but that’s a lot of work and wipes out any pending changes you’ve made, so we’ll consider that unfeasible). The best way to manage this is to add the original repo as another remote. The remote can be called anything you want. We will call it upstream, a common pattern with github users.

git remotes fig 2

As you may remember, you provide the keyword origin to your push statement. That’s not a magic word, it’s referring to the remote to which you are pushing your commit history to. Most of the time you don’t have rights to push to someone else’s repo, but git push upstream <branch> is a legitimate git command. You can also use the upstream remote with other commands.

Fetch and Pull

You can fetch the latest information from the remove with git fetch upstream. This will pull down all references and branch names. You can then git pull upstream master to fast-forward apply all changes in the upstream’s master branch to your current branch. I made sure to make sure I’m in my own master branch before I began, but you could do this in any branch – great if you started some edits based off master and a few PRs have been applied since.

git remotes fig 3

Once you’re done, don’t forget to push changes to YOUR remote. You don’t technically need to do it, but if you work on another machine, you’d have to perform the whole clone/remote add/fetch/pull process again.

git remotes fig 4

Now you’re able to see all the changes made in the repo and you’re able to base new branches off the up-to-date contents of your master branch!

Using git amend for quick corrections

Now that you know how to rewrite your git history with rebase, let’s take a look at amending your commits. An amend is much simpler and, for the case of typos or other minor corrections you discover immediately after a commit, sometimes much more appropriate.

For the setup, we’re going to add some markdown to the 12-days-of-commitmas repository’s, but with incorrect tags. A URL is of the format “[text to display](url://to/visit)”. It’s easy to get this backwards or to use the same tags on both sides of the URL. Here, I’ve used square braces for the URL and commited it anyway. Whoops!

git amend fig 1

Continue reading

Using git rebase to rewrite history

As part of The 12 Days of #Commitmas, we’re all practicing our git-fu. I’ve learned a bit about rebasing that I’d like to show you now.

Why are we rebasing?

The definition, from man git-rebase, is “Forward-port local commits to the updated upstream head.” Clear as mud, if you ask me. Another way of putting it is that a rebase moves a branch to a new base commit. Let’s say you create a new branch from master on the 1st of the month and make two changes, then a week goes by. A half dozen changes have been made to master and your branch doesn’t have it. You can rebase your commits against the current master rather than the original master. Underneath the hood, git is rewriting the project history to achieve all of this. All the commits are actually new. This means the checksums for commits are unique (we’ll look at why that matters in a moment).

This is great for integrating your feature against the master and maintaining a linear history. There’s another reason we might want to rebase, though – maintaining a clear history.

Continue reading