Contributing: Git workflow
This is a complementary article (in addition to the main contributing guide) describing the accepted Git workflow step-by-step.
We use GitHub flow for the development, which is basically about committing into branches and merging through pull requests.
-
Git setup: real name and email; Editors/IDE: proper indentation, auto strip trailing whitespaces
-
Never push to
master
; start each new feature in a branch:- Branch naming:
short-name-through-hyphens
; useNNNN-bug-name
to refer an issue - Within a branch, please keep the history linear, i.e.
rebase
instead ofmerge
to keep the branch up-to-date
- Branch naming:
-
Atomic commits; no "oops" commits, squash if needed; Git commit message agreements
-
Respect those who will review your changes: prepare your branch before opening a PR, cleanup commits and rebase to catch-up recent changes from
upstream/master
-
Do not rebase already published changes and force-push until review is over: push
fixup!
commits, then rebase one last time once getting LGTM from maintainers
Make sure to perform the necessary setup steps:
git config --global user.name "YOUR NAME"
git config --global user.email "YOUR EMAIL ADDRESS"
Please use your real name (no nicknames, sorry).
If you're new to GitHub's Fork & Pull model, you'll probably find this help article useful.
In a nutshell to clone your fork and setup the upstream:
git clone https://github.com/YOUR-USERNAME/embox embox
cd embox
git remote add upstream https://github.com/embox/embox.git
git remote -v
# origin https://github.com/YOUR-USERNAME/embox.git (fetch)
# origin https://github.com/YOUR-USERNAME/embox.git (push)
# upstream https://github.com/embox/embox.git (fetch)
# upstream https://github.com/embox/embox.git (push)
Contributors with push access clone the original repository directly, i.e.
the upstream is origin
:
git clone https://github.com/embox/embox embox
cd embox
# (optionally) Setup upstream as an alias of origin
git remote add upstream https://github.com/embox/embox.git
Note: Depending on whether you have
SSH keys set up,
you may wish to prefer using git@github.com:embox/embox.git
as the clone URL.
Do these things for each feature you work on. To switch features, just use git checkout my-branch
.
Create a new branch from master
. The code in master
always
compiles and passes all tests (well, it tends to).
git fetch upstream
git checkout upstream/master -b my-branch
-
Give a new branch some descriptive name, separate words with hyphens
-
If it's a feature branch, it may be worth spending some time to open an issue and describe your intentions. Someone may already have had some thoughts on the topic and could probably give you some advice
-
It is a good practice to begin a branch name with a number of the issue being addressed, like
NNNN-bug-name
, for example,721-contributing-guide
. This will update the issue status accordingly
Hack, hack, hack...
Keep commit message agreements.
Before publishing your work please pick up all recent upstream changes. May be someone has added a fix for a bug that you were forced to work around?
The main point here is to rebase
, i.e. "replay" your changes on top of the
updated upstream/master
.
-
When doing
pull
, always do it with--rebase
to avoid unnecessary merge commits:git checkout my-branch git pull --rebase upstream
- Setup
git config --bool pull.rebase true
to makepull
imply--rebase
by default - You might prefer using tools like git-up
- Setup
-
To catch up any new changes from
master
userebase
instead ofmerge
:git checkout my-branch git fetch upstream git rebase upstream/master
Please spend extra 5-15 minutes to organize your commits. The person who will review your changes would really appreciate that.
-
Use
git commit --amend
to edit the last commit, don't produce unnecessary "oops" commits -
Befriend
git rebase --interactive
-
Quite often, especially when developing something from scratch, you'll only need a single commit: add a new driver, fix a crash, etc.
Please also refer to the checklists and the cheatsheet.
Then just do it:
git push origin my-branch
To push a new branch created locally, you will probably need to set up tracking information:
git push --set-upstream origin my-branch
If you edit the history (to integrate feedback, or to add a change you forgot
to commit to an existing commit), you will need to use --force
to push the
branch. When force-pushing, always specify the branch explicitly:
git push --force origin my-branch
- Also setup
git config push.default simple
for extra safety
Force-pushing is safe provided two things are true:
- The branch has not yet been merged to the upstream repo
- You are only force-pushing to your fork, not to the upstream repo
Generally, no other users will have work based on your pull request, so force-pushing history won't cause problems.
Before opening a new pull request for you branch, especially for long running branches, please take a look at you changes once again. Basically, it's worth performing the same checks as for pushing described above.
It is also worth synchronizing your local
repository with the upstream to catch up all recent updates from
upstream/master
and checking once again that nothing is broken. This way, it
is guaranteed that your branch will merge cleanly, i.e. the pull request can be
merged by the "Merge" button from the GitHub web interface.
Very likely, you will be advised on how to make your proposed changes better. Quite often these are just remarks about coding style, typos, bad naming, etc. There are also real bugs like a missing error check or resource leaks.
Please, seek out the commits that introduced bad lines and add follow-up
changes as separate fixup!
commits. This is trivial for a single commit
PRs; git blame
to the rescue otherwise.
This way, after review is over you will be able to perform auto-squash rebase and pretend that you made everything correctly right from the beginning.
Few things to note here and to summarize:
-
Unless you really screwed up and maintainers ask you explicitly, do not rebase and force-push during the review process. It is a rather confusing practice
-
Instead, put some efforts to prepare the branch for review before opening a PR, i.e. squash "oops" commits, check against the checklists, etc.
-
Add follow-up changes as distinct
fixup!
commits referring the proper commits from your branch and push them as usual, without rebasing -
Finally, once review is over rebase for the last time to squash fixup commits you made
-
For maintainers: please don't push "Merge" button until Travis CI finishes to build the PR, even if you just happened to reword a typo in some commits message and sure that this won't break a build.
Otherwise, Travis won't cancel the build anyway but will fail to fetch necessary refs for the closed PR, thereby spamming about the broken build.
Just don't do that and wait until getting "green" light.
- Embox on QEMU emulator
- ARM
- AARCH64
- x86
- MIPS
- RISC-V
- PowerPC
- DLX (Microblaze)
- SPARC
- Porting to a new architecture
- Audio
- FPGA
- FS
- Graphics
- NET
- USB
- iec61850
- C Plus Plus
- GY 30 I2C light sensor on STM32
- Emdocker
- Emdocker on MAC
- Xen port workflow
- Troubleshooting
- QEMU with GRUB2 and Syslinux
- LKL subsystem