Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

What is version control and why do we need it?

Strictly speaking, we don't really need version control. We could store the code only a single person's laptop, or distribute copies of the code to everyone on the software team. However, as software members work on different aspects of the robot, managing the different copies of code gets very, very difficult. Just imagine how difficult it would be to manually combine someone's LED code, another person's Drivetrain edits, and some vendordep updates by hand. This is where version control comes in, specifically Git.

Git is the most popular version control system, and almost every major project uses it in some way or another. The core philosophy of version control is that changes in the codebase are like steps in a ladder. Our main code is stored in one big "trusted" ladder, where new changes will eventually be applied. When a software member chooses to develop a feature, they will diverge from the "trusted" ladder and make their changes, which will (hopefully) get merged back into the main ladder. This tree/ladder structure makes it extremely easy to see what changes were made and who made them. This means it is trivial to revert to a working version should the robot code stop working, and the branches allow multiple people to work on the same codebase without interfering with each other's changes.

What is Gitlab? How is it different from Git?

Git provides the version control system and allows separation of code. However, we still have a problem: how can the code be distributed to all the software members and stored in a trusted place? This is the main function that services such as GitLab, GitHub, and Bitbucket provide. They provide a central machine (server) that all the software members will upload their code to. As well as providing this central server, they provide additional helpful features such as Issues, Merge Requests, and Pipelines.

