Skip to Content
DraftsStage 2GitIntro to Git

Intro to Git

Software evolves over time as changes are made to add new features or fix bugs.

As a single developer, it’s pretty easy to edit files directly on your own computer, but if we want to have a team of developers to help out on the same project, how would it work?

The simplest way would be taking turns using the computer, but that’s not very efficient. Can we do better?

One Version

One system that allows for easy collaboration is Google Docs. Everyone can type at the same time directly into a single document that is hosted online. As long as everyone is editing different parts, this works pretty well.

But this system starts to break down once people start overlapping their edits. It gets chaotic and usually someone has to stop to let the other person go first.

Another issue is around experimentation. You might want to make some bigger changes like changing the color scheme, but you’re not sure if you’ll like it. Other people would continue editing with the experimental color scheme, and now you can’t easily undo your big change if you end up not liking it.

It gets worse if we were to try using this system to write code because many systems require all the project code to run, so it’s hard to test our changes without dealing with everyone else’s changes. If someone asked us to show what we’ve done so far, the project might not even work because someone else is in the middle of a big change and isn’t finished yet.

How can we experiment and test our own changes?

Branches

What we want is to temporarily work in isolation from everyone else. In Google Docs, the simplest way would be to create a copy of the document. Similarly, we could copy the entire source code folder and work independently from there.

Git calls these independent copies “branches”, and it’s the primary way to work on your own changes. In fact, Git makes creating branches very easy and fast, and it also helps keep track of what is happening.

Branches are primarily identified by their name, so usually you create a branch with a name that is unique to you or what you’re working on. This let’s other team members know it’s your branch, and usually only you are making changes to it.

Now we can work individually on our changes, letting us experiment and test our own changes easily in our own copy. Whenever you are happy with the change you’ve made, you take snapshots of the project, along with a message describing what you’ve done. Git calls these snapshots “commits”. As you make commits, Git updates the branch you’re working on to correspond to the commit you just made, so you can also return to that snapshot of the project using the name of the branch.

A commit also contains additional information such as what previous commit it was based on, when it was made, and its author.

feature
main

Merging

However, once you’re happy with our changes, you’ll want it to be included in the final version. So how does that work? Will we need to copy and paste all our changes back into the version that others can see?

Git allows us to keep track of these diverging timelines since it records what happened to each branch based on the commits that were made. Then it can show what changes are relevant between any two branches.

Usually, there is a main branch that corresponds to the latest snapshot of the project. This main branch is likely the snapshot of the project that is being used out in the world and is usually referred to as “main” or “master”. As we made commits on our separate branch, our snapshot of the project became less similar to the “main” branch snapshot that we started with.

Now we want the “main” branch to includes the changes we’ve made to our branch. The primary way to do this on a team is to create a request to “merge” our changes into another branch. This request is usually done through some additional code review software separate from Git, and are usually referred to as “pull requests” or “merge requests”. This is because we want to make sure the main branch remains well understood and stable. To keep this focused on Git, we will skip the step of requesting a merge and instead do the merge without any other software that would do it for us.

Usually we ask Git to perform a merge between two branches, where one branch serves as the target and the other branch serves as the source of the changes. After the merge, the target branch will be updated with a new snapshot that includes the changes from the source branch. The difficulty is that changes have usually been made to both the source branch and the target branch.

How does this work? How does Git know what changes should be brought over?

When we ask Git to perform a merge between two branches, it will look at the history of those two branches to find when they diverged. It can know when they diverged because each commit contains information about the commit it was based on, so it can walk backwards from the current commit of each branch until it finds a commit that is a common ancestor.

This ancestor commit serves as the base and it can then know what happened in the target branch and what happened in the source branch. In other words, it only looks at changes made since the ancestor commit.

💡
Git can be hard because it’s the multiverse, plus merging

Conflicts

master Summer Merch Available sale Summer Merch Available - Sale 20% OFF winter Winter Merch Available We don't want the new one to be Winter Merch Available - Sale 20% OFF! In fact git will say there is a conflict This is because the left side and right side have made changes to the same region of code So it requires you to tell it what that region should look like going forward on the branch you're making the merge commit on once the merge commit is created the latest common ancestor will be newer

PRs

sometimes a merge commit may be the last step with merge commits from master to your branch

Subscribe for more

Get notified about new pages.
Unsubscribe anytime.