18.10 Diff Mode
Diff mode is a major mode used for the output of M-x diff
and
other similar commands. This kind of output is called a patch,
because it can be passed to the patch
command to
automatically apply the specified changes. To select Diff mode
manually, type M-x diff-mode
.
The changes specified in a patch are grouped into hunks, which are contiguous chunks of text that contain one or more changed lines. Hunks usually also include unchanged lines to provide context for the changes. Each hunk is preceded by a hunk header, which specifies the old and new line numbers where the hunk’s changes occur. Diff mode highlights each hunk header, to distinguish it from the actual contents of the hunk.
The first hunk in a patch is preceded by a file header, which shows the names of the new and the old versions of the file, and their time stamps. If a patch shows changes for more than one file, each file has such a header before the first hunk of that file’s changes.
You can edit a Diff mode buffer like any other buffer. (If it is
read-only, you need to make it writable first; see Miscellaneous Buffer Operations.)
Whenever you edit a hunk, Diff mode attempts to automatically correct
the line numbers in the hunk headers, to ensure that the patch remains
correct, and could still be applied by patch
. To disable
automatic line number correction, change the variable
diff-update-on-the-fly
to nil
.
Diff mode arranges for hunks to be treated as compiler error
messages by M-g M-n
and other commands that handle error messages
(see Compilation Mode). Thus, you can use the compilation-mode
commands to visit the corresponding source locations.
In addition, Diff mode provides the following commands to navigate, manipulate and apply parts of patches:
M-n
¶
Move to the next hunk-start ( diff-hunk-next
). With prefix
argument n, move forward to the nth next hunk.
By default, Diff mode refines hunks as Emacs displays them,
highlighting their changes with better granularity. Alternatively, if
you set diff-refine
to the symbol navigation
, Diff mode
only refines the hunk you move to with this command or with
diff-hunk-prev
.
M-p
¶
Move to the previous hunk-start ( diff-hunk-prev
). With prefix
argument n, move back to the nth previous hunk. Like
M-n
, this command refines the hunk you move to if you set
diff-refine
to the symbol navigation
.
M-}
¶
Move to the next file-start, in a multi-file patch
( diff-file-next
). With prefix argument n, move forward
to the start of the nth next file.
M-{
¶
Move to the previous file-start, in a multi-file patch
( diff-file-prev
). With prefix argument n, move back to
the start of the nth previous file.
M-k
¶
Kill the hunk at point ( diff-hunk-kill
).
M-K
¶
In a multi-file patch, kill the current file part.
( diff-file-kill
).
C-c C-a
¶
Apply this hunk to its target file ( diff-apply-hunk
). With a
prefix argument of C-u
, revert this hunk, i.e. apply the
reverse of the hunk, which changes the “new” version into the “old”
version. If diff-jump-to-old-file
is non- nil
, apply the
hunk to the “old” version of the file instead.
C-c C-b
¶
Highlight the changes of the hunk at point with a finer granularity
( diff-refine-hunk
). This allows you to see exactly which parts
of each changed line were actually changed.
By default, Diff mode refines hunks as Emacs displays them, so you may
find this command useful if you customize diff-refine
to a
non-default value.
C-c C-c
¶
Go to the source file and line corresponding to this hunk
( diff-goto-source
). By default, this jumps to the “new”
version of the file, the one shown first on the file header.
With a prefix argument, jump to the “old” version instead. If
diff-jump-to-old-file
is non- nil
, this command by
default jumps to the “old” file, and the meaning of the prefix
argument is reversed. If the prefix argument is a number greater than
8 (e.g., if you type C-u C-u C-c C-c
), then this command also
sets diff-jump-to-old-file
for the next invocation.
If the source file is under version control (see Version Control),
this jumps to the work file by default. With a prefix argument, jump
to the “old” revision of the file (see Examining And Comparing Old Revisions), when
point is on the old line, or otherwise jump to the “new” revision.
C-c C-e
¶
Start an Ediff session with the patch ( diff-ediff-patch
).
See Ediff in The Ediff Manual.
C-c C-n
¶
Restrict the view to the current hunk ( diff-restrict-view
).
See Narrowing. With a prefix argument, restrict the
view to the current file of a multiple-file patch. To widen again,
use C-x n w
( widen
).
C-c C-r
¶
Reverse the direction of comparison for the entire buffer
( diff-reverse-direction
). With a prefix argument, reverse the
direction only inside the current region (see The Mark and the Region). Reversing
the direction means changing the hunks and the file-start headers to
produce a patch that would change the “new” version into the “old”
one.
C-c C-s
¶
Split the hunk at point ( diff-split-hunk
) into two separate
hunks. This inserts a hunk header and modifies the header of the
current hunk. This command is useful for manually editing patches,
and only works with the unified diff format produced by the
-u
or --unified
options to the diff
program. If you need to split a hunk in the context diff format
produced by the -c
or --context
options to
diff
, first convert the buffer to the unified diff format
with C-c C-u
.
C-c C-d
¶
Convert the entire buffer to the context diff format
( diff-unified->context
). With a prefix argument, convert only
the hunks within the region.
C-c C-u
¶
Convert the entire buffer to unified diff format
( diff-context->unified
). With a prefix argument, convert
unified format to context format. When the mark is active, convert
only the hunks within the region.
C-c C-l
¶
Re-generate the current hunk ( diff-refresh-hunk
).
C-c C-w
¶
Re-generate the current hunk, disregarding changes in whitespace
( diff-ignore-whitespace-hunk
).
C-x 4 A
¶
Generate a ChangeLog entry, like C-x 4 a
does (see Change Logs), for each one of the hunks
( diff-add-change-log-entries-other-window
). This creates a
skeleton of the log of changes that you can later fill with the actual
descriptions of the changes. C-x 4 a
itself in Diff mode
operates on behalf of the current hunk’s file, but gets the function
name from the patch itself. This is useful for making log entries for
functions that are deleted by the patch.
Patches sometimes include trailing whitespace on modified lines, as
an unintentional and undesired change. There are two ways to deal
with this problem. Firstly, if you enable Whitespace mode in a Diff
buffer (see Useless Whitespace), it automatically highlights
trailing whitespace in modified lines. Secondly, you can use the
command M-x diff-delete-trailing-whitespace
, which searches for
trailing whitespace in the lines modified by the patch, and removes
that whitespace in both the patch and the patched source file(s).
This command does not save the modifications that it makes, so you can
decide whether to save the changes (the list of modified files is
displayed in the echo area). With a prefix argument, it tries to
modify the original (“old”) source files rather than the patched
(“new”) source files.
If diff-font-lock-syntax
is non- nil
, fragments of
source in hunks are highlighted according to the appropriate major
mode.