Lesson 4
Git Fetch and Pull: Managing Remote Changes and Resolving Conflicts
Introduction

As we reach the final lesson of the "Working with Remote Repositories" course, get ready to master the art of collaboration! Throughout this journey, we've explored local and remote branches, discovering their vital roles in teamwork. Now, in this exciting conclusion, we'll delve into git fetch and git pull, equipping you with the tools to manage remote changes and resolve conflicts seamlessly. These powerful commands will enhance your synchronization capabilities, setting the stage for smooth and efficient collaboration. Let's dive in!

Remote Tracking Branches

Remote tracking branches provide a way to keep tabs on changes in remote repositories without affecting your local branches immediately. When you clone a repository, Git sets up two types of references for branches:

  • Local branches (like main), which you actively work on and where you make changes.
  • Remote tracking branches (like origin/main), which represent the state of branches on the remote repository.

In a synchronized state, main and origin/main both point to the same commit, indicating that your local branch is up-to-date with the remote branch.

Here is a diagram that shows origin/main and main both pointing to the same commit, illustrating this synchronized state:

This dual-reference setup allows you to monitor changes from collaborators while choosing when to integrate updates into your local branch.

When Your Local Branch is Ahead of "origin/main"

As you work on your local branch (main), you might add commits that aren’t yet reflected in the remote tracking branch (origin/main). This means your local branch is "ahead" of the remote branch. When this happens, git status will indicate that your branch is ahead, giving you a reminder that there are commits waiting to be pushed.

Here is a diagram showing main being ahead of origin/main, with additional commits in main that haven't been pushed to the remote repository:

You’ll see a message similar to the following when you run git status:

Bash
1On branch main 2Your branch is ahead of 'origin/main' by 2 commits. 3 (use "git push" to publish your local commits) 4nothing to commit, working tree clean

This output tells you that your local branch main has two commits that aren’t yet reflected in origin/main on the remote repository.

This information helps you keep track of your local changes and decide when to update the remote repository.

Exploring Branches After Cloning

Imagine you’re collaborating on a travel project repository with different branches for each trip destination: paris, tokyo, and new-york. When you clone the repository, only the default branch, main, appears in your local environment. However, branches for each destination are still available on the remote repository.

To see these remote branches, use:

Bash
1git branch -r

The output might look like this:

Bash
1origin/paris 2origin/tokyo 3origin/new-york 4origin/main

This shows that branches for paris, tokyo, and new-york exist in the remote repository, along with main.

Switching Branches and Encountering Errors

You’re currently on main, but let’s say you want to start planning for the paris trip. To work on this branch locally, use:

Bash
1git switch paris

Since paris exists as a remote branch (origin/paris), Git will automatically create a local branch named paris that tracks the remote branch. You’ll see output like this:

Bash
1Switched to a new branch 'paris' 2Branch 'paris' set up to track remote branch 'paris' from 'origin'.

Now, a local branch named paris is created and set to track the origin/paris branch, allowing you to make changes specific to the paris trip.

However, if you try to switch to a branch that doesn’t exist on the remote, like london, Git will return an error because it cannot find a corresponding branch:

Bash
1git switch london

You’ll see an error message:

Bash
1error: could not find remote branch london to clone. 2fatal: invalid reference: london

This reminder helps you avoid confusion by ensuring that the branch you want to switch to exists on the remote. With git switch, you can explore branches and start working on new features or destinations with confidence, knowing that Git will guide you if something is amiss.

Deep Dive into "git fetch"

Previously, we explored a scenario where you added changes locally that didn’t yet exist in the remote repository. Now, let’s consider the opposite situation: imagine you’re working on a project with a teammate, and they’ve made updates to the remote repository that you don’t yet have in your local branch.

Here is a diagram showing this setup, where your teammate’s changes are present in the remote branch (origin/main) but are not yet in your local branch (main). It looks like Cosmo might be unsure of what to do next, but no worries – this is exactly where git fetch comes into play:

To see these new changes without affecting your local branch, you can use:

Bash
1git fetch origin

The git fetch command retrieves the latest information from the remote repository, updating your remote tracking branch (origin/main). This allows you to see if new commits or changes have been made by your teammate without merging them into your local branch (main) right away.

It typically completes without output if there are no new changes to download from the remote. However, if there are updates, git fetch may display a brief summary of new commits that were fetched. This summary generally includes information such as the branch name and the latest commit IDs, indicating that the local repository has fetched updates from the remote without merging them into the current branch.