These Git hosting platforms are, for the most part, interchangeable, but Valor chose GitLab because it was OSS and had the ability to be self hosted on our own servers (specifically Jan and Michael's).

Terminology

In Git-land, there are many terms you need to know. Here are the most important:

  • The smallest unit of change is called a commit. Ideally, these commits should edit only the files needed to provide a specific change
    • Good commit: "Tune y controller constants". This is specific and should only change the files needed to tune the y controller constants.
    • Bad commit: "Change code" - 10 files changed. This is not specific and only by looking into the commit can someone figure out what the commit is actually doing.
  • A feature or collection of changes should be done in a branch. Recall the tree/ladder structure from above. A branch diverges from the main "tree trunk" to provide a feature. Best practice is that one branch should be specific to one person, unless you agreed to work together. People will get annoyed if they are working on their own branch and realize that it got changed without their permission.
    • The branch name should be short and concise, but still specific to that change. Some good examples are gold-elevator-reset  and new-scorer-pit-sequence 
    • One bad example would be 221-update-pigeon-to-use-getyaw-and-update-status-signal-to-250hz . If anybody wants to check out the branch and test it, it is a pain to type out.
  • Pushing and pulling refers to the way to send and request code from the central server. Pushing means sending your local commits (pushing DOES NOT send changes that are not in a commit) to the central server. Pulling refers to bringing in changes from the central server to your local machine.
    • If you make a change, and want to get it on the central server, you want to push that branch
    • If someone makes a change, pushes it, and you want to use it, you have to pull that branch
  • Merging refers to the process of bringing in changes from one branch to another. Usually, this will be a side branch merging in to the main branch. Merging is a core part of Git, but you should (almost) never be merging branches using the Git CLI. Instead, you should be making Merge Requests.
  • Once you decide that your branch is ready to be part of the main robot code, you will make a Merge Request (this is a part of GitLab, not Git). This creates a nicely formatted page that shows people the changes you are making and whether it passes the pipeline (will be discussed later). The mentors will review it and make sure that the changes you are making are okay, and they will merge it. Even though you have the button to merge your own MR (a restriction of GitLab Free), you should NEVER be merging a branch unless a mentor tells you it is okay.
  • Rebasing is a more complex topic, but it will become very common during the build season. Recall that when you are making changes, you switch to your own branch (diverging from the main branch). When someone else makes changes and they get merged, however, now your branch is behind the main branch - essentially, the main branch has changes that your branch doesn't have. This might not seem like a huge issue, but when you finish your feature and want to merge it into the main branch, Git will complain because it knows that by mergeing your branch, you are essentially wiping out the changes that were on the main branch but not on yours. The solution to this problem is rebasing. Rebasing essentially moves up your "diverging" point and adds the changes from the main branch. However, this may cause conflicts if you made changes to files that were also changed by the new commits in the main branch. This requires manual intervention.

Submodules

Submodules are a way to nest Git repositories inside of other Git repositories. One of the main ways that we use it is the relationship between robot code and Valkyrie, our software library. Because we want to use Valkyrie in multiple robot code repositories (primarily 2025 and 2026), we separated Valkyrie into its own repository and added it as a submodule into the 2026 robot code. The best part of the submodule setup is that we can tell Git to track a submodule by a specific commit ID or a branch. This means that during build season, we can tell Git that we want to track the main branch of Valkyrie so that it will automatically update Valkyrie when Valkyrie gets changes, but after the season is over, we can freeze the submodule at the latest commit that still works, and it will always stay the same while the Valkyrie repository gets changes.

Setting up GitLab and Git

Whew, most of the stuff above was theory, to get you to understand how Git and GitLab interact and how we use it. Now its time to actually get GitLab and Git set up on your computer. These instructions are for Windows, but they should be similar on Mac.

  1. Install Git. This will install the git  CLI command that you will use to create commits, switch branches, and push/pull branches.
  2. Open your terminal and run ssh-keygen -t ed25519 . Use  Use the defaults they provide, and make sure that there is no passphrase. You should just be pressing enter again and again. You should see a path matching something like C:\Users\<username>/.ssh/id_ed25519  or C:\Users\<username>/.ssh/id_rsa. Remember this, as you will use it in the next step .
  3. Run notepad C:\Users\<username>/.ssh/ssh_configconfig (should mostly match the path you saw above). It may ask you to create the file. If it does, answer yes.
  4. Copy and paste the following into the file:
    Code Block
    Host git.valor6800.com
    	Port 6822
    	IdentityFile ~/.ssh/<id_rsa or id_ed25519>
    If you want an explanation of this config, keep reading. Otherwise skip to step 5.
    There are two main protocols to configure a central server with Git: HTTPS and SSH. HTTPS uses a username and password, while SSH uses public/private keys. While HTTPS is easier to configure, it is considered less secure than SSH, and is disabled on the Valor GitLab. Valor's GitLab also uses a non-standard SSH port number (6822). You can sort of think of ports as a series of mailboxes on a computer, and for the central server to respond to Git, you need to send data to the right "mailbox" on the central server, which happens to be 6822 instead of the default SSH port number of 22. This is where the SSH config file comes into play. Since Git uses SSH under the hood, it reads this .ssh/config  file that says that when accessing the host git.valor6800.com , it should use the port 6822  and use the public/private key pair that you created with ssh-keygen
  5. Run cat ~/.ssh/<id_rsa or id_ed25519>ed25519.pub . Copy the output. Go to the Valor GitLab, sign in, then click on your icon in the top right of the left sidebar, then go to Preferences → SSH Keys → Add new key. Paste the text you copied and set the expiration to four years from now (just sometime after you graduate). Click Add Key .
  6. Verify that you can connect to GitLab with ssh -T git@git.valor6800.com . If it succeeded, you should see something along the lines of Welcome to GitLab, ...! 
  7. Go to an appropriate directory where you want to store your Valor code and clone the 2026 code with git clone --recursive git@git.valor6800.com:valor6800/2026/robot.git . The --recursive  flag tells Git to clone the submodules inside of the repository.

The Common Path to Making Changes

This paragraph outlines the basic pathway for making changes to the repository.

  1. git checkout main . This checks out the main branch and stops you from diverging off a random branch.
  2. git pull . Just fetch the latest changes.
  3. git checkout -b <branch name> . This creates the branch and diverges off the main branch
  4. Change the file(s) you want
  5. git add . . This stages all the files that you have changed. You don't need to know about staged changes for now, but just know that before running git commit  you should run git add 
  6. git commit -m "<commit message>" . This creates a commit with the specified message. Recall good commit habits from above.
  7. git push -u origin <branch name> . This pushes the branch to the remote server. The -u origin <branch name>  specified the remote branch name as it can be different from your local one. Once you push once, you no longer need to push the flag - you can just run git push 
  8. Create a Merge Request in GitLab when you are ready to merge your changes. Go to the GitLab repository → Merge Requests → Create new Merge Request. Click on Select Source Branch and choose the branch you want to merge into main. Write your title, description, and assign the MR to yourself. Make sure you set the label to reflect the status of the Merge Request.
  9. When the mentors are ready, they will merge the MR and your changes will now be in the main robot code!

Rebasing

If you are working on your branch and changes were made to the main branch, you must run git rebase main  in your branch. The next time you push, you must git push --force . This is because you essentially disrupted the commit history by injecting steps in the middle of the ladder instead of at the end with regular commits. Be very careful with git push --force , however, as doing it on the wrong branch can lead to data loss!