Is there a way to apply a single hunk from a diff to a file? For example, say I do a diff from file A and B, and that produces three chunks of differences, each denoted with something like...
## -971,30 +977,28 ##
...(in the case of unified diffs). I'd then want to be able to feed that diff into stdin, and ask patch to only apply hunk N.
The manual method would be to cut-and-paste the interesting hunks, but I'm not after that kind of a solution.
filterdiff might help.
It allows extraction of subset of patches matching a variety of requirements, from one/many patch files. For example, here we extract from the file unified_diff.patch, the patches applicable to files with name matching one_file.c, only to lines 950 to 1050 of the original file:
filterdiff -i *one_file.c --lines=950,1050 unified_diff.patch
To extract specific/range of hunks:
filterdiff --hunks=1,3,5-8,15 file.patch
Extracting patches from mail messages:
filterdiff message-with-diff-in-the-body > file.patch
etc.
Some of the GUI diff/patch tools have a way to select blocks or even individual lines. I know TortoiseDiff from TortoiseSVN can work this way. I think I've seen windiff do it, but it's been a while since I had to use it.
As far as command line tools, I have not seen anything that will do what you are asking.
Emacs can not only edit diffs intelligently (including the ever-useful split-hunk operation), but can apply them one hunk at a time itself (avoiding the need to switch from the editor to run patch).
Related
I want to make diff between two files which contains lines beginning with "line_$NR". I want to make diff between the files making abstraction of the presence of "lines_$NR" but when the differences are printed I want lines_$NR to be displayed.
It is possible to do that?
Thanks.
I believe in this case, you have to preprocess your iput files to remove /^line_[0-9]*/, diff the resulting files, then recombine the diff output with the removed words according to line numbers in diff output.
Python's difflib should be very handy here, or same from perl. If you want to stick to shell, I suppose you could get by with awk.
If you don't need exact output, perhaps you can use diff's --line-format=... directive to inject actual line number in a diff, rather than the word you removed in preprocessing step.
This StackOverflow answer has an image of KDiff3 highlighting intra-line differences. Does someone know of a tool which can show the same (ex, via color) on the command line?
Another way to think of this is wanting to diff each difference in a patch file.
I don't know if this is sufficiently command line for your purpose, but vimdiff can do this (even does colour). See for example the image in this related question.
I tried all the tools I found: wdiff, dwdiff, kdiff3, vimdiff to show the difference between two long and slightly different lines. My favourite is diff-highlight (part of git contrib)
it supports diff format - great advantage over tools requiring two files like (dwdiff), e.g. if you need to visualize the output of unit tests
it highlights with black+white or with color if you connect it to colordiff
highlights characterwise - helpful for comparing long lines without spaces (better than wdiff)
Installation
On Ubuntu, you probably already have it as part of git contrib (installed within the git deb package).
Copy or link it into your ~/bin folder from /usr/share/doc/git/contrib/diff-highlight/diff-highlight
Usage example
cat tmp.diff | diff-highlight | colordiff
Result:
Another intuitive way to see all word-sized differences (though not side-by-side) is to use wdiff together with colordiff (you might need to install both). An example of this would be:
wdiff -n {file-A} {file-A} | colordiff
You can optionally pipe this into less -R to scroll through the output (-R is used to show the colors in less).
I had a similar problem and wanted to avoid using vimdiff. I found dwdiff (which is available in Debian) to have several advantages over wdiff.
The most useful feature of dwdiff is that you can customise the delimiters with -d [CHARS], so it's useful for comparing all kinds of output. It also has color built in with the -c flag.
You might be able to use colordiff for this.
In their man page:
Any options passed to colordiff are
passed through to diff except for the
colordiff-specific option 'difftype',
e.g.
colordiff --difftype=debdiff file1
file2
Valid values for 'difftype' are: diff,
diffc, diffu, diffy, wdiff, debdiff;
these correspond to plain diffs,
context diffs, unified diffs,
side-by-side diffs, wdiff output and
debdiff output respectively. Use these
overrides when colordiff is not able
to determine the diff-type
automatically.
I haven't tested it, but the side-by-side output (as produced by diff -y file1 file2) might give you the equivalent of in-line differences.
ccdiff is a convenient dedicated tool for the task. Here is what an example may look like with it:
By default, it highlights the differences in color, but it can be used on a console without color support too.
The package is included in the main repository of Debian:
ccdiff is a colored diff that also colors inside changed lines.
All command-line tools that show the difference between two files fall short in showing minor changes visuably useful. ccdiff tries to give the look and feel of diff --color or colordiff, but extending the display of colored output from colored deleted and added lines to colors for deleted and addedd characters within the changed lines.
Normally, 'diff' tool finds only changes between lines. For example, if i compare 'abcdef' and 'AbcdEf', diff will show that 'abcde' is changed and 'f' is unchanged. Is it possible to find multiple changes per line, so in example above i will see that it's only 'a' changed to 'A' and 'e' changed to 'E'? Or diff outut format does not support such?
There are multiple diff tools that will do what you're asking for.
Off the top of my head I know Winmerge and TortoiseMerge does that.
I recommend KDiff3 which highlights with different colours changes on the same line.
I wrote a tool to diff web code regardless of differences from comments and whitespace. This means my tool can diff a completely minified file against a similar beautified file. It is written entirely in JavaScript so you try it directly in your browser without downloading or installing anything. This does highlight differences per line and highlights differences per characters on those lines.
http://prettydiff.com/
I tried running 'diff' against two source directories get a patch file with a 'diff' between the two directories.
diff -rupN flyingsaucer-R8pre2_b/ flyingsaucer-R8pre2/ > a.patch
The command above does not seem to work, it generates a diff of everything and I get a 13 MB file, when in reality, it should be a couple of changes.
Should work with any recent version of gnu diff (tested here with gnu diff 2.8.1.)
You might want to add -b (and perhaps -B) to ignore difference in white space which perhaps generate large patch files unnecessarily.
I don't see any reason why it wouldn't work. Try adding "wb" to the argument list to ignore whitespace changes. Are you sure you got the trailing slashes the same on both sides?
I have something like this
src/sim/simulate.cc
41d40
< #include "mem/mem-interface.h"
90,91d88
< dram_print_stats_common(curTick/500);
<
src/mem/physical.hh
52d51
< public:
55,56d53
< public:
<
58a56,57
> public:
>
61,62c60,61
< virtual bool recvTiming(PacketPtr pkt); //baoyg
<
---
I believe this was created using the diff command in a source tree. What I want is to create the patch using that output, and to apply the same changes to my source tree.
I believe that diff -u oldfile newfile > a.patch is used to create patch files, although some other switched may be thrown in as well (-N?).
Edit: OK, 4 years later and finally going to explain what the switches mean:
-u creates a Unified diff. Unified diffs are the kind of diffs that the patch program expects to get as input. You can also specify a number after the u (min 3, default 3) to increase the number of lines output. This is in case 3 lines isn't unique enough to pinpoint just one spot in the program.
-N treats absent files as being empty, which means it will produce a lot of additional content if one of the files is empty (or see next point).
Also, newfile and oldfile can both be directories instead of single files. You'll likely want the -r argument for this to recurse any subdirectories.
If you want to get the same patch output as SVN or git diff, given two different files or folders:
diff -Naur file1.cpp file2.cpp
What you have there is a non-unified diff. patch can read it, but will be unable to make context matches and is more likely to make mistakes.
That is a (partial) patch file, though it would have been better if they provided you with a unified diff output.
The main issue with that patch is that it doesn't mention which files are being modified, and since there is no context provided, the files must be exact, patch will be unable to allow for minor changes in the file.
Copy the diff in the original post to a patch file named test.patch then run
patch <original file> test.patch
#Sparr and #Arafangion point out that this works best if you have the exact original file used to create the original diff.