Using git fetch regularly keeps you informed of changes in the remote repository, giving you control over when to incorporate these updates into your work.

Understanding and Exploring Changes After Fetching

When you run git fetch, Git updates your remote tracking branches to reflect the latest commits from the remote repository. This means that any new changes made by collaborators on the remote repository are now visible in your remote tracking branches (like origin/main), but your local branches remain unchanged.

Here is a diagram that shows the repository state after fetching. Notice that origin/main has advanced with new commits that are not yet in your local branch main:

This setup allows you to review what has changed on the remote side before deciding whether to bring those changes into your local branch.

Exploring "git fetch --dry-run"

Before fetching updates from a remote repository, you might want to assess what changes are available without yet integrating them into your remote tracking branches. The git fetch --dry-run command is useful in this scenario, as it allows you to preview potential updates from the remote repository without modifying your local environment.

Here’s how you can use it:

Bash
1git fetch --dry-run

When you run this command, it provides output listing the branches and new commits that would be fetched if you performed a normal git fetch.

Using our travel project example, where updates have been made by a teammate on the paris branch, the output might look something like this:

Plain text
1From https://your.remote.repo.url 2 123abcd..456efgh main -> origin/main 3 * [new branch] paris -> origin/paris

In this output:

  • The line without an asterisk (main) indicates that there are new commits on the existing main branch that would be fetched to update your local remote tracking branch origin/main.
  • The line with an asterisk (paris) shows that paris is a new branch on the remote that would be added to your local repository's remote tracking branches.

By reviewing these details, you can plan your next actions with full awareness of incoming changes while keeping your current work intact.

Understanding "git pull" and Its Implications

While git fetch updates your remote tracking branches without changing your local branches, git pull combines git fetch and git merge in one step. When you run git pull, Git fetches the latest changes from the remote repository and attempts to merge them directly into your current local branch in one seamless action.

For example:

Bash
1git pull origin main

This command first fetches changes from the main branch on the remote repository and then merges them into your current local branch (which is typically also main). Using git pull is convenient when you want to synchronize your local branch with the remote branch quickly, incorporating any updates made by collaborators.

However, because git pull automatically merges changes, it can sometimes lead to merge conflicts if your local branch has modifications that conflict with the updates from the remote branch.

Handling Merge Conflicts After Pulling

If you encounter a merge conflict during a git pull, Git will alert you and mark the conflicting files. Here’s how to resolve these conflicts:

  1. Identify Conflicts: Git will list the files with conflicts and show conflict markers within the files, indicating areas with differences.

  2. Resolve Conflicts: Edit each file with conflicts, choosing which changes to keep. Remove the conflict markers once you’re done.

  3. Mark the Conflicts as Resolved: After resolving conflicts, mark the files as ready for the merge:

    Bash
    1git add <conflicted-file>
  4. Complete the Merge: To finalize the merge, commit the changes:

    Bash
    1git commit

By following this process, you can resolve conflicts carefully, ensuring that your code remains functional after the pull.

"git pull" vs. "git fetch"

Understanding the differences between git pull and git fetch can help you choose the best command for each situation. Here’s a detailed comparison:

CommandDescriptionWhen to UseAdvantagesPotential Issues
git fetchFetches updates from the remote branch, updating remote tracking branches only.Use when you want to review changes before merging.Allows you to see what’s new in the remote without affecting your local branches.Requires a separate git merge to integrate changes into the local branch.
git pullFetches updates and merges them into your current branch in one step.Use when you’re confident about the incoming changes.Quick and efficient for keeping branches synchronized without extra steps.Can lead to unexpected merge conflicts if there are local changes.

In short:

  • git fetch gives you control by allowing you to review changes before merging. It’s a great choice if you’re unsure of the changes or want to avoid conflicts.
  • git pull is efficient for immediate synchronization, but it automatically merges changes into your local branch, which may result in merge conflicts if you have conflicting local work.
Summary

This lesson covered managing remote changes using git fetch and git pull. We explored how remote tracking branches reflect updates without affecting local branches. By understanding scenarios where local branches are ahead, we learned when to utilize git push. We examined git fetch for reviewing remote changes and git pull for direct synchronization, discussing their distinct advantages and the potential for merge conflicts. Finally, we outlined steps to resolve merge conflicts effectively. Now, transition to the practice section to strengthen your skills in handling remote changes and conflict resolution. Dive in and enjoy the challenge—good luck!

Enjoy this lesson? Now it's time to practice with Cosmo!
Practice is how you turn knowledge into actual skills.