Skip to content

Instantly share code, notes, and snippets.

@wolever
Last active December 21, 2015 04:08
Show Gist options
  • Star 10 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save wolever/6246808 to your computer and use it in GitHub Desktop.
Save wolever/6246808 to your computer and use it in GitHub Desktop.
git-unpull: undoes the merge commit created by an accidental 'git pull', plus some added helpful information!
#!/bin/bash
# Reverts HEAD back to ORIG_HEAD, for example after a 'git pull' accidentally
# creates a merge. This is identical to running 'git reset --hard ORIG_HEAD',
# except that unpull prints some helpful information along the way.
# Useage:
# $ git unpull
# HEAD: a0ac0fd Merge branch 'master' of /tmp/foo
# 2284c9d some remote commit
# ORIG_HEAD: 35431fd my local commit
# Really reset HEAD to ORIG_HEAD? (y/n) y
# + git reset --hard ORIG_HEAD
# HEAD is now at 35431fd bar
# Installation:
# copy git-unpull to ~/bin/ or /usr/local/bin/, or wherever you prefer to
# keep such things.
IFS="`printf "\n\t"`"
set -eu
if [[ "$*" ]]; then
echo "usage: git unpull"
echo
echo "Reverts HEAD back to ORIG_HEAD, for example after a 'git pull'"
echo "accidentally creates a merge. This is identical to running"
echo "'git reset --hard ORIG_HEAD', except that unpull prints some"
echo "helpful information along the way."
echo
echo "Note that unpull can be run repeatedly; subsequent unpulls will"
echo "undo the previous unpull."
echo
echo "Hint: after an unpull, you can use 'git rebase --onto origin/master'"
echo "to rebase (as if you had run 'git pull --rebase')."
exit 1
fi
git log --format="%h %s" ORIG_HEAD..HEAD | {
num_changes=0
while read line; do
let "num_changes += 1"
if [[ "$num_changes" -eq 1 ]]; then
echo " HEAD: $line"
else
echo " $line"
fi
done
head="$(git log --format="%h %s" -n 1 HEAD)"
orig_head="$(git log --format="%h %s" -n 1 ORIG_HEAD)"
if [[ "$num_changes" -eq 0 ]]; then
echo " HEAD: $head"
fi
if [[ "$head" == "$orig_head" ]]; then
echo "ORIG_HEAD: $orig_head"
echo "HEAD and ORIG_HEAD are the same (nothing to do)"
exit 42
fi
if [[ "$num_changes" -eq 0 ]]; then
echo " (no common commits between HEAD and ORIG_HEAD)"
fi
echo "ORIG_HEAD: $orig_head"
if [[ "$num_changes" -gt 2 ]]; then
echo "warning: $num_changes commits between HEAD and ORIG_HEAD!"
fi
}
subst="$?"
if [[ "$subst" -eq 42 ]]; then
exit 0
fi
if [[ "$subst" -ne 0 ]]; then
echo "$subst"
fi
read -p "Really reset HEAD to ORIG_HEAD? (y/n) " confirm
if [[ "$confirm" == "y" || "$confirm" == "yes" ]]; then
set -x
git reset --hard ORIG_HEAD
fi
@skinofstars
Copy link

or... git reset --hard HEAD@{1}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment