This post is intended to lay out the fundamentals of our workflow, the reasoning behind it, as well as to provide a refresher on git fundamentals.
Each team should be able to quickly iterate on the features it handles without interfering with the others’ work. To that end, at least at first, we’ll all work on separate ROMs. Obviously, everyone needs to be able to compile and run their code on their machine.
We want our code to be modular, so we’ll split up logically distinct parts of
the code into multiple files and include them with the
.INCLUDE (or its alias,
.INC) directive. While prototyping, each team will then include the relevant
files into the appropriate test ROM.
Using git effectively
When working on a group project, effective collaboration is vital ; CodiMD and Discord are pretty straightforward to use, but git deserves special attention.
First off, for the very basics, this cheat sheet should come in handy ; understanding and knowing its contents is an absolute prerequisite.
Beyond that, core characteristics of our workflow are:
masteris sacred. Don’t try to commit directly to it, nor to rewrite its history.
- When working on a feature, always create a separate branch.
- Commit and push often (but not to
master; you can’t, anyway, because it is a protected branch).
- Use descriptive commit messages. We highly suggest to use the following template :
module: verb object, such as
mapgen: improve performance
- Do not commit binary files unless absolutely necessary (one notable exception: tiles).
- When the feature you’ve been working on is ready to be merged into master, create a Pull Request (PR). This will provide an opportunity for the rest of the team to review and discuss your changes.
- Use GitHub Issues
abundantly. They are a great way to organize our work and are
well-integrated with git. For example, if your work resolves a bug that was
mentioned in, say, issue #24, you can write
fixes #24in your commit message. The issue will be closed automatically (though not deleted!), and a reference to your commit will appear in it.
Creating a branch named
tile-colors locally and checking it out
(i.e. switching to it):
git checkout -b tile-colors
Staging changes and committing them
Local changes must typically be staged before they can be committed. This is
git add <path>.
After doing so, and before committing, please review what you’re about to
git status (to see the affected files). If you want to inspect the
details of your staged changes, you can use
git diff --cached. If you feel
you’ve made a mistake, unstage as
Once you are satisfied with your staged changes, commit them with
which will open your text editor to let you write a commit message. Please write
a concise summary of your changes on the first line, add a blank line, then feel
free to go as much into details as you’d like in the rest of the commit.
Then, push your changes to your branch.
Pushing your newly created branch to GitHub
-u flag sets up a remote branch to track your local branch.
origin refers to a remote, namely our GitHub repository.
git push -u origin tile-colors # needed for the first push git push # use this for subsequent pushes
Merge commits and fast-forwarding
When merging (
git pull, etc.), depending on your git history, a merge commit is not always created.
When the git history is linear, you can fast-forward : no merge commit is created.
A - B - C master merge \ ---------------> A - B - C - D master D feature (fast-forward) feature
When there’s a fork, you cannot fast-forward : a merge commit is required.
A - B - C - D master merge A - B - C - D - F master \ -----------------> \ / ^---- merge commit E feature (no fast-forward) E feature
git pull allows merge commits. To avoid these types of commit, either pull with the flag
--ff-only (will only merge if it can be fast-forwarded), or
--rebase (will perform a rebase when needed, do not use if you don’t know how to use it). You can use
git config pull.ff only to automatically use
--ff-only on this repository.
When merging, if you want to squash all your commits into one, use the flag
A - B master \ C - D - E feature
git merge --squash feature
A - B - C' master (C' = C + D + E)
Sometimes, you do not want to commit your changes, but need to save your changes
somewhere (for instance when pulling). You could create a temporary commit, then
later rebase and squash, but an easier way is to use the stash.
git stash puts your unstaged changes into the stash,
git stash pop applies the latest stashed item and removes it from the stash,
git stash drop discards the latest stashed item without applying it (use with caution).
Additional commands can be found with
git help stash.