Git hard or go home

I am in love with Git. It’s the neatness junkie’s dream come true. Multiple people can code away safely, independently, then every commit can be written and rewritten at any time to end up with a tidy, coherent product. As long as you know what you’re doing, that is.

With the years I worked out a few strategies for taming Git, making both mine and my collaborators’ work easier. Perhaps these’ll save you some headaches down the road.

Understand the model

A prerequisite to understand most of Git’s concepts is learning how the data model works. It’s so important, that before I let developers do anything with Git, I force them to read through the “Git Basics” chapter of Pro Git. The rest they can learn as they go. In essence:

  • all commits are nodes in a directed graphs, where
    • when multiple commits point to the same parent, they’re all branches,
    • when one commit has multiple parents, it’s a merge,
  • there’s no such thing as “branch” or “tag” in itself, they’re just labels given to specific commits—friendlier names to refer to than 63949df, so:
    • deleting a branch or tag merely deletes the label. The commit 63949df is still there and you can reference it. At least until Git decides to do garbage collection, when all orphaned commits are permanently deleted.
    • a “fast forward” merge moves a label to a different commit, as long as the branch you’re merging into didn’t have any commits of its own. Since there’s no separate merge commit for it, there will be no trace of this merge later in the graph, so make sure that’s what you want. Otherwise do git merge --no-ff.

Take your time to study the model, the charts and perhaps the commit graph in some existing repository. Working with branches will suddenly make much more sense for you, and more importantly you’ll grasp the concept of rebasing much, much quicker.

Rebase freely

Rebasing is the wonder broom that keeps the commit graph tidy. It’s what you do to get rid of commits saying Merge branch 'master' of https://github.com/your-name/your-repo.git which make the commit graph look like a Guitar Hero script—completely unreadable.

You can:

  • amend broken commits, if you:
    • mistyped the last commit’s message do git commit --amend and edit the commit,
    • forgot to stage some changes, add a file, do
      git add <missing changes>
      git commit --amend -C HEAD
      
  • squash obsolete commits, once you realize a commit other than your last one could use amending, do:
    git add <missing changes>
    git commit --fixup=<hash of commit to amend>
    git rebase -i --autosquash <hash of commit to amend>^
    

    Note the trailing caret ^ in the last line.

  • rebase instead of merge on pull, pretty please. This makes sure master (or any other branch) is a single, straight line, that’s easy to follow. This will also cause fewer conflicts and make the remaining ones easier to resolve. Use either git fetch && git rebase origin/<your branch> or git pull --rebase.

There’s a caveat to rebasing—it changes history, discarding some commits and replacing them with other ones. That’s not an issue, as long as all of the commits you’re replacing are only local to your sandbox, but once you pushed these commits out into the world, you might be peeing into the pool.

Branch smartly

Just because branching and merging with Git is easier than with older version control systems, that doesn’t make branching any less dangerous:

Start juggling too many [branches] at once, and you’re bound to drop a few. In most source control systems, you can create hundreds of branches with no performance issues whatsoever; it’s the mental overhead of keeping track of all those branches that you really need to worry about. Your developer’s brains can’t exactly be upgraded the same way your source control server can (…)

To stay on top of your repository:

  • keep branches short and small, branch off, make your changes, create a pull request and merge as soon as possible. I used to advocate the gitflow model in the past, but nowadays I consider its long-lived develop and release branches an anti-pattern, and favor the simpler GitHub Flow. Fewer branches mean fewer (ideally just one) sources of truth.
  • delete remote branches, once merged, usually right after a pull request is closed. If you ever need to resurrect a branch and add something to it, you can always push it anew. Otherwise it’s hard to see which branches are still active.
  • don’t git cherry-pick or commit the same patch of changes to multiple branches. It’s confusing and will likely give you headaches during merging. If you stick to a single, long-lived master branch with short-lived feature branches, you shouldn’t ever need cherry-picking. Otherwise, use rebasing to move a commit from one branch to another.

Push thoughtfully

Once your changes are out there, on the remote(s), you might as well assume everybody else has already fetched them. GUI clients like SourceTree have auto-fetching enabled by default. If you now realize you’d still like to do some amendments—say fix a silly typo or rebase the master branch—you’re screwed. You’ll have to ask everybody to git reset their local branches and cause a lot of grief.

Take your time before you push anything, and never, ever mark the “Push changes immediately to remote” checkbox in your Git client. It’s like disabling the Undo feature. Commit your changes locally, leave them baking for an hour or a day, then review them—see if there are no missing or obsolete line changes, files, whether commit messages are correct—and only then run git push.


Reduced amount and magnitude of merge conflicts, actually useful commit graphs, immediately obvious location of the most current code—all benefits I drew from applying these here practices. Call it Git etiquette or call it a way to improve the ratio of pleasure to pain in using Git. And do share your own tips in the comments, please.

Talking like you own the place

“Last year we acquired [company] and …” I was chatting with my friends about some recent business of the company I’m part of. They looked at me funny and interrupted “you keep saying ‘we‘. That’s sooo unusual.”

