Understand Git history
Git represents history in a fundamentally different way than centralized version controls systems (CVCS) such as Team Foundation Version Control, Perforce, or Subversion. Centralized systems store a separate history for each file in a repository. Git stores history as a graph of snapshots of the entire repository. These snapshots, called commits in Git, can have multiple parents, creating a history that looks like a graph instead of a straight line. This difference in history is incredibly important and is the main reason users familiar with CVCS find Git confusing.
Commit history basics
Start with a simple history example: a repo with three linear commits.
Commit A is the parent of commit B, and commit B is the parent of commit C. This history looks very similar to a CVCS. The arrow pointing to commit C is a branch. Branches are pointers to specific commits, which is why branching is so lightweight and easy in Git.
A key difference in Git compared to CVCS is that the developer has their own full copy of the repo. They need to keep their local repository in sync with the remote repository by getting the latest commits from the remote repository. To do this, they pull the main branch with the following command:
git pull origin main
This merges all changes from the main branch in the remote repository, which Git names origin
by default. This pull brought one new commit and the main branch in the local repo moves to that commit.
Understand branch history
Now it's time to make a change to the code. It's common to have multiple active branches when working on different features in parallel. This is in stark contrast to CVCS where new branches are heavy and rarely created. The first step is to checkout to a new branch using the following command:
git checkout -b cool-new-feature
This is a shortcut combining two commands:
git branch cool-new-feature
to create the branchgit checkout cool-new-feature
to begin working in the branch
Two branches now point to the same commit. Suppose there are a few changes on the cool-new-feature
branch in two new commits, E and F.
The commits are reachable by the cool-new-feature
branch since they were committed to that branch.
Now that the feature is done, it needs to be merged into the main branch. To do that, use the following
command:
git merge cool-new-feature main
The graph structure of history becomes visible when there's a merge. Git creates a new commit when the branch is merged into another branch. This is a merge commit. There aren't any changes included this merge commit since there were no conflicts. If there were conflicts, the merge commit would include the changes needed to resolve them.
History in the real world
Here's an example of Git history that more closely resembles code in active development on a team.
There are three people who merge commits from their own branches into the main
branch around the
same time.
Next steps
Learn more about working with Git history in GitHub and Azure Repos or Git log history simplification.