git-revert: revert an existing commit.
authorJunio C Hamano <junkio@cox.net>
Wed, 10 Aug 2005 05:30:17 +0000 (22:30 -0700)
committerJunio C Hamano <junkio@cox.net>
Wed, 10 Aug 2005 06:38:49 +0000 (23:38 -0700)
Given one existing commit, revert the change the patch
introduces, and record a new commit that records it. This
requires your working tree to be clean (no modifications from
the HEAD commit).

This is based on what Linus posted to the list, with
enhancements he suggested, including the use of -M to attempt
reverting renames.

Signed-off-by: Junio C Hamano <junkio@cox.net>
Makefile
git-revert-script [new file with mode: 0755]
index c14ec4f82a079383502c000bc3efc23fe7959c8a..5efb6268a1311099cb131f05feef81453011bf7e 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -70,6 +70,7 @@ SCRIPTS=git git-apply-patch-script git-merge-one-file-script git-prune-script \
 
 SCRIPTS += git-count-objects-script
 # SCRIPTS += git-send-email-script
+SCRIPTS += git-revert-script
 
 PROG=   git-update-cache git-diff-files git-init-db git-write-tree \
        git-read-tree git-commit-tree git-cat-file git-fsck-cache \
diff --git a/git-revert-script b/git-revert-script
new file mode 100755 (executable)
index 0000000..dc2dea4
--- /dev/null
@@ -0,0 +1,37 @@
+#!/bin/sh
+. git-sh-setup-script || die "Not a git archive"
+
+# We want a clean tree and clean index to be able to revert.
+status=$(git status)
+case "$status" in
+'nothing to commit') ;;
+*)
+       echo "$status"
+       die "Your working tree is dirty; cannot revert a previous patch." ;;
+esac
+
+rev=$(git-rev-parse --no-flags --verify --revs-only "$@") &&
+commit=$(git-rev-parse --verify "$rev^0") || exit
+if git-diff-tree -R -M -p $commit | git-apply --index &&
+   msg=$(git-rev-list --pretty=oneline --max-count=1 $commit)
+then
+        {
+                echo "$msg" | sed -e '
+                       s/^[^ ]* /Revert "/
+                       s/$/"/'
+                echo
+                echo "This reverts $commit commit."
+                test "$rev" = "$commit" ||
+                echo "(original 'git revert' arguments: $@)"
+        } | git commit -F -
+else
+        # Now why did it fail?
+        parents=`git-cat-file commit "$commit" 2>/dev/null |
+                sed -ne '/^$/q;/^parent /p' |
+                wc -l`
+        case $parents in
+        0) die "Cannot revert the root commit nor non commit-ish." ;;
+        1) die "The patch does not apply." ;;
+        *) die "Cannot revert a merge commit." ;;
+        esac
+fi