Getting Started Git - Terrapin-Rocket-Team/SRAD-Avionics GitHub Wiki

Table of Contents


Github Tutorial

What is Version Control?

Working on a big project, especially one where you have multiple people working on it, isn’t easy. Emailing files back and forth, losing certain versions, accidentally overwriting an important part and not being able to recover it — these are all problems that come with this task. Version control is the name used to describe the operations of these codebases that work to fix these problems. Through proper version control, you effectively have a time machine for your code, helping you keep track of all the major changes you make and allowing you to revert to previous versions. Version control also allows multiple people to work on the same project simultaneously without stepping on each other’s toes, with some software also allowing you to store the code in the cloud.

Git

Git is a specific tool for version control, and is one of the most popularly used tools for many codebases worldwide. It’s a system that has the ability to take a snapshot of your code at different points in time, calling them commits, and saving them to your codebase’s history. You can create a commit whenever you reach a stable point in your work and Git will record all the commits made chronologically. When making a commit, Git records only the changed files and lines compared to the previous commit, allowing you to easily see what code has changed in a given commit while also avoiding storing whole copies of the codebase. It also incorporates other features to help with collaboration, such as branches, where you can create parallel versions of the code to work with multiple people editing.

Github

Github (https://github.com/) is a platform/website that implements Git, but also works to store your project’s code in the cloud. Think of it kind of like Google Drive meshed with Git. Within a user’s account or organization within Github, there are what are called repositories, which are kind of like projects or standalone codebases. It is essentially the parent directory of your project, similar to a folder that has within it both files and subfolders that make up the project.

Repositories

The way Github works is that each repository can have a remote and local version. The version that is stored on the cloud, on Github’s servers is called the remote, and the version of the repository that’s on a user’s laptop or computer is the local repository. By making a copy of the remote on one’s own computer, a process called cloning, a local version of the repository is created that the coder can now edit. Now, you can edit the files however you like in whatever coding environment you desire, making commits along the way to take screenshots of your progress. However, by default the commits are only stored to the version of the repository you directly are on — meaning in this case, the commits only exist on the local repository, the version on your own machine. To add these commits and the updates that belong to them to the remote, the version on Github’s site, you have to push these commits, essentially sending these commits as updates to the remote repository. Because of this set-up, the local and remote versions may often be out of sync, especially if someone else on the project made a commit on their computer that they pushed to the remote, while your local copy isn’t updated. Thus, it is important to remember to often fetch origin, which refers to updating the local version on your computer with any updates that may have occurred to the remote.

Branches

Github also implements many of the other features of Git, one important one being branches and pull requests. If two people are planning to work on the same project, but don’t want each other’s commits to start overlapping and confounding their own work, it would make sense for them to create two copies of the code to work on independently, and then combine the two versions later. This is effectively what branching is, where an independent duplicate to the primary codebase is created in parallel for a developer to experiment and code within, before bringing their changes back onto the main version when they are stable and working.

By default, every version of the code is on a branch, and so the primary branch is where the code normally lives, and is called the main branch. Through Git and/or Github, a branch can be created based off of duplicating another existing branch, with this usually being done off the main branch. On this branch, development and experimentation can occur, adding as many commits and changes as wanted, without worrying about corrupting the main branch. Multiple branches can be created as well, for multiple people to work on different things simultaneously and independently. When the branch’s work is done, and the commits are ready to be brought over into the main version, a merge or pull request will occur. A pull request is simply a request for the updates on one branch to be brought onto another, and typically it will have reviewers to ensure that no changes would be breaking. During this process, there may occur merge conflicts, which happen if a certain change on a branch contradicts some commit made onto the main branch after the branching occurred, and it looks to resolve this conflict by accepting either version, or both. Depending on the project, team, or company, there may be guidelines and good practices to follow regarding branching and pull requests, with the Avionics subteam’s guidelines being found here: Github Guidelines.

Other Features and Resources

There are other features within Git that could be useful, such as staging, stashes, hooks, etc, which may not be covered here but are also useful to know. If you’re using the Git Command Line Interface (CLI) by installing Git Bash or the binary onto your computer instead of Github Desktop, it is important to stage all your changes before committing them or pushing to remote, as staging tells Git what files and changes to track. In Github Desktop, by default, all changes are staged. Stashes allow for uncommitted changes to be saved before switching local branches or versions, while hooks can trigger actions based on the lifecycle of the repository.

Learning Git can be daunting at first, but luckily there are plenty of tutorials and visualizations online that can help. Below are a few good websites, resources and games that can help you better understand Git: Git Branching Game Git Command Visualization Git CLI Cheat Sheet Github Tutorial for Beginners FreeCodeCamp Git Video

Getting Started with Github

To use Github, a Github account is needed in the first place. Navigate to https://github.com/, press sign up, and follow the instructions to get an account. By being a college student, you’ll also have access to Github Premium and their Student Developer Pack, which is optional but nice to have and comes with some useful perks.

In order to get added to the Terrapin Rocket Team Github organization, and be able to start working with the existing repositories, you’ll have to be a part of the Slack. Under Browse Channels or Join Channels, join the channel called join-github, and enter your email or other details associated with your Github account there. Eventually, you’ll receive an invite to join the Github organization for the club in your email inbox, so by promptly accepting that invitation, you’ll have joined the Terrapin Rocket Team Github.

Github Desktop

Now that you have access to the remote repositories of the club, it’s simply a matter of getting a local copy of them for you to work on and contribute to. The most commonly used tool for this is to download Git on your local computer and use it, and learning how to use Git Bash or Git’s command line version is a very useful skill. However, for the sake of simplicity, this walkthrough will use Github Desktop, a GUI for Git that is free and easy to use.

Once you’ve downloaded the Github Desktop application, you’ll want to sign in with the same Github account as before, that now should have access to the Terrapin Rocket Team organization. Once on the Get Started page, select the Clone Repository button, to make a copy of a remote repository on your local machine. You can search for and select the desired repository, and then select where on your local machine do you want this project and all its files to be stored. Github Desktop will set up a local repository in the location you select, so modifying or adding any files within the selected folder will be reflected as changes to your local repository, which can then be committed and pushed onto the remote.

The base screen for Github Desktop has several buttons and features which are useful:

Screenshot 2024-07-20 143530

1 - This is the dropdown where you can select which local repository you are working on 2 - Dropdown that lists all the branches available on the local repository, and allows you to select which one to switch to. This is also where you can select branches to merge together or rebase. 3 - Button to Fetch/Push to remote, syncing together the local and remote repositories 4 - Tab to view all the previous commits and changes on the current branch 5 - Sidebar that shows all the specific files that have been changed since the last commit, with the yellow icon meaning modified, the green plus icon meaning this file has been created, and the red minus icon meaning a deleted file 6 - Shows the diff, or the specific changes line by line for a selected file 7 - Summary textbox to write the title for a given commit 8 - Button to create a commit

A typical workflow process may look like this: First, select the correct repository (1) and the correct branch to be working on (2). Fetch the origin/remote (3) to ensure you’re working with the most recent version, and then using your IDE or code editor, make the changes and edits you’d want to. Back in Github Desktop, view your changes with the sidebar and diff screen (5, 6). Write a descriptive title for your changes in the summary box (7), such as “Edited BMP sensor reading logic”, and then create a commit (8). Push your changes to origin (3) to make sure it’s reflected in the remote repository.

Good Practices

Github has a wealth of other features which are useful to use between task management, documentation, and workflow streamlining, the usage of which differs from team to team. Using these features, as well as the basic functionality of Git, there are a few good practices to follow when completing coding work.

Make good and often commits

It’s always better to have more commits than less, especially if there was a previous version you’d want to revert to that is now lost since it wasn’t committed. A good rule of thumb is that every time you’ve completed a single, atomic task or subtask, to make a commit. This way, each commit is related to a single piece of work or code, and if there are issues with that feature or section, the changes which relate to that can be easier pinpointed. If two tasks or goals are being worked on, one after another, make each task its own commit.

With this also comes the idea that commit names and summaries should be concise and descriptive. With just a few words, someone from another subteam should be able to understand what was worked on, and a generic idea of what features were implemented. The Git Documentation recommends that commits are written imperatively, such as “Make X do Y”. This also makes it easier to follow the flow of development and features through the repository’s commit history. Ideally, each commit should have stable code that works being added, but in the case the code that is committed isn’t completed, some marker should indicate that the commit’s version is incomplete.

Use Branches

Branches offer a way to complete work in isolation in conjunction with multiple members of a team, so are especially useful to allow an entire subteam to work on the same codebase. We will use the idea of feature-based branching, which is essentially that any time a new feature is to be worked on or implemented, a branch will be created for it, development for that feature will occur on that branch, and then that branch will be merged back onto main. Make sure that when you are making commits, it’s on one of these feature branches, instead of directly committing to main. This will allow the team to better organize the work for each feature, as well as how to introduce multiple features into the main version. Other teams and projects may have their own standards, but make sure to follow their guidelines for how to use branches.

Use the Issues Page

For the Avionics subteam, the workflow for a feature starts with an Issue being created on the repository’s Github page. This way, when a branch is created to complete the work for a given issue or task, it can be associated with a posted Issue, as well as with the user assigned to it who is working on it. This way, corresponding Issues, commits, branches and people which are all related by feature can be connected to better see which parts are associated with each other. By doing this, it’s easier to keep track of which Issues are being worked on, what features each branch is looking to tackle, as well as manage pull requests when it comes to merging the branches. More in-depth guidelines for this can be found here: Avionics Github Guidelines

Avionics Github Guidelines

For the Avionics subteam, a large part of our work and task management will be done on Github, a methodology that is in line with good practices and common usage of version control in software development. For an introduction to Github and version control as a whole, visit the Github Tutorial documentation guide.

Tasks

As an alternative to Kanban Boards and Trello, tasks can be stored on Github via Github Issues. This can be found by visiting the SRAD Avionics Github repository, and visiting the Issues tab.

Creating an Issue

Issues in Github are essentially tasks, or a list of things to-do, that represent the next stages of fixes and changes for the repository’s projects. You should create an issue to describe any of the following, if not already there: A task you’re currently working on A bug/error you found in the code or files that needs addressing Next step tasks for a subproject or for once another issue/task has been completed Project ideas, or potential tasks for future feature development

Once you have an idea of the task you want to create, press the New Issue button to create a new issue. The issue should have a title that is descriptive yet concise, encapsulating the breadth of the issue. Then, for the description box, the following items should be included: A brief description of the issue, and what steps need to be taken for it, or how to start going about the task A rough checklist of subtasks/milestones contained within the task that should be hit along the way Links to any helpful resources or documentation guides for the task

Once the task’s description has been written, assign a label, or multiple labels, to the task that describe the general areas/topics involved with this issue.

Assigning Issues

Once a task has been created, it’ll show up under the general Issues tab on the SRAD_Avionics Github page. The next step would be to find an issue you are interested in, or are willing to pick up. These tasks may be assigned during meetings, assigned to the creator of the issue, or assigned when someone picks up a task that fits their skills. When picking up a task, in the Assignees section within the issue, assign either yourself or someone else to complete the task.

If you find an issue which someone else is already assigned to, but you’d be willing to help or have some helpful feedback or advice for completing the task, leave it as a comment on the issue. The comment section should be used to communicate information about the issue at hand.

Completing Tasks

Creating a Branch

Once an issue has been assigned, the assignee, or whoever is working on that issue should create a branch for all their development. Branches should be used to develop and push updates related to the task in parallel to other tasks and updates, so that all development relevant to an issue is kept on its corresponding branch.

To create a branch, select Create a branch under the development pane on the issue’s page. Use the default name for the branch, or rename the branch to be the name of the issue that it is correspondent to, if that is a unique identifier. If the branch should not work off the changes in the main branch, choose another branch as the source, and then checkout/open the branch locally.

All changes and work should be done on this new branch. If others are working on the issue, they can just check out the branch locally, or view it on the Github site. As work is being done, make sure to check off the checklist items under the issue’s description to indicate the milestones/progress being achieved.

Merging Changes

When the branch is finished with its development, its changes need to be merged back into the main branch to be included in the primary version of the repository. This is done in 3 main steps:

Merging Main into the Branch

While development has occurred on this branch, changes may have been made to the main branch of the repository, as other tasks are being worked on in parallel and other updates are being made. To ensure that the newest updates in the main branch are included in the version of code that is on the branch, create a merge commit of the main branch into the branch involved with the issue at hand.

Ideally, there would be no conflicts when doing this and the branch has worked on changes independent of the main branch’s development. However, if there are conflicted files when merging the branches, indicating that both the main branch and the local branch modified the same file, you will have to manually resolve these conflicts. Using the commit history available through Git locally or Github, contact the person/people who made the commit(s) that modified the same file. Work with them to determine which changes are crucial and should be included, and not overridden by current changes on the branch related to the worked-on issue.

If you have Git in VSCode, you can use that as a code editor to resolve conflicts present within coding files. The full documentation for VSCode’s Merge Editor can help with this. Using the Merge Editor, these conflicts can be resolved by either accepting the incoming change (from the main branch), or keeping the current change (version present on the task’s branch). If a conflict is simply adding in new lines of code, overwriting blank spaces, accept the version of the conflict with the new code, but make sure you communicate with the other team member to ensure both codebase versions reconcile well. When you are done, complete the merge.

Creating a Pull Request

Once the branch’s version has caught up with all the updates, a Pull Request will need to be opened to get the changes into the main branch of the repository. This can be done on the Github site, or can be done with the Create a Pull Request button within Github Desktop. On the Pull Request Creation screen, a few things will need to be included.

First, write a concise title that describes the issue and the subtasks that were completed to work towards it. This can resemble the name of the original issue. Then, in the description, include a more thorough description of the issue and all changes that are made. This description should address all changed files that this Pull Request is attempting to merge, and what changes they implement, as well as how they affect the overall project. If parts of the code, or certain files, had/do yield a merge conflict, explain each conflicted file as well as how the decisions were made for which version of the branches to accept. Essentially, the description should encompass the changes that are trying to be made to the main branch, as well as include the reasoning behind changes to files that were within the main branch’s version (via conflict resolutions). If it satisfies this theme, the description need not be excessively long.

Assign the Pull Request labels that correspond to the original issue, and then assign reviewers and assignees. Assign the team lead (Varun Unnithan, me 🙂), or someone else who will be responsible for looking over the pull request and merging it to the Assignees section. If there are other people who should look over the changes and make sure it’s good before merging, assign them as a Reviewer of the pull request. When that is all done, create the pull request.

Completing a Pull Request

Pull requests should be audited and looked over by anyone assigned to the pull request, or was noted as a reviewer for it. When looking over a pull request, any concerns can be taken up with the creator of the pull request, and can be written in the comments section of the pull request. For any reviewers, leave a comment once reviewed if the pull request looks good, saying you looked over it. Once it has been reviewed, these changes will be merged into the main branch.