4

With viewing a diff for a modified working copy, is there a way to revert the hunk under the cursor?

That is, reverse the change shown in the diff, making the changes to source-file the diff refers to.

Ideally it would refresh the diff too, although I could handle that myself.


Currently I'm navigating to the hunk using diff-goto-source, then using git-gutter:revert-hunk from the git-gutter package, however I would like to perform this inside the diff.

6

If you C-cC-a (diff-apply-hunk) on a hunk which has already been applied, diff-mode will detect this and ask whether you wish to reverse that change.

You can also request this directly by passing a prefix argument to the command.

In cases where the context is insufficient to tell whether or not the patch has been applied, the latter method would be necessary.

| improve this answer | |
  • Thanks for the hint, found there is an argument to reverse (diff-apply-hunk t), (this could be used to update the answer) – ideasman42 Dec 20 '19 at 7:44
4

There are R in diff-mode.

R runs the command diff-reverse-direction

Reverse the direction of the diffs.

So first R and then C-c C-a to apply reversed diff.

It is possible to revert individual hunk without reversing whole diff by invoking diff-aply-hunk with prefix argument. So another solution is C-u C-c C-a.

| improve this answer | |
  • While this is good to know, I'd like to be able to remove the hunk in a single step (view-diff, navigate to hunk, revert it). – ideasman42 Dec 20 '19 at 11:12
  • TIL C-u C-c C-a. Updated the answer. – muffinmad Dec 20 '19 at 11:55
1

Adding own answer, since diff-apply-hunk didn't do exactly what I wanted.

This is a stripped down diff-apply-hunk with some modified behavior, to revert hunks without changing the context.

  • The buffer is saved after reverting.
  • The hunk is removed.
  • No new windows open.

It allows for quickly navigating over a diff and reverting hunks, without having to switch buffers and save each time.

(defun diff-apply-hunk-reverse-and-save (&optional _arg)
  "Revert the current hunk, removing it from the diff, saving the buffer immediately."
  (interactive "P")
  (diff-beginning-of-hunk t)
  (pcase-let
    (
      (`(,buf ,line-offset ,pos ,_old ,new ,switched)
        (diff-find-source-location nil t))) ;; last arg is 't for always reversed.
    (cond
      ((null line-offset)
        (error "Can't find the text to patch"))
      (switched
        (error "Patch is already removed"))
      (t ;; Apply the hunk
        (with-current-buffer buf
          (goto-char (car pos))
          (delete-region (car pos) (cdr pos))
          (insert (car new))
          (save-buffer))
        (diff-hunk-kill)))))
| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.