FujiNet Development Guidelines - FujiNetWIFI/fujinet-firmware GitHub Wiki

FujiNet is a fun project with many repositories and developers. However, that can at times lead to a turbulent git history, and lead to difficulties later down the line when someone needs to bisect the repository to find when a particular change affected some element of the project.

The following is an attempt to give people some simple instructions on how to develop in a consistent manner with git, which will lead to cleaner history, and an easier time for everyone on the project viewing and understanding changes.

Throughout this guide, I will use the fujinet-apps repo as an example, but it applies to any other repo in the project.

Some follow up reading after this page are the sub-pages of this guide:

Git setup

Set up your GitHub account

If you have not already done so, set up your GitHub account and log into it.

Then, if you have not done this for GitHub before, create a new ssh key pair, as described here: Connecting to GitHub With SSH - Generating a New SSH Key and Adding it to the SSH Agent

Finally, add the public key just generated to GitHub, which can be done following these steps: Conneting to GitHub With SSH - Adding a New SSH Key to Your GitHub Account

Fork the target repository, and clone it to your machine

You should first fork the repository on github through your personal account, then clone it locally:

git clone [email protected]:markjfisher/fujinet-apps.git

Setup an "upstream" remote to the original repository.

This will allow you to easily fetch changes from other developers, and combine them with any changes you are also in the process of making.

You should only do one of the following:

# If you are going to create Pull Requests in GitHub (the norm for most developers)
git remote add upstream https://github.com/FujiNetWIFI/fujinet-apps.git

# If you have direct push access, then use:
git remote add upstream [email protected]:FujiNetWIFI/fujinet-apps.git

Doing New Development

We are mostly using a "Squash and Merge" strategy in GitHub, so it's important to use feature branches for your changes.

Why PRs must come from a branch, and not your master when using "Squash and Merge"

What the policy does:

When we merge a PR with Squash and Merge, GitHub merges all the commits of your PR into a single commit into master. That changes the commit IDs (SHAs) of your work into a new single commit ID (SHA) when it lands in the main repo.

Why that breaks if you PR from your master:

If your PR comes from your master, then after the squash-merge, the upstream master has a new SHA for “your” commits, but your local master still has the old SHAs. Now your master is misaligned (diverged). Git/GitHub will prompt you to delete or reset your local commits because the history is different.

Why branches fix this:

Do your work on a feature branch. After the PR merges, you simply delete the branch. Your local master remains a clean tracking branch of upstream master (no local commits), so it never diverges or needs history surgery.

The issue to the user is that F1 and F2 only exist in their repository now. So if they come from the user's master branch, the whole users master branch is out of sync with the upstream master. Feature branches avoid this issue as master will only contain changes and merges from the upstream repository.

How to work (step by step)

Get a clean master

Change to the correct main/master name here.

git checkout master
git fetch upstream
git reset --hard upstream/master   # fast way to realign exactly

Create a feature branch from the clean master:

Whatever your feature is, give it a short description, e.g. "fix-144-error"

git checkout -b feature/<short-description>

Commit and push the branch

git add -A
git commit -m "Explain X"
git push -u origin feature/<short-description>

Open a PR from your branch to upstream master

The upstream repository will squash and merge your commits. The SHAs in upstream will differ from your branch's SHAs - that's expected.

After merge: delete the branch (on GitHub and/or locally)

git switch master
git pull
git branch -D feature/short-description

Your master stays aligned, and you will not be prompted to delete commits.

Git Commit Messages

There is considerable debate over what makes a good commit message.

Many companies have started using commit messages to contain additional information that helps the build process generate automated change logs, and do automatic version bumping based on the message itself. That's way too much for a project like this one, and requires considerable discipline.

Instead, we should be strive for a few simple goals when writing commit messages, detailed below.

A good read that already covers a lot of this can be found at https://gist.github.com/robertpainsi/b632364184e70900af4ab688decf6f53

Format of the message

The git commit has a specific format. There's a subject line, (which should be kept as short as possible), followed by a blank line to separate the title from the body of the commit message, then the body of the commit message itself, if required.

In most situations, the subject line should be enough, but if you need to add more detail then move it into the body section.

Add ipify app to test network-lib

ipify is a simple cross-platform application that exercises the network-lib
functionality.

Here you can see a short title, the blank line, and the body explanation.

The blank line is actually important, git itself requires it to separate the title from the body, and without it, your body will appear in the summary on the same line as the title, so it's not good enough to start the body text on the line after the subject, there has to be a full blank line.

Subject Line

The git subject line should be able to fulfil the following statement:

If applied, this commit will <your subject line here>

So instead of past tense (e.g. "Added foo to bar"), it should be imperative, or present tense ("Add foo to bar").

Read back the above statement in your head for both examples ("If applied, this commit will..."), and you'll see why Add is better than Added.

Body

As mentioned previously the body should be a full blank line after the title. It can contain additional information that will help maintainers and other developers understand what the change is doing if the subject line isn't enough.

It's very rare that I use this feature, but it can be useful if you want to include things like Issue Numbers in Github, for example

Add ipify app to test json network-lib

This completes issue #1234

where 1234 is the GitHub issue number the change is related to, if you're working on fixing a reported bug for example.

This isn't a place to wax lyrical about your change either. Tests are usually the best way to document your change, but that isn't something we have the luxury of at the moment in this project.

So keep your body short, you can mention platforms here, mention issue numbers, but things like "Used a loop to count the foo so it would be faster to process the bar" does not make for a good body.

Changing previous git messages

A quick way to edit the text of the commit message on your most recent commit you have locally (that hasn't been pushed to a remote server!) is to use:

git commit --amend

This is great if you notice spelling mistakes (and have huge OCD like me), or the message doesn't reflect the change anymore.

So, if you're still crafting your commit, the above command will present you with an editor that you can use to change the title, and even add or change the body. Save that file and exit your editor, and git will update the commit with the new message.

[!important] You should strive to NEVER amend commits after you have sent them to a remote repository. This is because you are rewriting history. Even just the commit message itself, you are generating a brand new commit (it has a different ID to the previous one), and everyone else will have your old commit.

If you want to change the commit message of a change from several commits ago (again, that you have not pushed upstream), then if you look back at the "commands" available when doing the interactive rebase earlier, one of them is "reword". You can use this to change just the git commit message of a particular commit. In that case, keep everything as "pick" except the commit you want to change the message for, and change that to "reword". Save the "commands", and git will then offer you a chance to edit your message on the commit you wanted to change.

I have never done this. Instead, I will squash all commits into a single commit, and so I don't need to change the commit message of something several commits ago. And I would never do this to commits from other people, as you cannot amend commits that have come from the upstream repo, without breaking everyone else's git repo.