Sams Teach Yourself Emacs in 24 Hours |
||||||||||||||||||||||
Hour 14: Finding Differences Between Files |
||||||||||||||||||||||
|
Using the UNIX program diff, you can find the differences between two files that are almost identical. The two files might be
The original file before a change and the changed file.
A file edited by two different persons (for example, two different persons who work together on a project).
A file located on two different machines and edited on both machines. An example of this might be your .emacs file that you might have a copy of both at home and at work.
In the last two examples, both files have a common ancestor, namely the file before it was modified. When this is the case, the program diff3 might make it easier for you to create one file, which is the original file plus the modifications made.
The output from the command-line version of diff is hard to interpret, unless the changes are few or you are really cool at looking at these outputs. Fortunately, Emacs contains an interface to diff, called Ediff, that makes it much easier. Besides making it easier to look at the output from one diff, Emacs also offers functions for merging the files and applying patches. Applying patches is beyond the scope of this book, but if you apply patches often, I urge you to take a look at the info pages for Ediff. Emacs also has the capability to find the differences between the files of two directories. This is especially useful if you have a set of files that you work on in two different places (such as your Lisp files located at work and at home).
Note - Windows doesn't include diff, so you have to install a copy. There is a diff program included with the Cygwin tools on the CD-ROM. Other UNIX tool sets might also include diff, but you should test them to make sure that Emacs understands the output from another version of diff. Regardless of the version of diff you use, you might have to customize the variable diff-command so that Emacs can execute it. (See Hour 10, "The Emacs Help System and Configuration System," for a description of how to customize variables.) |
A number of functions in the Ediff library lets you diff two items.
ediff-buffers--This asks for the name of two buffers and diffs them.
ediff-files--This asks for the name of two files, loads them into Emacs, and diffs them.
ediff-windows-linewise, ediff-windows-wordwise--These ask you to point at two windows and then diff the content of these windows. The -linewise function is faster than the -wordwise, but on the other hand, the -wordwise function generally does a better job, especially with small regions. -linewise compares buffers line-by-line, while -wordwise compares them word-by-word.
ediff-regions-linewise, ediff-regions-wordwise--These ask for the names of two buffers and then diff the region of these. Note that you can have only one region in each buffer, therefore it is not possible to create two regions in the same file for diffing. However, in Hour 15, "Getting an Overview of a File," a method for diffing two parts of the same buffer is shown (technically it is not the same buffer, but it seems so to the user).
Don't let it scare you that there are so many different functions for diffing two files; after all, they are easy to remember, because they are all called ediff- what-you-want-to-diff.
In Figure 14.1, an Ediff session is shown. Emacs has found four differences between the two files. The current difference is number one and is highlighted, which makes it easier to find. The differences reported by the diff program can span more text than is actually the difference, therefore Emacs highlights the part which is actually different. Thus in the upper buffer, the line that is the current difference is green, except for the word redo, which is dark blue, to indicate that this is the actual difference. Likewise the line in the buffer below is yellow, except the word undefined, which is light blue.
Caution - Figure 14.1 includes the window managers border, which you can see at the top of the window. This is merely to show you that the control buffer is located in its own frame. |
If you make the window with the control buffer the active one, you can invoke the command that controls the Ediff session.
Tip - If you press ? in the control buffer, the buffer expands to show the available keybindings in it. This can be seen in Figure 14.2 |
There are several ways with which you can move from diff to diff. The most basic one is by pressing n or p in the control buffer. These move, respectively, to the next or previous diff.
Note - In the following text it is understood that all the commands are invoked in the control buffer. The two buffers showing the difference are modifiable as always, thus if you press a key such as n in this buffer, it is simply inserted into the buffer. |
If you know the number of a difference, you can jump directly to this diff by pressing the number and the letter j. Thus pressing 4j in the control buffer takes you to difference number four.
When you browse one of the difference buffers, you might find a location of special interest. You can synchronize both buffers to the same location by locating the point in the difference region and, in the control buffer, pressing ga or gb depending on whether the buffer where you placed the point is buffer A or buffer B. (The name of the buffer is indicated in the mode line.)
The buffers with the differences are editable like always; therefore, you can also scroll them up and down to see other parts of the buffers without having to advance to another difference. Sometimes you might want to scroll both buffers simultaneously. To do that press v to scroll downward in the buffer, and V to scroll upward. Likewise if the lines are truncated, you can scroll both buffers horizontally at the same time by pressing either < or >.
To quit one of the Ediff commands press q ( q for quit).
Ediff uses the diff program to calculate the differences. The region that is marked as different, but actually isn't different, is the output from diff. Emacs can optionally do extra refinements of the difference, but this costs extra computer power. If you have a slow computer (or it is hard at work), this might not be desirable. By pressing @ in the control buffer, you can turn off this extra refinement; pressing @ again turns it back on.
To avoid spending a lot of time refining huge regions, Emacs contains a variable called ediff-auto-refine-limit, which is a number saying how many characters at most a region must contain for automatic refinement to take place (see Hour 10, "The Emacs Help System and Configuration System," for a description of how to customize variables).
Caution - This option doesn't seem to work in the version of Ediff that is shipped with GNU Emacs version 19. You must have GNU Emacs version 20. |
When automatic refinement has been disabled or was not done due to a huge region, you can press * to force Emacs to do the refinement.
You might run into situations when a large chunk of text has been edited and then moved to a different place. In such cases, these two chunks of text are unlikely to belong to the same difference region, so the refinement feature of Ediff will not be able to tell you what exactly differs inside these chunks. In these situations you can mark the text that should be almost identical in both buffers and press = (the equals sign). This starts a new Ediff session for the subpart of the buffers.
Caution - This feature doesn't work in the version of Ediff that is shipped with GNU Emacs version 19. You must use GNU Emacs version 20. |
You might often want to skip the diffs that contain only differences in the number of white spaces. To do this, press ## (two hash marks). Emacs then simply skips these regions.
Though Ediff has special functions for merging two buffers into one, it is often easier to use Ediff and copy the resulting files into one of the files. This can be done by pressing either a or b. a copies the diff from buffer A to buffer B, while b copies the text the other way.
If you later find that it was wrong to overwrite a given region, you can restore it again by pressing either ra or rb, for restore region in buffer A or in buffer B.
When you have copied a region from one buffer to the other, you might want to recalculate the difference between the two buffers. This can be done by pressing ! (the exclamation point).
Sams Teach Yourself Emacs in 24 Hours |
||||||||||||||||||||||
Hour 14: Finding Differences Between Files |
||||||||||||||||||||||
|
© Copyright Macmillan USA. All rights reserved.