summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJunio C Hamano <junkio@cox.net>2005-08-09 22:30:17 -0700
committerJunio C Hamano <junkio@cox.net>2005-08-09 23:38:49 -0700
commit045f82cbee3135a3d75256828b0cf101eedf38c8 (patch)
tree986795a0ba6489139fbbf1c1b5efd602ff6d6136
parentd87449c553262a24df26648633c7c73b2db7dcc6 (diff)
downloadgit-045f82cbee3135a3d75256828b0cf101eedf38c8.tar.gz
git-revert: revert an existing commit.
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>
-rw-r--r--Makefile1
-rwxr-xr-xgit-revert-script37
2 files changed, 38 insertions, 0 deletions
diff --git a/Makefile b/Makefile
index c14ec4f82a..5efb6268a1 100644
--- 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
index 0000000000..dc2dea4898
--- /dev/null
+++ b/git-revert-script
@@ -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