Practical Git for the Unintiated


Part 2 in our series on breaking into software engineering. In this episode, we will talk about Git arguably one of the most important technologies that developers leverage daily. In my post on how to get into SWE I mentioned Git, and you will probably find it on many other people's lists, but Git has a lot of features and it can be daunting to look at something like Git and figure out how much you should know when getting started. This article will cover what Git is, why we use it, and which of its uses should you be competent with to meet people's expectations. As with all my articles, this is just my opinion of what you should know and what I commonly use.

What is Git?

Git is a version control system used for tracking changes, versions, etc. It can be used to allow many developers to work on the same code simultaneously while allowing for conflict resolution, rollbacks, and diverting streams of work.

Git, or something similar (looking at you Google), is used by pretty much every company under the sun. I will go out on a limb and say that any company not using Git (barring some exceptions like Google) will likely not be a great place to work. We can talk more about that somewhere else. My point is that Git is ubiquitous, you will need to know it, so why not get a head start?

How to use Git

I will not go through the installation of Git here, it is likely something like
brew install git depending on your machine, but you can find instructions online easily. I will break down the most basic git work-flow and what commands you should be familiar with.

My workflow

First I clone or create a repo, then I create a branch. I make some changes, commit them, create a pull request, merge changes into main. Then I will checkout main, pull the latest version, create a new branch, and work on a new feature. Along the way I will do some rebasing, look at the logs, check my status, view the diff, and a few other things I will detail below.

Cloning

Git allows you to store changes on some remote location, often Github or Gitlab, and clone that repository onto your local machine for development. To do this you will run the command git clone <url-of-your-repo> You will then have the repo on your machine and can begin coding.

Pulling

Your local version will not automatically sync with the remote, to get other changes which may have been pushed by someone else, you will have to pull the changes by running git pull <branch-name>. If you want to pull the newest version of main on remote you would say git pull origin main and if you simply want whatever your current branch is tracking (by default the remote version of itself) you would say git pull.

Branches

Git has a concept of branches. A branch represents a development path of your application. Your application will have a main branch which should be your current, live, version of your application. When you want to add features, make changes or anything other than just view the code, you should create a branch and work on it. The 2 main ways I create branches are:

  • git branch <branch-name>
    git checkout <branch-name>
    This will create a new branch and then you will check it out (set it as your current branch)
  • git checkout -b <branch-name>
    This will create and checkout your branch in one step

Commits

In Git, sets of changes are referred to as "commits". Commits consist of a set of changes and a message. They can be referred to by a hash, which we will go into a bit later. To create a commit you will first make some changes, edit a file, create a file, etc. Once your changes have been made you have to "track" them. To see what changes you have made you can run git status to see the files changes and which are staged or unstaged. If you want to look at the actual differences between files you can run git diff which will show all the changes you have made when compared to the remote. To track your changes you run git add <file-names> you can also run git add . to track everything, but be careful there...

Now that you have tracked changes you create a commit git commit. This will put all of the changes into one group which can be referred to later these changes are considered "staged". A window will pop up prompting you for a description for your commit, you can make this a bit faster by running git commit -m "<your commit message>" to provide your commit message when creating your commit.

Pushing/Pull Requests

To send your local changes to the remote, you will have to run git push, but there is some nuance here. Usually, you should never push to main (unless you are the only user of some small repo, but still it's not wise). Instead, you should push to the remote version of you branch and then create what Github calls a "Pull Request" or what Gitlab calls a "Merge Request". This is a document that says "Hey I want to merge my changes to main" and then someone will look at your changes and reject or accept them, at which point you can merge them into main to become the live version. To accomplish this you will run:
git push -u origin <branch-name>
This will create a remote branch named <branch-name> and set up your local branch to follow it. It will then push your commits to that branch. You will then be prompted to create a Pull Request. From now on you will not have to specify which branch to push or pull from.

Getting remote branches

You might have to pull someone else's branch onto your machine. To do that you run git fetch followed by git checkout <branch-name>

Merging/Resolving conflicts

Sometimes someone will push to your branch, but you have local changes. You can merge, which will try to resolve the conflicts and will then prompt you to solve them yourself, or you can git pull --rebase which will accept the remote changes as the current version and stick your changes on top of them. Often I choose to rebase, but when there are many complex changes it can be complicated and a merge might be easier.

Walking through history

Running git log will show you all of the commits in history, and you can jump between them with git checkout <commit-hash> This can allow you to revert changes or test different commits.

Undoing

If you want the remote version of a file you can run git restore <file-name>. To remove your working changes you can run git reset --soft to only remove unstaged changes, or git reset --hard to reset all tracked changes.

Stash

Jumping between branches will bring your unstaged changes with you and often complain, to get around this, and other potential issues you can stash your changes git stash to hop around or experiment, and when you want them back you can run git stash pop

Others

There are some other commands I won't go into here which are worth learning on your own, later, they include:

  • cherrypick
  • bisect
  • More complex versions of the commands we have mentioned.

You now have the basics (and most of the important parts) of Git 😎