How to Git

This is intended to be a basic introduction to using Git and GitHub written for those getting started. This introduction will touch on

Git and GitHub

Git

Git is a piece of version control software. You can download it here. When you set up a git folder, it will track changes to the files in your folder. A couple key features we use are

  • commits, which are snapshots of our code that act as "save points" as we make progress, and
  • branches, which are alternate versions of our repository that we use to develop different features.

We'll circle back to these soon, but first, let's talk about some things you'll need to do to get started with Git.

GitHub

Let's say you've downloaded git and want to start working the Controls repository. You'll find our repository stored online on GitHub here. The Git version control software doesn't necessarily need to be combined with GitHub, but what GitHub gives us is a cloud-based git repository that makes it easier to store, share, and manage our system's code together.

Cloning

In order to work on the Controls code, you'll first need to get a copy of the repository on your local machine. To do that, you'll use the command

git clone <URL> 

If you haven't yet cloned the Controls repository, you'll want to follow this guide on getting started from our README. However, you can use this command with any online repository to make a copy of it in whichever local folder you're in.

Pulling

Once you have a local copy of the code, you can make changes and otherwise turn it into the amazing, god-level project you envision. Every so often, though, other people will also make changes to the Controls code and push those changes to GitHub. When this happens, you can pull these changes from the remote GitHub repository using

git pull 

This will fetch the changes and then apply them to your local repository. Since the files you have locally must be compatible with the version of code on the remote repository, it's recommended that you run "git pull" frequently to check for changes, especially when you are making a new branch or planning to merge a branch in to the master branch.

Branches

Branches

Branches are what allow us to work on multiple features at once while still keeping them separate from each other, or to have multiple people all working on the same repository. We can create branches to make alternate versions of our code and then merge them back together once we're ready. The main branch of the Controls repository is called "master," and this is where we keep the latest, most official version of our code. If you've just cloned the repository, you'll already be looking at this branch. However, when you start your own issue, you'll likely complete it on a new branch and then only merge it in to master once it's completely finished.

To make a new branch, you can run

git branch new_branch_name 

Now, if you type

git branch 

the new branch will show up along with master in a list of branches! Git will highlight the branch you're currently on, and you can check out and work on different branches using

git checkout branch_name 

There are many branches in the remote repository, but they won't come up under "git branch" unless you switch to them on your local machine first. To check out a branch that someone else has worked on, you can find the branch you want on GitHub (click "master" on the top left to choose from a drop-down menu) and switch to it using "git checkout." Once you do that, you'll have a branch on your local machine that is set up to track its remote branch, allowing you to fetch any new changes to that branch with "git pull."

New branches made on your computer start as a purely local branch. You can begin making changes, but neither the branch nor your changes will appear in the remote repository until you commit and push them to GitHub, which leads us to the next topic:

Committing and Pushing

Committing

Whenever you finish a key part of your code, you'll want to save it by "committing" those changes using git. But before that, it's good practice to first run the command

git status 

This will give us some key information that will help ensure we're saving the changes we want to save where we want to save them. 

Git status will tell us

  • What branch we're on
  • Whether our local branch has commits ahead of and/or behind the origin remote branch (if one exists)
  • Changes staged for commit
  • Changes not staged for commit
  • Untracked files

