Monday, November 30, 2015

Filtering standup mail at Pivotal

One of the great traditions at Pivotal is daily standup, which is not only filled with business things but also contains some nice updates on local events, new people and general interesting things.  In the good spirit that we should be aware and know about the other Pivotal Labs around the world, standup notes from all labs are sent to all pivots.

To declutter my otherwise pretty empty inbox I decided to filter these other standup messages in a 'standupOther' label, so I can read them when I have the time.  This is not as simple as it should be in Gmail:  There are many labs and they number is constantly increasing, so the right solution is to filter my local standup to one folder and then all others to another.  However, Gmail filters are not cool with NOT and they are also not great a keeping a dependency within filters.

The solution is to first assign the label to the local standup emails, then filter on standup messages that have not been labeled in a second rule (Gmail will warn you that this may not work, but it will). A third rule is necessary to filter out the announcement that I am going to run standup next week.  

You have to enter these filters exactly in this order:  New filters go to the bottom of the stack. Although Google does not guarantee the order of the filter application, it has been top to bottom for the last few years.  If you have to edit one of these filter later, the order will be upset.  Simply edit the other filters too (adding requirements on the things you know will be there, like 'Interestings', as gmail is smart about detecting changes).






Wednesday, November 25, 2015

A Git workflow

In my current project, we are introducing branches both at the server level and at the local level.  We have server level branches when our master is being released and we want to add functionality while the release process is going on.  I personally want a local branch for each story I am working on so that I can quickly switch back to the previous state to check things out.  This has led to some confusion and pain:  Essentially, we constantly forget which git command to use when.

Git is not intuitive when it comes to this workflow (or any workflow, if you ask the skeptics), especially as the team prefers to do rebase over merge.  Here is one of the many possible solutions.  I describe the case with the local work in progress branch, but you can leave that part out as described below

Workflow with a local work-in-progress branch

Step 1:  Create a work in progress branch and commit to it.  I still have not settled on always calling this branch 'wip', as it is ephemeral anyway, or giving it a decent name.   For short and simple stories, I definitely recommend wip.
git checkout -b wip
git commit -am 'done'

Step 2: You can squash or otherwise modify your commits with a
git rebase -i <REVISION>.  You can use various short cuts to refer to the revision where you branched off, I personally like to actually use the revision id (sha) there.  
We use 'git lola' a lot, which is an alias for
git log --graph --decorate --oneline --all

I realized I often only want to see the last few commits, so here is a bash alias (it does not show the coloring as git lola does, which is a shame)
alias lola='git log --graph --decorate --oneline --all | head'

Step 3: Update master to receive any new work your colleagues may have done.
git checkout master
git pull -r 
The -r option on the rebase is not required as we should not have any updates to master, but my teammates are in the good habit of always typing pull -r.

Step 4: Rebase the wip branch on the updated master, solving any merge conflicts as you go.
git checkout wip
git rebase master

If there are any merge errors, fire up your merge tool and use 'git rebase --continue'.  The commit should now be good to go and pass all your tests.

Step 5: Merge the wip branch into master.
git checkout master
git merge wip
Although this team does not like merges, this merge is actually a fast-forward so it is acceptable to them.  I guess it leaves the wip branch as a parent in the merge comment, but as we will be shortly deleting that branch this is harmless.

Step 6: Rewrite the commit and do a duet-commit / pair-commit:  To clearly distinguish our temporary commits (early, often) from the real deal, I only do a duet-commit when I am actually ready to ship this code.
git reset HEAD^
git duet-commit 

This assumes your work was all contained in one commit.  You will have to do some extra git magic if you have more than one commit to convert to a duet-commit.

Step 6: Ship the code and delete the branch
<magic-shipping-command>
git branch -d wip



Step 7: Enjoy your fresh commit

As one of my current team mates says: "I hate branches, they really blow. Stop reading this."  Sounds a lot like this guy to me :-)