How to Check If a Git Remote Has New Commits

GitGitBeginner
Practice Now

Introduction

In this lab, you will learn how to check if a Git remote repository has new commits that are not yet present in your local repository. This is a crucial skill for collaborative development, allowing you to stay updated with changes made by others.

We will begin by simulating a remote repository and adding it to our local project. Then, we will use the git fetch command to retrieve information about the remote's branches and commits without merging them. Finally, we will explore how to compare your local branch with its upstream counterpart to identify any new commits on the remote.


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL git(("Git")) -.-> git/DataManagementGroup(["Data Management"]) git(("Git")) -.-> git/BranchManagementGroup(["Branch Management"]) git(("Git")) -.-> git/CollaborationandSharingGroup(["Collaboration and Sharing"]) git/DataManagementGroup -.-> git/reset("Undo Changes") git/BranchManagementGroup -.-> git/log("Show Commits") git/CollaborationandSharingGroup -.-> git/fetch("Download Updates") git/CollaborationandSharingGroup -.-> git/pull("Update & Merge") git/CollaborationandSharingGroup -.-> git/remote("Manage Remotes") subgraph Lab Skills git/reset -.-> lab-560074{{"How to Check If a Git Remote Has New Commits"}} git/log -.-> lab-560074{{"How to Check If a Git Remote Has New Commits"}} git/fetch -.-> lab-560074{{"How to Check If a Git Remote Has New Commits"}} git/pull -.-> lab-560074{{"How to Check If a Git Remote Has New Commits"}} git/remote -.-> lab-560074{{"How to Check If a Git Remote Has New Commits"}} end

Fetch Remote with git fetch

In this step, we'll learn how to fetch changes from a remote repository. Imagine you're working on a project with others, and they've made some updates. You need to get those updates to your local machine. The git fetch command is how you do this. It downloads the latest changes from a remote repository but doesn't merge them into your current branch.

First, let's simulate having a remote repository. We'll create a bare repository and then add it as a remote to our existing my-time-machine repository.

cd ~/project
mkdir remote-repo.git
cd remote-repo.git
git init --bare

This creates a bare Git repository, which is typically used as a central repository that developers push and pull from.

Now, let's go back to our my-time-machine repository and add this bare repository as a remote.

cd ~/project/my-time-machine
git remote add origin ~/project/remote-repo.git

We've named our remote origin, which is a common convention. Now, let's verify that the remote was added correctly.

git remote -v

You should see output similar to this, showing the fetch and push URLs for the origin remote:

origin	/home/labex/project/remote-repo.git (fetch)
origin	/home/labex/project/remote-repo.git (push)

Now, let's simulate a change in the remote repository. Since it's a bare repository, we can't directly make commits in it. Instead, we'll simulate a change by creating a new file in the bare repository's directory.

cd ~/project/remote-repo.git
echo "This is a remote change" > remote_file.txt

Now, go back to your my-time-machine repository.

cd ~/project/my-time-machine

At this point, your local repository doesn't know about the remote_file.txt that was added to the simulated remote. This is where git fetch comes in.

Run the git fetch command:

git fetch origin

You might not see much output, or you might see something indicating that new objects were received.

What git fetch origin did was connect to the origin remote and download any new commits and objects that are not in your local repository. However, it did not merge these changes into your current branch (master). The changes are now available in your local repository, but they are stored in a special branch that tracks the remote, typically named origin/master.

This is a key difference between git fetch and git pull. git pull is essentially git fetch followed by a merge. By using git fetch first, you can see what changes are available on the remote before deciding to integrate them into your work. This gives you more control and helps prevent unexpected conflicts.

In the next step, we'll see how to compare your local branch with the fetched remote branch to understand what changes were downloaded.

Run git log HEAD..@{u}

In the previous step, we used git fetch to download changes from the remote repository. Now, let's see how we can view the commits that are on the remote but not yet in our local branch. This is where the command git log HEAD..@{u} is very useful.

