Master Git - Understanding Branches, Remotes, and HEAD for Better Collaboration

Demystify key Git concepts like local vs. remote branches, fetching, pulling, pushing, and the HEAD pointer to improve your version control skills and team collaboration.

Git Official Documentation

Demystifying Git: Understanding Branches, Remotes, and HEAD

As developers, we use Git and GitHub daily, but some concepts can still trip us up. Today, we’re going to demystify some common Git scenarios and concepts that often cause confusion. We’ll focus on the relationship between local and remote branches, the git fetch command, and the ever-mysterious HEAD.

The Tale of Two Branches: Local vs. Remote

Imagine you’re working on a feature branch called awesome-feature. You’ve created this branch locally and pushed it to GitHub. Now, both your local machine and GitHub have a branch called awesome-feature. But here’s the kicker: these two branches can diverge!

Real-life scenario:

  1. You create awesome-feature locally and push it to GitHub.
  2. Your colleague, Alice, pulls awesome-feature, makes some changes, and pushes to GitHub.
  3. Now, the awesome-feature on GitHub has changes that your local awesome-feature doesn’t.

This is where the concept of “remote branches” comes in. Your local Git keeps track of the state of branches on GitHub (or any remote) using “remote-tracking branches”. These are usually named origin/branch-name.

Fetching: Updating Your Local Knowledge

When you run git fetch origin, you’re essentially asking Git to update its knowledge about the state of the remote repository. It’s like checking for new emails without actually opening them.

What git fetch does:

  1. It communicates with GitHub to see what changes exist on the remote.
  2. It updates your local remote-tracking branches (like origin/awesome-feature).
  3. It doesn’t change your working directory or local branches.

After fetching, you can see what’s new:

1
2
git fetch origin
git diff awesome-feature origin/awesome-feature

This shows you what changes are on GitHub that you don’t have locally.

Pull: Fetch + Merge

The git pull command is actually a combination of two steps: fetch and merge. It’s like checking for new emails and automatically putting them in your inbox.

1
git pull origin awesome-feature

This fetches the latest changes from the awesome-feature branch on GitHub and merges them into your current local branch.

Push: Sharing Your Changes

When you try to push your changes, Git checks if your local branch has diverged from the remote branch. If it has, you’ll get an error like:

! [rejected]        awesome-feature -> awesome-feature (non-fast-forward)
error: failed to push some refs to 'https://github.com/your-repo.git'

This is Git’s way of protecting you from accidentally overwriting changes on the remote.

How to resolve:

  1. First, pull the latest changes:
    1
    
    git pull origin awesome-feature
    
  2. Resolve any merge conflicts if they occur.
  3. Then push your changes:
    1
    
    git push origin awesome-feature
    

The Mysterious HEAD

HEAD is Git’s way of knowing “where you are” in the history of your project. It’s like a bookmark in a book.

Normal HEAD:

Usually, HEAD points to the latest commit of your current branch. When you make a new commit, HEAD moves forward automatically.

HEAD -> awesome-feature -> Latest Commit

Detached HEAD:

Sometimes, you might checkout a specific commit or a remote branch directly:

1
2
3
git checkout abc123  # Some commit hash
# or
git checkout origin/awesome-feature

Now you’re in a “detached HEAD” state. It’s like you’ve placed your bookmark on a specific page, rather than at the end of a chapter.

In this state:

  • You can look around and make experimental changes.
  • If you make commits, they won’t belong to any branch.
  • To save your work, create a new branch:
    1
    
    git checkout -b experimental-idea
    

Best Practices

  1. Fetch Often: Regularly run git fetch to stay updated with remote changes.
  2. Pull Before Push: Always pull before pushing to avoid rejection.
  3. Use Branches: Create feature branches for new work to keep main/master clean.

Cheers! 🍺