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.