Make sure you are still in the ~/project/my-time-machine directory.

cd ~/project/my-time-machine

Now, run the following command:

git log HEAD..@{u}

You might see output similar to this:

commit abcdef1234567890abcdef1234567890abcdef (origin/master)
Author: Simulated User <[email protected]>
Date:   Mon Aug 7 10:05:00 2023 +0000

    Simulated remote commit

Let's break down this command:

  • git log: This is the command to view commit history.
  • HEAD: This refers to the commit your current branch is pointing to.
  • @{u}: This is a shorthand for the upstream branch. In our case, since we fetched from origin and our local master branch is tracking origin/master, @{u} refers to origin/master.
  • HEAD..@{u}: This is a range notation in Git. It means "show me the commits that are reachable from @{u} but not reachable from HEAD". In simpler terms, it shows you the commits that are on the remote tracking branch (origin/master) but are not on your current local branch (master).

This command is incredibly helpful for seeing what changes you will get if you were to merge or rebase your local branch with the remote tracking branch. It allows you to review the incoming changes before integrating them, which is a crucial part of a safe and controlled workflow.

You might be wondering, "How did Git know about the simulated remote commit?" When we ran git fetch origin in the previous step, Git downloaded the information about the commits in the origin repository, including the commit that introduced remote_file.txt. This information is stored in the origin/master tracking branch in your local repository. The git log HEAD..@{u} command then compares your local master branch (HEAD) with this origin/master tracking branch (@{u}) to show you the difference.

Press q to exit the log view if it's in full-screen mode.

Understanding the difference between your local branch and the remote tracking branch is fundamental to working effectively with remote repositories. This command provides a clear way to visualize those differences.

Test Synced Remotes

In the previous steps, we fetched changes from a simulated remote repository and learned how to view the commits that are on the remote but not in our local branch using git log HEAD..@{u}. Now, let's see what happens when our local branch is up-to-date with the remote tracking branch.

First, let's simulate merging the remote changes into our local branch. While git fetch only downloads changes, git pull downloads and then merges. For the purpose of this test, we'll simulate the state after a pull by manually updating our local branch to match the remote tracking branch.

Make sure you are in the ~/project/my-time-machine directory.

cd ~/project/my-time-machine

Now, let's simulate the merge by resetting our local master branch to the same commit as origin/master. Note: In a real scenario, you would typically use git merge origin/master or git pull origin master to integrate changes. We are using git reset --hard here purely for demonstration purposes to quickly put our local branch in sync with the remote tracking branch for the test.

git reset --hard origin/master

You should see output indicating that your branch has been updated and the working tree is clean.

HEAD is now at abcdef1 Simulated remote commit

Now that our local master branch is synced with origin/master, let's run the git log HEAD..@{u} command again.

git log HEAD..@{u}

This time, you should see no output.

Why no output? Because HEAD (our local master branch) and @{u} (the origin/master tracking branch) are now pointing to the same commit. The range HEAD..@{u} is empty because there are no commits reachable from @{u} that are not also reachable from HEAD.

This is the expected behavior when your local branch is fully synchronized with its upstream remote tracking branch. The git log HEAD..@{u} command is a quick way to check if there are any incoming changes from the remote that you haven't integrated yet. If the command shows no output, it means your local branch is up-to-date with the remote tracking branch.

Understanding how to check for incoming changes and how to interpret the output of git log HEAD..@{u} is essential for collaborating with others and keeping your local repository in sync with the remote.

Summary

In this lab, we learned how to check if a Git remote has new commits. We began by understanding the purpose of git fetch, which downloads changes from a remote repository without merging them. We simulated a remote repository by creating a bare Git repository and adding it as a remote named origin to our local my-time-machine repository. We verified the remote setup using git remote -v.

Next, we simulated a change in the remote repository by creating a file directly in the bare repository's directory. We then used the git fetch origin command to retrieve these changes into our local repository, preparing us to check for new commits.