Last active
December 21, 2015 04:08
-
-
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!
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
or...
git reset --hard HEAD@{1}