Diff, Patch, and Friends
Near the beginning of this article, I promised to explain this line:
that describes the chunk that diff found differences in. In each file, the chunk starts on line 1 and extends for 9 lines beyond the first line. However, with this small example, the chunk shown in the example contains the whole file. With larger files, only the lines around the changes, called the context, are shown.
In files 9 and 10, I've inserted a lot of blank lines in the middle of the paragraph, in order to show what multiple chunks look like. File 9 is damaged, file 10 is correct (except for the blank lines in the middle of the paragraph):
<h3>diff -u 9 10</h3> --- 9 Mon Apr 22 15:46:37 1996 +++ 10 Mon Apr 22 15:46:14 1996 -1,7 +1,7 Ecce Eduardus Ursus scalis nunc tump-tump-tump occipite gradus pulsante post Christophorum Robinum descendens. Est quod sciat unus et solus -modus gradibus desendendi, non nunquam autem +modus gradibus descendendi, nonnunquam autem -33,7 +33,7 sentit, etiam alterum modum exstare, dummodo -pulsationibus desinere et de no modo meditari +pulsationibus desinere et de eo modo meditari possit. Deinde censet alios modos non esse. En, nunc ipse in imo est, vobis ostentari paratus. Winnie ille Pu.
So you see that we have one seven-line chunk starting at line 1 and one seven-line chunk starting at line 33 are shown here.
You should notice several things here:
There is one header at the top of each chunk.
Blank lines are included as part of a chunk's context.
Lines that are not changed and that are not within three lines of a changed line are not included in any chunk.
“Patches” (or “diffs”) are the output of the diff program. They include all the chunks of changes between the two files.
This only brushes the surface of diff. For one thing, the three lines of unchanged context is configurable. Instead of using the -u option, you can use the -U lines option to specify any reasonable number of lines of context. You can even specify -U 0 if you don't want to use any context at all, though that is rarely useful.
What does the -u (or -U lines) argument mean? It specifies the unified diff format, which is the particular format covered here. Other formats include:
“context diffs” which have the same information as unified diffs, but are less compact and less readable
“ed script diffs” or “normal diffs” which are in a format that can be easily converted into a form that can be used to cause the (nearly obsolete) editor ed to automatically change another copy of the old file to match the new file. This format has no context and could easily be replaced by -U 0, except for compatibility with older software and the POSIX standard.
You will almost never want to create context or normal diffs, but it may be useful to recognize them from time to time. Context diffs are marked by the use of the character ! to mark changes, and normal diffs are marked by the use of the characters < and > to mark changes.
Here are examples:
diff -c 1 2 *** 1 Sat Apr 20 22:11:53 1996 --- 2 Sat Apr 20 22:12:01 1996 *************** *** 1,9 **** Ecce Eduardus Ursus scalis nunc tump-tump-tump occipite gradus pulsante post Christophorum Robinum descendens. Est quod sciat unus et solus ! modus gradibus desendendi, non nunquam autem sentit, etiam alterum modum exstare, dummodo ! pulsationibus desinere et de no modo meditari possit. Deinde censet alios modos non esse. En, nunc ipse in imo est, vobis ostentari paratus. Winnie ille Pu. --- 1,9 ---- Ecce Eduardus Ursus scalis nunc tump-tump-tump occipite gradus pulsante post Christophorum Robinum descendens. Est quod sciat unus et solus ! modus gradibus descendendi, nonnunquam autem sentit, etiam alterum modum exstare, dummodo ! pulsationibus desinere et de eo modo meditari possit. Deinde censet alios modos non esse. En, nunc ipse in imo est, vobis ostentari paratus. Winnie ille Pu. diff 1 2 4c4 < modus gradibus desendendi, non nunquam autem --- > modus gradibus descendendi, nonnunquam autem 6c6 < pulsationibus desinere et de no modo meditari --- < pulsationibus desinere et de eo modo meditari
There are a few other important things to note here:
In context diffs, the * character is used in place of the unified diff's - character, and the - character is used in place of the + character. The context diff format was designed before the unified diff format, but the unified diff format's choice of characters is mnemonic and therefore preferable.
Context diffs repeat all context twice for each chunk. This is a waste of space in files, but far more importantly, it separates the changes too widely, making patches less human-readable.
Normal, old-style diffs are very contracted and use very little space. They are useful in situations where you don't normally expect a human to read them, where saving space makes a lot of sense, and where they will never be applied to files which have changed. For example, RCS (covered in the May 1996 issue of LJ) uses a format almost identical to old-style diffs to store changes between versions of files. This saves space and time in a situation where any context at all would be a waste of space.
Pick up any e-commerce web or mobile app today, and you’ll be holding a mashup of interconnected applications and services from a variety of different providers. For instance, when you connect to Amazon’s e-commerce app, cookies, tags and pixels that are monitored by solutions like Exact Target, BazaarVoice, Bing, Shopzilla, Liveramp and Google Tag Manager track every action you take. You’re presented with special offers and coupons based on your viewing and buying patterns. If you find something you want for your birthday, a third party manages your wish list, which you can share through multiple social- media outlets or email to a friend. When you select something to buy, you find yourself presented with similar items as kind suggestions. And when you finally check out, you’re offered the ability to pay with promo codes, gifts cards, PayPal or a variety of credit cards.Get the Guide