Diff, Patch, and Friends
Near the beginning of this article, I promised to explain this line:
-1,9 +1,9
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.
Realizing the promise of Apache® Hadoop® requires the effective deployment of compute, memory, storage and networking to achieve optimal results. With its flexibility and multitude of options, it is easy to over or under provision the server infrastructure, resulting in poor performance and high TCO. Join us for an in depth, technical discussion with industry experts from leading Hadoop and server companies who will provide insights into the key considerations for designing and deploying an optimal Hadoop cluster.
Sponsored by AMD
Built-in forensics, incident response, and security with Red Hat Enterprise Linux 6
Every security policy provides guidance and requirements for ensuring adequate protection of information and data, as well as high-level technical and administrative security requirements for a system in a given environment. Traditionally, providing security for a system focuses on the confidentiality of the information on it. However, protecting the data integrity and system and data availability is just as important. For example, when processing United States intelligence information, there are three attributes that require protection: confidentiality, integrity, and availability.
Learn more about catching the bad guy in this free white paper.
Sponsored by DLT Solutions
Free Webinar: Hadoop
How to Build an Optimal Hadoop Cluster to Store and Maintain Unlimited Amounts of Data Using Microservers
Realizing the promise of Apache® Hadoop® requires the effective deployment of compute, memory, storage and networking to achieve optimal results. With its flexibility and multitude of options, it is easy to over or under provision the server infrastructure, resulting in poor performance and high TCO. Join us for an in depth, technical discussion with industry experts from leading Hadoop and server companies who will provide insights into the key considerations for designing and deploying an optimal Hadoop cluster.
Some of key questions to be discussed are:
- What is the “typical” Hadoop cluster and what should be installed on the different machine types?
- Why should you consider the typical workload patterns when making your hardware decisions?
- Are all microservers created equal for Hadoop deployments?
- How do I plan for expansion if I require more compute, memory, storage or networking?
| Dynamic DNS—an Object Lesson in Problem Solving | May 21, 2013 |
| Using Salt Stack and Vagrant for Drupal Development | May 20, 2013 |
| Making Linux and Android Get Along (It's Not as Hard as It Sounds) | May 16, 2013 |
| Drupal Is a Framework: Why Everyone Needs to Understand This | May 15, 2013 |
| Home, My Backup Data Center | May 13, 2013 |
| Non-Linux FOSS: Seashore | May 10, 2013 |
- Dynamic DNS—an Object Lesson in Problem Solving
- Making Linux and Android Get Along (It's Not as Hard as It Sounds)
- Using Salt Stack and Vagrant for Drupal Development
- New Products
- A Topic for Discussion - Open Source Feature-Richness?
- Drupal Is a Framework: Why Everyone Needs to Understand This
- Validate an E-Mail Address with PHP, the Right Way
- RSS Feeds
- Readers' Choice Awards
- Tech Tip: Really Simple HTTP Server with Python
- BASH script to log IPs on public web server
1 hour 40 min ago - DynDNS
5 hours 16 min ago - Reply to comment | Linux Journal
5 hours 48 min ago - All the articles you talked
8 hours 12 min ago - All the articles you talked
8 hours 15 min ago - All the articles you talked
8 hours 17 min ago - myip
12 hours 41 min ago - Keeping track of IP address
14 hours 32 min ago - Roll your own dynamic dns
19 hours 46 min ago - Please correct the URL for Salt Stack's web site
22 hours 57 min ago




Comments
The first comment asked for
The first comment asked for reasons. Here are a few.
1. Years of fighting with graphical tools can lead one to learn command line tools.
2. A major difference between the two is the former can be used in scripts.
3. Another significant difference is robustness. It's generally much easier to crash a graphical tool than a well-designed command line one.
4. Lastly, command line tools most often contain less code and require less system resources to operate, often making them better suited to work faster and more efficiently than graphical tools.
Smaller, faster and more reliable. Built for automation. A higher learning curve may be a trade off for higher performance.
Why?
Why in the world would I want to fight with command line tools when trying to compare and merge versions? Graphical diff and merge tools have existed for decades.
Now if you can show me a diff and merge tool that understands the syntax of the file being compared and I'll be far more interested. I have seen merge tools eat a brace way too often.
I think the images for figure
I think the images for figures 1 and 2 are broken. When I follow the links to view these figures, the images don't show up in my browser window.
using diff and patch
If I use diff -Naur to generate a patch symbolic links are not respected. e.g. see below;
How can I get patch/diff to respect symbolic links?
>---------------------------------------------------<
$ ll foo*
foo:
total 4
lrwxrwxrwx 1 foo users 5 Jun 9 13:04 link -> stuff
-rw-r--r-- 1 foo users 12 Jun 9 13:04 stuff
foo2:
total 4
lrwxrwxrwx 1 foo users 5 Jun 9 13:04 link -> stuff
-rw-r--r-- 1 foo users 12 Jun 9 13:04 stuff
$ diff -Naur foo foo2 > patch
$ mv foo2 foo2.orig
$ patch -p0 < patch
patching file foo/link
patching file foo/stuff
$ ll foo
total 8
-rw-r--r-- 1 foo users 27 Jun 9 13:08 link
-rw-r--r-- 1 foo users 27 Jun 9 13:08 stuff
>---------------------------------------------------<
Working with directories
This article is missing info on patching multiple files.
See here: http://lists.gnu.org/archive/html/help-gnu-utils/2004-06/msg00024.html for examlpe.
Re: Diff, Patch, and Friends
Nice article! I now link to it from
my "Howto contribute to an open source project" tutorial,
www.kegel.com/academy/opensource.html
Re: Diff, Patch, and Friends
You may want to link to the manpages for the free versions
of diff and patch too, instead of only the GNU versions:
http://mirbsd.bsdadvocacy.org/man1/diff.htm
http://mirbsd.bsdadvocacy.org/man1/patch.htm
To the editor: ed(1) is by no means obsolete; I'm actually
faster with ed than with vi (whose modus operandi is
cruelly to a wordstar-compatible editor user like me).
http://mirbsd.bsdadvocacy.org/man1/ed.htm
You didn't mention diff3 either, did you?