It is important to have documentation for people to reference as they learn how to work in a team. One document I use when I’m onboarding a student onto one of my codebases is my GitHub Rules and Expectations. The basic idea is to give them a clear idea of how to interact with everyone when it comes to the codebase and step-by-step instructions on what to do in certain situations. Below is the current version of my document. And yes, the “Rationale for Rules” is a section under the rules, so the students understand why I’m asking them to follow the rules.
Rule 1: The main branch is only for final work and has a clean commit history
Rule 2: Do not directly commit to the main branch
Rule 3: Work In Progress (WIP) branches:
- Use these for all initial work
- Tiny commits on these branches are perfectly acceptable
- It is fine to use a WIP for a pull request (PR) if its commit history is clean.
- These can and should be pushed to the repo to have backups of work.
Rule 4: Clear commits that make the commit history clean have:
- A short description as its first line
- A clear description of what the commit contains
- (optional) Separate lists of the files this commit adds, deletes, and changes and notes on what was done if needed
Rule 5: When renaming or moving files, use git mv, so Git is aware of what is going on
Rule 6: Do not blindly use git add -a . Instead, carefully choose what files should be added and use a .gitignore file. Do commit the .gitignore file.
Rationale for Rules
Rules 1, 4, and 5 focus on making the main branch as readable as possible for current you, future you (the you that will forget all the nuances of your repo in a week or more), and anyone else that will interact with the repo.
Rule 2 is partially about readability and partially to help with the interaction between team members. Moreover, it encourages using pull requests and code reviews properly within the team because they are best practices when a team is sharing a repo.
Rule 3 is to lower the barrier of committing and putting things into the remote repo. In a WIP, nothing is too small to commit. Losing work is worse than tiny, nonsensical commits. No one will look at your WIP branch except you, unless you invite them.
Rule 6 is to prevent random additions of system-specific files or things that do not belong in the repo because of their size, they constantly change (like log files), etc.
Branch names should have the following structure to make it easy for others to find branches:
USERNAME — your username
WIP — include if this branch is a Work In Progress branch
PURPOSE — short name of what the branch is for
Pre-Code Review Checklist
- When running all tests (python3 -m unittest discover), do all tests pass?
- Reasonable whitespace?
- Any repetitive code or long functions that could be refactored?
Squashing a Branch and Pull Requests
When you are ready for your code to go into the main branch.
- git checkout -b BRANCH_NAME — Branch off the current working branch (this is usually off of a WIP branch, so use the same name but without WIP in the name)
- git rebase -i HEAD~NUM_OF_COMMITS — Use interactive rebase to squash the commits in this branch into as few commits as appropriate (the fewer, the better)
- git push — Push the new branch to the remote repo
- Create a pull request with the new branch — Use the GitHub interface to create the pull request (PR) from the branch and assign it to the appropriate person
- Once the code review is approved and you are ready to merge into the main branch, choose one of the following:
(a) If the branch has no conflicts with the main/base branch and therefore can be done automatically.
(a.i) If PR involves only one commit — Use the pull request interface to “Rebase and merge”.
(a.ii) If PR has multiple commits that just need to be squashed — Use the pull request interface to “Squash and merge”
(b) If PR has multiple commits that need to be reorganized or rebase/merge cannot be done automatically — Ask Prof. Stephens-Martinez for help. She will walk you through it or direct you to resources that will help.
- Delete all branches associated with these changes in local and remote repos unless you have a strong reason to keep them. Git will warn you for some of these branches that the commits aren’t in main (squashing and rebasing look like new commits to git). So double check the correct branch is being deleted and delete anyway.
Git Mental Model that May Help
The entire commit history is a large graph.
- A commit is a diff of changes to apply to the repo
- Nodes are commits
- Edges only exist within the context of a branch
- The only branches existing in the graph at a given time are the ones that are interacting
- Git makes copies of commits as it needs to keep the graph a directed acyclic graph
For more on this topic, here is a video lecture of me going more in-depth on the git mental model. The video is from my Fall 2022 post-CS2 data science class (CS216). The audio is scratchy, and that particulate lecture hall has mics to pick up audience questions. So it also picks up a bunch of crowd sounds.