{"thread":{"id":"1651","subject":"[PATCH] Redo \"revert\" using three-way merge machinery.","startedAt":"2005-08-26T08:04:42Z","lastAt":"2005-08-26T08:04:42Z","messageCount":1,"participants":["Junio C Hamano"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"7777","messageId":"7v8xypgm3p.fsf@assigned-by-dhcp.cox.net","threadId":"1651","inReplyTo":null,"subject":"[PATCH] Redo \"revert\" using three-way merge machinery.","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2005-08-26T08:04:42Z","receivedAt":"2005-08-26T08:04:42Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"The reverse patch application using \"git apply\" sometimes is too\nrigid.  Since the user would get used to resolving conflicting merges\nby hand during the normal merge experience, using the same machinery\nwould be more helpful rather than just giving up.\n\nSigned-off-by: Junio C Hamano <junkio@cox.net>\n\n---\n\n git-revert-script |   75 ++++++++++++++++++++++++++++++-----------------------\n 1 files changed, 42 insertions(+), 33 deletions(-)\n\n186bb385d806bf08b5a81888230ad7a96aec50c7\ndiff --git a/git-revert-script b/git-revert-script\n--- a/git-revert-script\n+++ b/git-revert-script\n@@ -2,38 +2,47 @@\n . git-sh-setup-script || die \"Not a git archive\"\n \n # We want a clean tree and clean index to be able to revert.\n-dirty=`git-diff-cache --name-only --cached HEAD`\n-case \"$dirty\" in '') dirty=`git-diff-cache --name-only HEAD` ;; esac\n-case \"$dirty\" in\n-'') ;;\n-*)\n-\techo >&2 \"Modified:\"\n-\techo \"$dirty\" | sed >&2 -e 's/^/\t/'\n-\tdie \"Your working tree is dirty; cannot revert a previous patch.\" ;;\n-esac\n+check_clean_tree || die \"Cannot run revert from a dirty tree.\"\n \n rev=$(git-rev-parse --verify \"$@\") &&\n-commit=$(git-rev-parse --verify \"$rev^0\") || exit\n-if git-diff-tree -R -M -p $commit | git-apply --index &&\n-   msg=$(git-rev-list --pretty=oneline --max-count=1 $commit)\n-then\n-        {\n-                echo \"$msg\" | sed -e '\n-\t\t\ts/^[^ ]* /Revert \"/\n-\t\t\ts/$/\"/'\n-                echo\n-                echo \"This reverts $commit commit.\"\n-                test \"$rev\" = \"$commit\" ||\n-                echo \"(original 'git revert' arguments: $@)\"\n-        } | git commit -F -\n-else\n-        # Now why did it fail?\n-        parents=`git-cat-file commit \"$commit\" 2>/dev/null |\n-                sed -ne '/^$/q;/^parent /p' |\n-                wc -l`\n-        case $parents in\n-        0) die \"Cannot revert the root commit nor non commit-ish.\" ;;\n-        1) die \"The patch does not apply.\" ;;\n-        *) die \"Cannot revert a merge commit.\" ;;\n-        esac\n-fi\n+commit=$(git-rev-parse --verify \"$rev^0\") ||\n+\tdie \"Not a single commit $@\"\n+head=$(git-rev-parse --verify HEAD) ||\n+\tdie \"You do not have a valid HEAD\"\n+prev=$(git-rev-parse --verify \"$commit^1\" 2>/dev/null) ||\n+\tdie \"Cannot revert a root commit\"\n+git-rev-parse --verify \"$commit^2\" >/dev/null 2>&1 &&\n+\tdie \"Cannot revert a multi-parent commit.\"\n+\n+# \"commit\" is an existing commit.  We would want to apply\n+# the difference it introduces since its first parent \"prev\"\n+# on top of the current HEAD.\n+\n+{\n+\tgit-rev-list --pretty=oneline --max-count=1 $commit |\n+\tsed -e '\n+\t\ts/^[^ ]* /Revert \"/\n+\t\ts/$/\"/'\n+\techo\n+\techo \"This reverts $commit commit.\"\n+\ttest \"$rev\" = \"$commit\" ||\n+\techo \"(original 'git revert' arguments: $@)\"\n+} >.revertmsg\n+\n+# This three way merge is an interesting one.  We have come from\n+# $commit to $head, and would want to apply the change between $commit\n+# and $prev to us.\n+git-read-tree -m -u $commit $head $prev &&\n+result=$(git-write-tree 2>/dev/null) || {\n+    echo >&2 \"Simple revert fails; trying automated revert.\"\n+    git-merge-cache -o git-merge-one-file-script -a || {\n+\t    echo >&2 \"Automated revert failed.  After fixing it up,\"\n+\t    echo >&2 \"you can use \\\"git commit -F .revertmsg\\\"\"\n+\t    exit 1\n+    }\n+    result=$(git-write-tree) || exit\n+}\n+\n+git commit -F .revertmsg\n+rm -f .revertmsg\n+\n"}]}