Our workflow
by yberreby
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.
Organizing code
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:
master
is 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 asmapgen: 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 #24
in your commit message. The issue will be closed automatically (though not deleted!), and a reference to your commit will appear in it.
Cheat sheet
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
done with git add <path>
.
After doing so, and before committing, please review what you’re about to
commit with 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
needed.
Once you are satisfied with your staged changes, commit them with git commit
,
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
The -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 merge
, 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
By default, 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.
Squashing
When merging, if you want to squash all your commits into one, use the flag --squash
For example:
A - B master
\
C - D - E feature
git merge --squash feature
A - B - C' master (C' = C + D + E)
Stashing
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
.