Git/GitHub Best Practices

The Software team currently uses the Git version control system to keep track of changes to our code. We host our various repositories on GitHub, under an organization for Husky Robotics.

Repositories
We currently have three main repositories:
 * PY2020 (TODO: Change to Resurgence) - primarily C++; the main codebase that runs on the rover's onboard computer. This is where the bulk of Software's work is focused.
 * MissionControl - primarily React.js and TypeScript; the Mission Control software that runs on the base station and provides the user interface for operators to control the rover and view telemetry data.
 * RoboticsSimulator - primarily C# in Unity; the 3D simulator we are currently developing to aid in testing our code under different conditions without needing the actual rover or terrain.

We additionally have some smaller repositories for libraries that are not available from the Ubuntu package catalog.
 * TODO: list them here.

Branches/Pull Requests
All repositories should have their /  branch protected, which means that commits cannot be pushed to them directly. Instead, contributions should be made by creating a branch for each feature being worked on, and then submitting a pull request when finished. In order to be merged, a pull request should meet the following requirements:
 * Must pass the automated Continuous Integration (CI) checks - at least, this will require the code to compile, if not also to pass a suite of automated tests. The idea behind this is to ensure that all code on the default branch is in a reasonably working/stable condition.
 * Must pass a code review by Software leads - This is done through GitHub's review feature, which allows a reviewer to either approve a pull request, or point out specific changes that should be made to the code or ask questions about specific parts of it.
 * The code being implemented must contain documentation, preferably in the form of Doxygen comments, so the information will be included in our auto-generated documentation pages. The idea behind this is to ensure that all code in the default branch is reasonably documented, which makes it easier to maintain and work with later.
 * If applicable, the code being implemented must include tests that ensure its behavior is correct.

Ideally, please try to keep the life of each branch relatively short, and make pull requests more often for smaller features; it is often more difficult to review very large pull requests, and long-lived branches can sometimes diverge from the default branch enough that merging them can be tricky.

Ignored Files
Ideally, every repository should contain a  file that tells Git not to track the files or directories listed in it. In general, however, please do not commit any of the following:
 * Auto-generated files of any kind. This includes compiled executables and CMake files. The reason for this is that these files are often large and contain information specific to the user's system which is not applicable to other users (and may in some cases expose personal information).
 * The exception to this is documentation pages, but this should ideally be generated automatically by CI on an orphan branch instead of on the default branch.
 * Libraries or dependencies. This includes  and other libraries in general. The proper way to include dependencies in projects varies between languages, but it generally involves having them present in standard locations on the system where the build system can find them; the package managers for most GNU/Linux distributions will take care of this. If the library you need isn't packaged, then the user should install it manually on their system before building the repository, and we'll need to document instructions on how to do this. Please contact a lead if you need any help with dependencies.
 * System or editor configuration files. This includes,  ,  , or any other system-specific files that are generated automatically. These often contain a user's personal configuration, which as with auto-generated files is not applicable to every user and may contain personal information.

For Leads (may remove section):

 * All repositories must have at least one CI action that compiles the code upon push.
 * It is recommended to have a test suite as well.
 * If the repository is for a cross-platform project, a build matrix should be used to compile the code/run tests on all supported operating systems. This way we can discover operating system-specific issues.
 * All repositories must protect the master branch, and require code reviews and CI checks to pass before pull requests can be merged.

General Best Practices/Etiquette
The following is a (somewhat disorganized) list of tips, best practices, and etiquette guidelines to observe when contributing to the Git repositories.


 * Don't push until you're ready! Once you push a branch, it's hard to change without forcefully rewriting it, which can cause problems for other users. There's a lot of powerful Git operations you can do locally before pushing which can help to clean up your revision history a little. This doesn't mean to never push your code until you're done with the feature you're working on, as you can lose work this way and it makes collaboration less productive, but you don't necessarily have to push after every commit.
 * Made a mistake? Use ! Amending lets you apply the changes you have staged as if they were part of the latest commit; this lets you fix a mistake in your latest commit easily, while avoiding making another commit. Note that this only works if you haven't already pushed the commit - see "Don't push until you're ready" above!
 * Write meaningful commit messages! The first line of your commit message should be a summary of the changes in 80 characters or less, and should be in the present tense - try to complete the sentence "This commit will..." However, you can add more information by inserting two new lines after the end of the first line and then writing a more detailed message. Describe your changes, but also why they were made - what problems does your commit solve? What considerations or design decisions went into your commit? Is there anything you'd like someone reading this change in the future to know? The idea behind this is to provide a meaningful changelog for our code so that anyone maintaining it or looking through it in the future can understand the thought process behind each commit.