Checking which branch we're on is vital to ensuring we're committing to the right one. Additionally, it's good to note how our local branch compares to the remote one. If you've just created a new branch, then there is no remote branch yet. However, if you were to check out a remote branch and then commit to it, git status would tell you that you're now one commit ahead of the origin branch. If someone were to make commits to the origin branch, then you'd also be a few commits behind the origin. (In that case, you'd probably want to use "git pull" to grab the new commits so that you can make sure everything works together smoothly before pushing your own changes back to the remote branch.)

We highly recommend running git status frequently to make sure that your commands are doing what you intend.

The last three sections are related to the "staging environment," and what changes you want to save. New files that you make begin in

1. The Untracked Files section

Files listed here are not watched by Git, so although you can edit and save them normally, changes in these files won't be tracked or have version control. Git tells you, however, that you can include these files using

git add <file>

If you do that and re-run "git status," your new file will appear in green under "Changes to be Committed." We'll circle back to that in a moment. 

The second place your files may be listed is

2. Changes not staged for commit

Whenever you save changes to files already being watched by Git, they'll appear in this section. Changes here may be saved normally, but to commit them for version control, you'll once again need to use git add  to add them to the staging area. (Tip: you can type git add <path/to/file>  to add everything in a specific directory, and git add .  to add everything in the current directory. You can also use the wildcard * as a substitute for any pattern in the filename, ex: *.c will add all c files.)

After running git add  your files will be in the final area:

3. Changes to be committed

When you make a commit, the changes in these files are the ones that will be saved. If you decide you don't want to save some of these files after all, you can remove them using

git restore --staged <file> 

Running git restore <file>  will discard any changes to that file that are only saved in the local directory (not yet committed).

Finally, once you've checked that you're on the right branch and have added the files you want to save, you can commit them using

git commit -m "Write your commit message here" 

The "-m" flag lets you write your commit message within the command as shown above. While not necessary, it's a bit more convenient than having to write it afterwards when using git commit  by itself. Either way, it's important to write an informative commit message that will allow you (and anyone else) to remember what happened in that commit in case you want to go back to it later.

And with that, you've made a commit! The last step is to push your changes to GitHub so that they're available to everyone else, and you can do that using

git push 

The first time to you try to push changes from a local branch, Git will tell you to use the flag "--set-upstream" to set your local branch to follow a remote branch. Once you've set an upstream branch for your local one, however, all you'll need to do is run git push  and Git will know which branch you want to update. It's recommended that you commit throughout the day and then push changes at least at the end of the workday, if not more frequently.

Merging

Whenever we want to add the features of one branch into another, we can combine them using a merge. This is how branches with finished features are added to the main branch, but it's also how you can pull new changes from a different branch onto your own.

The most common case is if the master branch is updated after you've already split a new branch off of it. You won't be able to merge in your branch if it's missing commits that are in master, so you'll need to merge master into your branch. To do this, you'll need to be in your branch. Run "git pull" to grab all the latest changes, then run

git merge <branch-name>

or git merge master  in this case to make the merge. If you're lucky, this will be all you need to do, but sometimes you'll run into dreaded merge conflicts

Merge conflicts occur whenever Git is not able to automatically combine two branches. When this happens, you'll need to manually choose which changes to apply. Git inserts "conflict markers" into your file like so:

Whenever greeting someone, make sure to say
<<<<<<< HEAD
extra cheese please!
=======
cheesed to meet you!
>>>>>>> branch-a

As you can see, the changes from HEAD (the commit your local files are currently on) and the changes from branch-a are compared. Merely delete whatever you don't want to keep, and stage + commit your changes.

For merging, you can also use VSCode's built-in merge editor. In the VSCode source control editor, you'll be able to see which files have issues. Upon finding them, VSCode will give you the option to open them in the merge editor, where you'll be able to select the changes you want from the two versions of code. When you've finished with a file, you can select it in the Source Control editor on the left hand side and choose to stage the changes, and once you've finished with all the conflicting files, you'll be able to finally make a commit completing your merge!

Git Cheatsheet/More Useful Commands

These are the ones that are probably most useful to developers on Solar starting out. A more in-depth cheatsheet can be found here or here or here.

CommandDescription
git clone <link> 

Creates a copy of a repository from a specified link and downloads it to the local machine.

git pull 

Fetches changes from a remote repository and merges them into the current branch.

git add <file> 

Stages specific files or folders in the working directory for the next commit.

git add -A 

Stages all changes, including untracked files and deletions, in the working directory for the next commit.

git add . 

Stages all changes in the current directory for the next commit.

git commit 

Records changes in the staged area, creating a new commit. Opens the default text editor for the user to specify a commit message.

git commit -m "<message>" 

Records changes in the staged area, creating a new commit with a commit message specified in the command itself.

git push 

Pushes local commits to a remote repository, updating the remote branch with the latest changes.

git restore --staged <file> 

Unstages changes for a specific file, reverting them from the staging area.

git restore <file> 

Discards changes in the working directory for a specific file, reverting it to the state of the last commit.

git status 

Displays the status of changes as untracked, modified, or staged in the working directory.

git branch 

Lists all local branches and highlights the currently active branch.

git branch -a 

Lists all branches including remote branches.

git branch <branch-name> 

Creates a new branch with the specified name.

git checkout <branch-name> 

Switches between branches or restores working tree files.

git checkout -b <branch-name> 

Creates a new branch and switches to it in a single command.

git merge <branch-name> 

Merges changes from a specified branch into the current branch.

git diff 

Shows the differences between the working directory and the staging area.

git diff --cached 

Displays the differences between the staging area and the last commit.

git fetch 

Fetches changes from a remote repository without merging them into the local branches.

git log 

Displays the commit history, showing details like commit messages, authors, and timestamps.

git log --oneline 

Displays a simplified one-line commit history, showing abbreviated commit hashes and commit messages.

git stash 

Temporarily saves changes that are not ready to be committed, allowing you to switch branches or perform other tasks.

git stash list 

Shows a list of stashed changes, including stash IDs and descriptions.

git stash pop 

Applies the latest stash and removes it from the stash list.

Resources

This article only provides the minimum information required to get started on Controls with Git; Git can do quite a bit more, and becoming familiar with its capabilities will place power in your hands. Some additional resources to further your knowledge include