Skip to content

Instantly share code, notes, and snippets.

@jigpu
Created August 30, 2023 17:56
Show Gist options
  • Save jigpu/ee8cc222037826a8c146c5d1c416d82a to your computer and use it in GitHub Desktop.
Save jigpu/ee8cc222037826a8c146c5d1c416d82a to your computer and use it in GitHub Desktop.
Compare a commit in the current (input-wacom) repository with its upstream source.
#!/bin/bash
# compare-commit-upstream.sh
#
# Given a commit ID in the current repository, find the corresponding
# upstream commit and print out the difference, if any. If no upstream
# commit can be found, print a message and exit with code 0.
#
# Usage: ./compare-commit-upstream.sh <local-git-commit-id>
function extract_unifed_without_context() {
# Read a patch file in unified diff format and print out only the
# added and removed lines. Removes all context (unchanged lines)
# and other non-patch data (e.g. commit messages from git patches).
awk '/^@@/,/^diff/' "$1" | grep -E "^[+-]"
}
function patch_diff() {
# Compare two unified diff patches to see if they are "identical".
#
# Given two files in unified diff format, this function checks to
# see if they add and remove the same text. This function is very
# stupid and doesn't care what the surrounding lines look like,
# what the file names are, etc.
LEFT=$(extract_unifed_without_context "$1")
RIGHT=$(extract_unifed_without_context "$2")
diff -u <(echo "$LEFT") <(echo "$RIGHT")
}
function find_upstream_commit_id() {
# Extract the commit ID of the upstream parent, if possible.
#
# Given the ID of a commit in the local repository, we search for the
# line of information in the sign-off block that contains information
# on the upstream commit and return its ID.
KEYWORD="Imported into input-wacom"
git log -1 "$1" | grep "$KEYWORD" | grep -Eo '\([0-9a-fA-F]+\)' | tr -d '()'
}
function print_upstream_commit() {
# Print out a commit which has been accepted upstream.
#
# Given the ID of a commit accepted upstream, find and print out the
# commt in patch form. This function should find any commit merged
# into the HID tree, even if Linus has not picked it up yet.
URLBASE="https://git.kernel.org/pub/scm/linux/kernel/git/hid/hid.git/patch/"
curl "${URLBASE}?id=${1}" | head -n -3
}
function compare_commit_to_upstream() {
# Compare a commit in the current repository with its upstream source.
#
# Given a commit ID in the current repository, find the corresponding
# upstream commit and print out the difference, if any. If no upstream
# commit can be found, print a message and exit with code 0.
DOWNSTREAM="$1"
UPSTREAM=$(find_upstream_commit_id "$DOWNSTREAM")
if [[ -z "$UPSTREAM" ]]; then
echo "No upstream commit found for $DOWNSTREAM. Exiting."
exit 0
fi
echo "Comparing $DOWNSTREAM locally to $UPSTREAM upstream"
LEFT=$(git log -1 -p "$DOWNSTREAM")
RIGHT=$(print_upstream_commit "$UPSTREAM")
patch_diff <(echo "$LEFT") <(echo "$RIGHT")
}
compare_commit_to_upstream "$1"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment