A Git Check for Missing Commits From a Remote

Branching Game

I recently add a pre-flight check to a devops project to ensure that all commits from the Git repository’s origin/master are present locally. This is to guard against developers accidentally reverting others’ deployed changes.

It took a bit of Git fu to figure out. The command to run is:

$ git rev-list HEAD..origin/master

This checks for commits that are on the remote called origin’s master branch but not in the history for the current checkout (HEAD). Git lists any such commit SHA’s one per line:

$ git rev-list HEAD..origin/master
99bba25e2e7bd120d3f0e65b2b2dcaf5d4eeb3d0
a725f37f01e799bf35aa292f7be5159716864a7d

If there are no such commits, the output will be empty.

Note it does not check for the reverse case: commits in the local checkout’s history that are not present on origin/master. For example, if you’re on your local master and have committed but not pushed, that will not appear.

I wrote my check in Python, using subprocess.run to execute git and inspect the output:

import subprocess
import sys


def _check_git_includes_origin_master():
    subprocess.run(["git", "fetch", "origin"])
    rev_list_run = subprocess.run(
        ["git", "rev-list", "HEAD..origin/master"],
        stdout=subprocess.PIPE,
        stderr=subprocess.PIPE,
        universal_newlines=True,
    )
    missing_commits = rev_list_run.stdout.splitlines()
    if missing_commits:
        print(
            (
                f"Current git status is missing {len(missing_commits)}"
                + f" commit{'s' if len(missing_commits) > 1 else ''} from"
                + f" origin/master. Please pull master and if necessary "
                + f"rebase the current branch on top."
            ),
            file=sys.stderr,
        )
        sys.exit(1)

Fin

Hope this helps with your Git automation!

—Adam


Make your development more pleasant with Boost Your Django DX.


Subscribe via RSS, Twitter, or email:

One summary email a week, no spam, I pinky promise.

Related posts:

Tags: ,