I always talked this way. How else should I be talking about the organization I spent over 6 years with, advanced through three positions and delivered numerous projects now used by millions of our users. I’m definitely making an impact on the day to day business of the company and if I wasn’t able to do so I’d be long gone and contributing elsewhere.

Apparently I’m and odd outlier here. Many (most?) people would refer to places they spend half their waking hours at for decades as some variation of “the company I work for” as if they firmly tried to distance themselves from someplace unpleasant. That’s what we do with people—when we don’t like somebody we use words to create distance:

  • revert to formal titles “Mr Smith”, “Mrs Jameson”, then
  • depersonalize references, replacing them with “this man” or “that woman”, reaching extremes with complete
  • dehumanization at “that miscreant” or “those idiots”.

The equivalents for a company would be:

  • “Google” (fill in your company name),
  • “the company I work for”,
  • “sweatshop”.

The moment I catch myself saying “the company I work for” will be my trigger to make major changes. Either in employment or in attitude.

Michał’s conference war chest

It’s not unusual for conferences to cost an arm and a leg. At €1,000 or more for just the entry, on top of which come travel and accommodation, and I often attend two or three events a year. That’s a pile of money in need of justification spending, and I can only do so if I bring back lots of valuable information. Here’s what I do nowadays—the tools and tricks I worked out for surviving and thriving as a conference attendee.

Preparation

During a conference I want to focus strictly on acquiring information and connecting with other attendees, so to free up time I prepare a lot upfront.

Session selection comes first. Conference schedules usually appear piece by piece, so a week or two before the event I go through all sessions and plan my agenda. The last thing I want is to make haphazard, effectively random decisions at the venue.

  • If I’m attending with any colleagues, we sit down together to split up the sessions and cover more ground.
  • If there’s more than one interesting session in a given time slot, I write down all of them and prioritize. This way I have more options when my first choice turns out to be a flop or suddenly gets canceled.

I add selected sessions into Google Calendar, synchronized across all of my devices. Some conferences have dedicated apps to store one’s schedule, but these may or may not work to my liking or could have issues on shaky Wi-Fi. Plus I quickly would’ve acquired a pile of useless apps and accounts.

GOTO Berlin schedule in Calendar

I’m really big on notes. Before the conference I setup a fresh Google Doc, since I’ll be taking notes on a tablet, with pre-entered:

  • sections for each chosen session, ordered chronologically,
  • names and
  • Twitter handles of speakers.

GOTO Berlin conference notes

Using Google Docs has a number of advantages:

  • I can share the document with colleagues, both at the venue or back at the office, where they can follow me in real-time,
  • Google Docs’ context-aware spellchecker is pretty decent, which helps a lot when (mis)typing on a tablet,
  • the chronological order lets me get ready quickly by opening the document and scrolling down to the next empty section,
  • speakers’ Twitter handles make live tweeting easier.

I’ll often write the Twitter handles with the conference hashtags, ie.:

 @mpaluchowski #craftconf

Note the leading space. This snippet I can easily copy and paste after every quote I tweet during a session.

D-Day(s)

The conference days are always intense, both physically as well as mentally, so my focus here is to stay light and fit.

I carry my own shoulder bag, currently the excellent Camel Active Dakar, which contains my tablet, wallet, business cards and a pen or two.

Camel Active Dakar shoulder bag

Conferences usually hand out their own bags, but most of these aren’t convenient to carry around for a full day. I carefully selected a good bag, that:

  • keeps my hands free all day—especially beneficial at standing lunches,
  • doesn’t bite into my shoulder(s),
  • doesn’t bump around my hip thanks to its vertical orientation,
  • easily fits into my lap during a session, when space is tight,
  • carries everything I need—the Camel one can easily carry a 12″ laptop or A4-sized documents.

Michal taking notes at CraftConf 2015

My device for note taking is currently the iPad Air 2. A laptop wouldn’t do because the vast majority won’t last a full day on batteries and I sure as hell don’t want to waste time on recharging.

Typing on a tablet is pretty cumbersome, but gets better with practice, plus Google Docs’ spellchecker helps a lot, and anyway I won’t be publishing raw notes anywhere without post-processing. A colleague is happy doing notes on an iPad Mini so the smaller form factor could work as well.

iOS 9’s Peek function was a real blessing, since I tweet a lot during sessions, on top of taking notes. Earlier I had to keep switching between the Google Docs and Twitter apps, whereas now I can just slide in Twitter on the side for a quick tweet and return to notes. Thanks, Apple!

A conference day is really hard for the body since I spend a lot of time sitting still in sessions, while my brain keeps working in high gear, burning lots of fuel and not getting nearly enough oxygen to clean up the trash from metabolism. This means unless I pay attention to my body, by the end of day I’ll likely develop a headache and won’t see much from the conference party. So I:

  • drink a lot of water, either carry my own bottle and keep sipping during sessions, or drink a glass at each break. The side effect is having to visit the bathroom often, but there’s a trick to that too.
  • move a lot in between sessions—no sitting, lots of walking, gesticulation, even leaving the venue when possible.
  • eat light, opting for complex fuel sources, like protein or complex carbohydrates. No pastry or sweets of any kind—these would burn up quickly leaving me hungry and distracted.

