This year Santa’s helpers have been tasked with making a garland. It’s a pretty simple task: string beads onto yarn in a specific order. When the garland reaches a specific length, add it to the main workshop garland. Each elf has a specific sequence they’re supposed to chain, which is given to them via a work order. (This is starting to sound like one of those horrible calculus problems. I promise it isn’t. It’s worse; it’s about Git.)
For the most part, the system works really well. The elves are able to quickly build up a shared chain because each elf specialises on their own bit of garland, and then links the garland together. Because of this they’re able to work independently, but towards the common goal of making a beautiful garland.
At first the elves are really careful with each bead they put onto the garland. They check with one another before merging their work, and review each new link carefully. As time crunches on, the elves pour a little more cheer into the eggnog cooler, and the quality of work starts to degrade. Tensions rise as mistakes are made and unkind words are said. The elves quickly realise they’re going to need a system to change the beads out when mistakes are made in the chain.
The first common mistake is not looking to see what the latest chain is that’s been added to the main garland. The garland is huge, and it sits on a roll in one of the corners of the workshop. It’s a big workshop, so it is incredibly impractical to walk all the way to the roll to check what the last link is on the chain. The elves, being magical, have set up a monitoring system that allows them to keep a local copy of the main garland at their workstation. It’s an imperfect system though, so the elves have to request a manual refresh to see the latest copy. They can request a new copy by running the command
git pull --rebase=preserve
(They found that if they ran
git pull on its own, they ended up with weird loops of extra beads off the main garland, so they’ve opted to use this method.) This keeps the shared garland up to date, which makes things a lot easier. A visualisation of the rebase process is available.
The next thing the elves noticed is that if they worked on the main workshop garland, they were always running into problems when they tried to share their work back with the rest of the workshop. It was fine if they were working late at night by themselves, but in the middle of the day, it was horrible. (I’ve been asked not to talk about that time the fight broke out.) Instead of trying to share everything on their local copy of the main garland, the elves have realised it’s a lot easier to work on a new string and then knot this onto the main garland when their pattern repeat is finished. They generate a new string by issuing the following commands:
git checkout master git checkout -b 1234_pattern-name
1234 represents the work order number and
pattern-name describes the pattern they’re adding. Each bead is then added to the new link (
git add bead.txt) and locked into place (
git commit). Each elf repeats this process until the sequence of beads described in the work order has been added to their mini garland.
To combine their work with the main garland, the elves need to make a few decisions. If they’re making a single strand, they issue the following commands:
git checkout master git merge --ff-only 1234_pattern-name
To share their work they publish the new version of the main garland to the workshop spool with the command
git push origin master.
Sometimes this fails. Sharing work fails because the workshop spool has gotten new links added since the elf last updated their copy of the main workshop spool. This makes the elves both happy and sad. It makes them happy because it means the other elves have been working too, but it makes them sad because they now need to do a bit of extra work to close their work order.
To update the local copy of the workshop spool, the elf first unlinks the chain they just linked by running the command:
git reset --merge ORIG_HEAD
This works because the garland magic notices when the elves are doing a particularly dangerous thing and places a temporary, invisible bookmark to the last safe bead in the chain before the dangerous thing happened. The garland no longer has the elf’s work, and can be updated safely. The elf runs the command
git pull --rebase=preserve and the changes all the other elves have made are applied locally.
With these new beads in place, the elf now has to restring their own chain so that it starts at the right place. To do this, the elf turns back to their own chain (
git checkout 1234_pattern-name) and runs the command
git rebase master. Assuming their bead pattern is completely unique, the process will run and the elf’s beads will be restrung on the tip of the main workshop garland.
Sometimes the magic fails and the elf has to deal with merge conflicts. These are kind of annoying, so the elf uses a special inspector tool to figure things out. The elf opens the inspector by running the command
git mergetool to work through places where their beads have been added at the same points as another elf’s beads. Once all the conflicts are resolved, the elf saves their work, and quits the inspector. They might need to do this a few times if there are a lot of new beads, so the elf has learned to follow this update process regularly instead of just waiting until they’re ready to close out their work order.
Once their link is up to date, the elf can now reapply their chain as before, publish their work to the main workshop garland, and close their work order:
git checkout master git merge --ff-only 1234_pattern-name git push origin master
Generally this process works well for the elves. Sometimes, though, when they’re tired or bored or a little drunk on festive cheer, they realise there’s a mistake in their chain of beads. Fortunately they can fix the beads without anyone else knowing. These tools can be applied to the whole workshop chain as well, but it causes problems because the magic assumes that elves are only ever adding to the main chain, not removing or reordering beads on the fly. Depending on where the mistake is, the elf has a few different options.
Let’s pretend the elf has a sequence of five beads she’s been working on. The work order says the pattern should be red-blue-red-blue-red.
If the sequence of beads is wrong (for example, blue-blue-red-red-red), the elf can remove the beads from the chain, but keep the beads in her workstation using the command
git reset --soft HEAD~5.
If she’s been using the wrong colours and the wrong pattern (for example, green-green-yellow-yellow-green), she can remove the beads from her chain and discard them from her workstation using the command
git reset --hard HEAD~5.
If one of the beads is missing (for example, red-blue-blue-red), she can restring the beads using the first method, or she can use a bit of magic to add the missing bead into the sequence.
Using a tool that’s a bit like orthoscopic surgery, she first selects a sequence of beads which contains the problem. A visualisation of this process is available.
Start the garland surgery process with the command:
git rebase --interactive HEAD~4
A new screen comes up with the following information (the oldest bead is on top):
pick c2e4877 Red bead pick 9b5555e Blue bead pick 7afd66b Blue bead pick e1f2537 Red bead
The elf adjusts the list, changing “
pick” to “
edit” next to the first blue bead:
pick c2e4877 Red bead edit 9b5555e Blue bead pick 7afd66b Blue bead pick e1f2537 Red bead
She then saves her work and quits the editor. The garland magic has placed her back in time at the moment just after she added the first blue bead.
She needs to manually fix up her garland to add the new red bead. If the beads were files, she might run commands like
vim beads.txt and edit the file to make the necessary changes.
Once she’s finished her changes, she needs to add her new bead to the garland (
git add --all) and lock it into place (
git commit). This time she assigns the commit message “Red bead – added” so she can easily find it.
The garland magic has replaced the bead, but she still needs to verify the remaining beads on the garland. This is a mostly automatic process which is started by running the command
git rebase --continue.
The new red bead has been assigned a position formerly held by the blue bead, and so the elf must deal with a merge conflict. She opens up a new program to help resolve the conflict by running
She knows she wants both of these beads in place, so the elf edits the file to include both the red and blue beads.
With the conflict resolved, the elf saves her changes and quits the mergetool.
Back at the command line, the elf checks the status of her work using the command
rebase in progress; onto 4a9cb9d You are currently rebasing branch '2_RBRBR' on '4a9cb9d'. (all conflicts fixed: run "git rebase --continue") Changes to be committed: (use "git reset HEAD <file>..." to unstage) modified: beads.txt Untracked files: (use "git add <file>..." to include in what will be committed) beads.txt.orig
She removes the file added by the mergetool with the command
rm beads.txt.orig and commits the edits she just made to the bead file using the commands:
git add beads.txt git commit --message "Blue bead -- resolved conflict"
With the conflict resolved, the elf is able to continue with the rebasing process using the command
git rebase --continue. There is one final conflict the elf needs to resolve. Once again, she opens up the visualisation tool and takes a look at the two conflicting files.
She incorporates the changes from the left and right column to ensure her bead sequence is correct.
Once the merge conflict is resolved, the elf saves the file and quits the mergetool. Once again, she cleans out the backup file added by the mergetool (
rm beads.txt.orig) and commits her changes to the garland:
git add beads.txt git commit --message "Red bead -- resolved conflict"
and then runs the final verification steps in the rebase process (
git rebase --continue).
The verification process runs through to the end, and the elf checks her work using the command
git log --oneline.
9269914 Red bead -- resolved conflict 4916353 Blue bead -- resolved conflict aef0d5c Red bead -- added 9b5555e Blue bead c2e4877 Red bead
She knows she needs to read the sequence from bottom to top (the oldest bead is on the bottom). Reviewing the list she sees that the sequence is now correct.
Sometimes, late at night, the elf makes new copies of the workshop garland so she can play around with the bead sequencer just to see what happens. It’s made her more confident at restringing beads when she’s found real mistakes. And she doesn’t mind helping her fellow elves when they run into trouble with their beads. The sugar cookies they leave her as thanks don’t hurt either. If you would also like to play with the bead sequencer, you can get a copy of the branches the elf worked.
Our lessons from the workshop:
- By using
rebaseto update your branches, you avoid merge commits and keep a clean commit history.
- If you make a mistake on one of your local branches, you can use
resetto take commits off your branch. If you want to save the work, but uncommit it, add the parameter
--soft. If you want to completely discard the work, use the parameter,
- If you have merged working branch changes to the local copy of your master branch and it is preventing you from pushing your work to a remote repository, remove these changes using the command
resetwith the parameter
--merge ORIG_HEADbefore updating your local copy of the remote master branch.
- If you want to make a change to work that was committed a little while ago, you can use the command
rebasewith the parameter
--interactive. You will need to include how many commits back in time you want to review.