Branches
Git[1] was also written around the idea of branches. You are (almost) always working on a branch with the default or first one being called `main` or `master`. The `master` was the original name, but it has racist connotations so there is a noticeable push to use `main` instead. Therefore, I will use `main`.
Branches also work like tags[2] in that they point to a specific commit. However, the main difference is when you are on a branch and make a commit[3], the commit is added after the current one and the branch is moved to the new commit. That way, the branch name is always the latest commit of that branch.
The general purpose of a branch is to work on something to the side, make multiple commits, and then if you are happy, pull the results back into the `main` branch. At the same time, you can switch back to the `main` branch to make other changes and Git will “automatically” merge the result together when you put the two back together (with some caveats).
The above screenshot is from an older project (hence the use of `master`) but it shows some of the cases where I used branches. The top one when when I gave my novel to a reader and it took me a few commits to integrate the suggested changes. While that was happening, I continued to edit and expand the novel from other feedback.
The bottom one (the yellow) was me working on two things at the same time. I was working on the project logo and cover page, which I thought would take a few commits but didn't. At the same time (really, a different computer), I was adding teasers and summaries to all the chapters. These were two very distinct things, but they were overlapping so I used branches to keep them separate until I was happy with the results.
Creating Branches
There are two ways to create a branch from the current commit. The first creates a branch but does not switch to the branch.
$ git branch new-branch-name
To create and switch to the branch, you use the `checkout` command with the `-b` to say “create a branch”.
$ git checkout -b new-branch-name
Current Branch
You can only work on a single branch at a time. The easiest way to see the current branch is the `git branch` command with no additional parameters.
$ git branch draft * main sent-to-bob
To switch to the new branch, use the checkout command.
$ git checkout sent-to-bob $ git branch draft main * sent-to-bob
To remember the branch, I use a shell prompt called Starship[4] on both Linux and Windows to tell me both the current version of the novel and it's branch.
dmoonfire@hunip:git-for-authors main* ⇡v0.0.7 2025-08-09T15:45:00> git branch draft * main sent-to-bob dmoonfire@hunip:git-for-authors main* ⇡v0.0.7 2025-08-09T15:45:04>
Forges and Remote Branches
All forges[5] allow you to also push up branch to the remote repository[6], but that is not done automatically. However, this becomes really helpful because you can use the forge's web UI to look at the branches, see them on the commit graphs, or pull them down to a different machine.
When you first try to push a remote branch to the server, it will give you a message.
$ git checkout sent-to-bob
$ git push
fatal: The current branch sent-to-bob has no upstream branch.
To push the current branch and set the remote as upstream, use
git push --set-upstream origin sent-to-bob
To have this happen automatically for branches without a tracking
upstream, see 'push.autoSetupRemote' in 'git help config'.
This is because there is no remote branch already there and it doesn't know how to automatically create the branch (`git config --global p ush.autoSetupRemote true`). I don't like using that because I occasionally make typos, but to push a branch is just add the remote name and the branch. I also add the `-u` (`--set-upstream`) so it doesn't ask me again.
$ git push -u origin sent-to-bob Enumerating objects: 22, done. Counting objects: 100% (22/22), done. Delta compression using up to 16 threads Compressing objects: 100% (13/13), done. Writing objects: 100% (13/13), 1.62 KiB | 1.62 MiB/s, done. Total 13 (delta 11), reused 0 (delta 0), pack-reused 0 (from 0) remote: remote: Create a new pull request for 'sent-to-bob': remote: https://src.mfgames.com/dmoonfire/some-novel/compare/main...sent-to-bob remote: To ssh://src.mfgames.com/dmoonfire/some-novel.git * [new branch] sent-to-bob -> sent-to-bob branch 'sent-to-bob' set up to track 'origin/sent-to-bob'.
After that, `git push` will work on that branch.
Readers and Editors
Probably the main reason I use branches is to handle readers and editors. I create a branch when I give the project over to a reader. When they finish days, weeks, or even months later, I can go back to the novel at the point I gave it to them, integrate changes without having to remember what I've done in the meantime, and then pull that branch into the `main` when I'm done. Pulling into `main` is when I'll get a list of conflicts where I changed the same paragraph in two different branches but that is a considerably smaller amount of work.
If I don't do that, I find myself looking at the notes they made on the page but the paragraph might have drastically changed in the meantime because I responded to another reader who responded faster and I may have already come up with the perfect answer or the new one might be better than what I did previously.
In terms of the CLI, it looks like this. When I sent a piece, I create the branch but don't switch to it.
$ git branch sent-to-bob
Then I can keep on making changes to `main` while I wait. Then, when Bob finally responds, I switch to their branch which changes the entire project back to the point I sent it to Bob.
$ git checkout sent-to-bob
Then I make changes and commit the results as I go through the feedback. Sometimes I can do it in a single commit but with some of the more detail-oriented feedback, it can take me days to finish integrating.
When I'm done, I pull the changes I've been making to the `main` branch into the `sent-to-bob` branch.
$ git merge main
If I made any changes to `main` that conflicted with the change in `sent-to-bob`, Git will then tell me I need to resolve them. I do that which can take another few commits to resolve. Then I do a quick reading/editing pass to smooth things off.
Once I'm ready and am happy with the results, I pull the change back into main.
$ git checkout main $ git merge sent-to-bob
And now the `main` branch has everything I've done while waiting for Bob and also all the changes I made from Bob's feedback. I do a final push and then delete the branch (`git push origin :sent-to-bob` which basically means "push nothing to the remote repository to delete it).
$ git push $ git push origin :sent-to-bob
As a note, `git push` is the same as `git push origin $NAME_OF_BRANCH` where `$NAME_OF_BRANCH` is the current branch.
Refactoring
The bulk of my writing has been commissioned work. That involves a lot of back and forth and sometimes the commissioner will ask me to rewrite a block of chapters because it doesn't work out for them. In those cases, I don't want to lose my old work until they are happy so I create a branch (`rewrite-10-to-15`), make the changes until they are happy, and then pull it back into `main`.
The reason I use a branch is because more than once, the commissioner has gone “wait, I've been thinking and what you wrote the first time was pretty good”. In those cases, I can just ignore the branch, or go back to the `main` branch and make more minor tweaks that works instead.
A lot of Git is about not losing your work. Branches really help in these situations.
Footer
Below are various useful links within this site and to related sites (not all have been converted over to Gemini).