git'ing along with others

2022-03-29 22:13:44 -0400

Version control is certainly part of "coding well with others", but there's "dumping stuff in chronologically" and the kind of discipline needed to collaborate well. Sometimes the discipline isn't as hard as it looks at first...

Oops, that should have been a branch

I recently joined a tiny fast-moving team that was already using git, and we're trying to be "as disciplined as we can afford to be" - the primary external motivator is to keep a stable enough master that we can safely run demos off of it, but at the same time have those demos include recent progress. Large chunks of work get done on branches and reviewed; small things, especially things that impact one file and are easily tested on their own, can go straight in with less fanfare.

Problem is that you start one of these small changes, committing as you go, when you suddently realize it's become a large one and "probably should have been on a branch all along". Well, if you haven't git pushed yet (because you're working on master and hoping you can just push a working change - it's not just luck that this ends up being true so you can use this trick) you can "retcon" that with two commands:

# You're already in the checkout, on master.
# Create a local branch of the work...
$ git checkout -b best-intentions
# now master and best-intentions both have your changes.
# "unzip" master back to the push point:
$ git branch -f master $(git rev-parse origin/master)
# now master has been "reconnected" at the point where you last
#   pushed; the next pull will update that smoothly...
#
# Bonus points: track the newly created branch properly
$ git push --set-upstream origin best-intentions

That's it, now you can get the new branch reviewed properly.

Silly little helpers

Most of the branches I use at work are quasi-independent feature branches, but I'm dipping into various ones at various times to help out, review, or test... and since our product takes a couple of minutes to build from scratch, the "one checkout that switches branches" model doesn't make any sense at all (really it's never made sense on anything large that I've worked on; for the cases where it did work, using git stash instead has always worked better) so I have a bunch of entire source and build trees.

Usually when I start the day I want to get all of them "caught up" to everyone else's work; taking advantage of the "git extension script" mechanism, I have a trivial git-morning script that finds all of my checkouts and just does a git pull in each of them. I have not been brave enough to have it do a git merge origin/master too, but I'll probably try the experiment soon just to see if it saves more time than it wastes from having to do all the cleanup first thing.