Finally, I try to sit near convenient exit rows, so that I can easily leave the session if I don’t like it, or reach the toilet before the crowd does. Trust me, this is a real problem during male-dominated software events.

Post-processing

There’s little value in all the information I acquire at a conference if it stays inside my head. Sharing it with others and turning it into action is where the payoff starts.

Conferences are often followed by a weekend, which is super convenient since I can focus on something completely different and then go back to my notes with a fresh look on Monday morning.

It takes me a day or so to process notes, where I rearrange them to:

  • group into common themes, ie. microservices, DDD, Agile etc.,
  • reorder into something that makes sense in the context, rather than whatever the speaker(s) thought would,
  • list out tools, books, blog posts and other resources I saw mentioned,
  • later add links to talk recordings, once they were posted.

Finally, I produce a brief summary from the pile of information, adding my own judgment of where I see the industry right now, or how it changed compared with previous conferences. This usually turns into a blog post, richly decorated with photos and tweets from the event.

We take a look at all materials with my colleagues to decide what is most relevant to us and what we’d like to try out now or later. These go into our regular planning and I get back to everyday work, counting down to the next great conference.

Developer turned Product Owner

The backlog is a mess. The order is random. There’s no grouping or coherence, let alone a vision of any kind. Stories are unclear, if at all described, and sprint planning takes forever while developers try to figure out what the product owner wants. I heard these complaints over and over again from teams, and then I had a chance to become a product owner myself. Turns out it’s not much different from a developer’s work.

TDD

Taking an agile approach means making small steps and testing how they influence the product. Just like TDD in programming:

  1. Think what you want to do.
  2. Decide how you will measure success, like you code a test.
  3. Have the team implement your idea, usually by writing code and just enough to make the test pass.
  4. Evaluate the idea against your KPIs, like you would run your test.
  5. With the findings, go back to 1 to adjust your hypothesis and approach.

Clean Code

The backlog items you’re preparing—usually stories, will be read and relied on by the team to build a product increment. The clearer the language, the easier it’ll be to understand and follow.

  • clear, unambiguous, expressive naming,
  • precise vocabulary,
  • short paragraphs,
  • good English (or any other language you use),

all of these are qualities that’ll help the team deliver faster and with fewer misinterpretations. All the same in code, where good naming for variables, functions, objects matters, and short, focused functions and components are preferred.

Abstraction

A good backlog is well organized, with related items grouped together into epics, aligned along a vision for the product. This in turn provides direction and focus for both the team and stakeholders, guiding conversations on how the product should be shaped, deciding what fits in and more importantly what doesn’t. It allows setting release and sprint goals, that the team can measure their progress against.

All this is exactly like abstraction in code, where similar logic gets grouped into objects, similar objects grouped into packages, named after the domain they cover. From an orderly, well-named code base one should easily be able to identify the purpose of the system, decide where to put new code and whether it belongs in there at all.

I know what the team’s doing

My programming experience is helping me tremendously in shaping the backlog and working with the team. Requirements are crisp, or quickly refactored to become so, order is clear and it’s easy to see what fits into our current vision and what should be deferred.

On top of that, I know the work the team does. When they come back reporting issues with implementing certain items, I understand those and we can easily adjust plans to reality, with the new information we received. Everyone’s work becomes easier and we’re steadily moving forward.

Obviously not every developer would make a good product owner. There’s a lot of touchy-feely people work involved, while many will likely prefer to deal with the clear, binary logic of computers. But for those who always liked to work on the edge between technology and people, this might just be the right career advance. One that’s surprisingly easy to make.

Seventy percent of the time Swiss

Boarding an airplane on Monday morning, coffee in hand, yawning, flying to Zürich for a week of alternating between the customer’s office and hotel, then back in the air on Friday evening to reach base—my home in Warsaw for the weekend. That was the offer I was given a while ago, good money, challenging work. I replied “no, thank you“.

Mind you, I am by no means bound to where I’m living currently, even though I love it here. There are many other extraordinary spots around the world where I could see myself moving. It’s just this particular arrangement that wouldn’t suit me—torn Schrödinger-style between two locations, neither really here nor there.

It would’ve uprooted me from all the current affiliations I had here, in Warsaw—the TEDx people, startup communities, Toastmasters and personal relationships. On the other hand, my temporary Zürich tenure (or anywhere else for that matter) wouldn’t have let me get engaged in anything meaningful there, since these relationships take time to develop and produce results.

There would be also practical consequences to consider. Since I would’ve been spending only weekends here in Warsaw, I’d want to maximize my enjoyment of them, so I’d have to pay somebody to clean my apartment, do laundry and arrange for all the other chores to be done, so that I can rest, catch up with family and friends. And I likely would’ve been spending vacation at home, sick of all the traveling.

There are times in life when that sort of work mode could be acceptable, perhaps even exciting. Usually that’s when one is younger, has no spouse, little experience. With time one learns that things of value require time and commitment to build, often related to one’s personal presence somewhere for an extended period of time. We might be living in a digital age, but we’re still very much physical creatures.