• This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn more.

Diff, Patch, and Friends: chapter #1

fergy

Member +
Joined
Jan 11, 2007
Messages
170
Likes
3
#1
Diff, Patch, and Friends: chapter #1-#3

Diff is designed to show you the differences between files, line by line. It is fundamentally simple to use, but takes a little practice. Don't let the length of this text scare you.
While diff is often used by developers to show differences between different versions of a file of source code, it is useful for far more than source code. For example, diff comes in handy when editing a document which is passed back and forth between multiple people, perhaps via e-mail. The changes can be found by looking at the differences between two files.
However, it is hard to show off how helpful diff can be in finding these kinds of differences.

I will make You an example on si.cpp ( from /apps/tuxbox/enigma/lib ) what is used to manage an fast pmt file in Your /tmp directory on Dreambox, what is used to manage Emulator ( so You can use any emu with CVS image ) :

So, open si.cpp with text editor and find this line:
Code:
 int PMT::data(__u8 *data)
 {
after that, copy and paste this:

Code:
// pmt.tmp addon START ----------------------------
	FILE *fout;
	fout=fopen("/var/tmp/pmt.TMP","wt");
	fwrite(data,((data[1]&0xf)<<8)+data[2]+3,1,fout);
	fclose(fout);
// pmt.tmp addon END ------------------------------
But look that after that You see this three lines:
Code:
 	pmt_struct *pmt=(pmt_struct*)data;
 	version_number=pmt->version_number;
 	program_number=HILO(pmt->program_number);
Save file and close Your text editor.
Congratulations, You have Your first patch and You can insert any emu in the image!!!

Well, that is example what patch do, and You are make a patch by hand. In this situation, that is a piece of cake because We have only 6 lines to insert between two lines . Imagine situation when You must insert 100's of lines in 40 locations !!!! : shocked2
Impossible mission.
So, in chapter #2, We will learn how to use diff with a patch command to insert it in original file.
Stay tuned. : multi :
 
Last edited:

fergy

Member +
Joined
Jan 11, 2007
Messages
170
Likes
3
#2
Diff, Patch, and Friends: chapter #2

OK, after chapter #1 when We are learning what is diff and how to manually patch original file, in this chapter I will try to explain how to make diff and how to automate process of chapter #1. :)

Let take as example code from chapter #1:

diff is:

Code:
// pmt.tmp addon START ----------------------------
	FILE *fout;
	fout=fopen("/var/tmp/pmt.TMP","wt");
	fwrite(data,((data[1]&0xf)<<8)+data[2]+3,1,fout);
	fclose(fout);
// pmt.tmp addon END ------------------------------
so, question is: how to make diff file????

Remember this code. It will be used latter in lesson.

Okay, let's clear out one thing: to be able to make diff, first of all You must have it. So let's start with making useful diff.

Open terminal and execute command:

Code:
diff -u path_to_first_file ( ex: /home/Lalala/Documents/fileA.cpp ) path_to_second_file ( ex: /home/Lalala/apps/tuxbox/enigma/lib/fileB.cpp
and hit Enter

You will get differences between fileA and file B.

Example: I was use file cahandler.cpp from sample image and cahandler.cpp from CVS image on two different locations:
first file is in: /home/Fergy/Desktop/sample/enigma_sample/lib/dvb and second one is in: /home/Fergy/tuxbox-dev/dm7000/apps/tuxbox/enigma/lib/dvb
So, I was cd to the location where is stored folder with sample's cahandler.cpp and execute command:
Code:
diff -u cahandler.cpp /home/Fergy/tuxbox-dev/dm7000/apps/tuxbox/enigma/lib/dvb/cahandler.cpp
hit Enter and voila:
Code:
--- cahandler.cpp      :20:42.000000000 +0100
+++ /home/Fergy/tuxbox-dev/dm7000/apps/tuxbox/enigma/lib/dvb/cahandler.cpp    :59:16.000000000 +0100
@@ -1,15 +1,30 @@
-#include <lib/dvb/cahandler.h>
 #include <unistd.h>
+#include <string.h>
+
+#include <lib/dvb/cahandler.h>
 #include <lib/base/eerror.h>
 #include <lib/system/init.h>
 #include <lib/system/init_num.h>
 #include <lib/system/info.h>
-#include <lib/gdi/font.h>
+
+ePMTClient::ePMTClient(eDVBCAHandler *handler, int socket)
+ : eUnixDomainSocket(socket, 1, eApp), parent(handler)
+{
+       CONNECT(connectionClosed_, ePMTClient::connectionLost);
+}
+
+void ePMTClient::connectionLost()
+{
+       if (parent) parent->connectionLost(this);
+}

 eDVBCAHandler::eDVBCAHandler()
+ : eServerSocket(PMT_SERVER_SOCKET, eApp), serviceLeft(eApp)
 {
        services.setAutoDelete(true);
+       clients.setAutoDelete(true);
        CONNECT( eDVB::getInstance()->leaveTransponder, eDVBCAHandler::leaveTransponder );
+       CONNECT(serviceLeft.timeout, eDVBCAHandler::serviceGone);
        eDVBCaPMTClientHandler::registerCaPMTClient(this);  // static method...
 }
Note that this is not whole code!!!
Anyway, You see that + and - sign's at the beginning of lines?
Sure, the patch contains lines preceded with minus mark (-) , this means that you have to delete that line from the original file
also other lines preceded with plus mark (+) , this means that you need to add then to the original file.
So to make a diff file, execute this command:
Code:
diff -u --recursive --new-file /path_to_the_first_file /path_to_the_second_file > /path_to_anywhere/patch.txt
and You will have Your first patch ( diff ) file at: /path_to_anywhere location with name: patch.txt

This is all for this lesson. In next lesson, We will learn how to use patch command to automate process of patching ( modiffying original file )

Stay tuned. : multi :
 
Last edited:

fergy

Member +
Joined
Jan 11, 2007
Messages
170
Likes
3
#3
Diff, Patch, and Friends: chapter #3

So, in chaptre #2 We was get our first patch.txt, and now We will learn how to automate patching process.

Command what We will use is:

Code:
patch
Let Me say few words about this command:
The patch command reads a source file's instructions on how to change a file, then applies the changes. The source file contains difference listings (or diff listings) produced by the diff command. By default, the patch command uses the source file read from standard input, but this can be overridden using the -i flag and the PatchFile variable.
The patch file must contain one or more lines of header information followed by one or more patches. Each patch must contain one or more lines of file name identification in the format produced by the diff -c command, and one or more sets of diff command output, customarily called hunks.
The patch command skips any leading text in a patch file, applies the actual diff listing, and skips any trailing text. Thus, you could use as a patch file an article or message that includes a diff listing, and the patch command would still work. In such a case, if the entire diff listing is indented by a consistent amount, the patch command will also adjust for that spacing.
To change a line range within the original file, each hunk within a patch must be a separate diff listing. The line numbers for successive hunks within a patch must occur in ascending order.

If no File parameter is specified, the patch command performs the following steps to obtain the name of the file to edit:

1. In the header of a context diff listing, the file name is determined from lines beginning with *** (three asterisks) or --- (three dashes). A line beginning with *** indicates the name of the file from which the patches were taken, while a line beginning with --- indicates the name of the file to which the patches should be applied. The shortest name of an existing file is selected.
2. If there is an Index: line in the leading text, the patch command tries to use the file name from that line.
3. A context diff header takes precedence over an Index: line.
4. If no file name can be determined from the leading text, the patch command prompts you for the name of the file to patch.
5. If the original file cannot be found, but a suitable SCCS or RCS file is available, the patch command attempts to get or check out the file.
6. If the leading text contains a Prereq: line, the patch command takes the first word from the prerequisites line (normally a version number) and checks the input file to see if that word can be found. If not, the patch command prompts you for confirmation before proceeding.

Flags

-b Saves a copy of each modified file before the differences are applied. The copied original is filed with the same name and the suffix .orig. If a file by that name already exists, it is overwritten. If multiple patches are applied to the same file, only one copy is made of the original file at the time of the first patch. If the -o OutFile flag is also specified, the .orig file is not created. But if the specified out file already exists, OutFile.orig is created.
-B Prefix Specifies a prefix to the backup file name. This flag only works in conjunction with the -b flag.
-c Interprets the patch file as a context diff listing (the output of the diff -c or diff -C command). This flag cannot be used with the -e or -n flag.
-d Directory Changes the current directory to the specified directory before processing.
-D Define Marks changes with the following C preprocessor construct:

#ifdef Define
... (NEWCODE)
#else
... (OLDCODE)
#endif /* Define */

The Define variable is used as the differentiating symbol. This flag only works when the normal or context form of diff listing is used as a patch file.
-e Interprets the patch file as an ed editor script. This flag cannot be used with the -c or -n flag.
-f Suppresses queries to the user. To suppress commentary, use the -s flag.
-F Number Sets the maximum fuzz factor. This flag applies to context diff listings only and causes the patch command to ignore the specified number of lines when determining where to install a hunk. If the -F flag is not specified, the default fuzz factor is 2. The factor may not be set to more than the number of lines of content in the context diff listing (ordinarily 3).

Note: A larger fuzz factor increases the odds of a faulty patch.

-i PatchFile Reads the patch information from the specified file, rather than from standard input.
-l (lowercase L) Causes any sequence of blank characters in the diff listing script to match any sequence of blank characters in the input file. Other characters are matched exactly.
-n Interprets the script as a normal diff listing. This flag cannot be used with the -c or -e flag.
-N Ignores patches where the differences have already been applied to the file. By default, already-applied patches are rejected.
-o OutFile Copies the files to be patched, applies the changes, then writes the modified version to the specified output file. Multiple patches for a single file are applied to the intermediate versions of the file created by any previous patches. Therefore, multiple patches result in multiple, concatenated versions of the output file.
-p Number Sets the path name strip count, which controls how path names found in the patch file are treated. This flag is useful if you keep your files in a directory different from the specified path. The strip count specifies how many slashes are stripped from the front of the path name. Any intervening directory names are also stripped. For example, assume a patch file specified /u/leon/src/blurf1/blurf1.c:

* -p 0 leaves the entire path name unmodified.
* -p 1 removes the leading slash, leaving u/leon/src/blurf1/blurf1.c.
* -p 4 removes four slashes and three directories, leaving blurf1/blurf1.c.

If the -p flag is not specified, only the base name (the final path name component) is used. This flag works only when the File parameter is not specified.
-r RejectFile Overrides the default reject file name. The default reject file name is formed by appending the suffix .rej to the original file name.
-R Reverses the sense of the patch script. For example, if the diff listing was created from new version to old version, using the -R flag causes the patch command to reverse each portion of the script before applying it. Rejected differences are saved in swapped format. The -R flag cannot be used with ed scripts, because there is too little information to reconstruct the reverse operation. If the -R flag is not specified, the patch command attempts to apply each portion in its reversed sense as well as in its normal sense, until a portion of the patch file is successfully applied. If the attempt is successful, the user is prompted to determine if the -R flag should be set.

Note: This method cannot detect a reversed patch if used with a normal diff listing where the first command is an append (that is, would have been a delete). Appends always succeed because a null context matches anywhere. Fortunately, most patches add or change lines rather than delete lines. Therefore most reversed normal diff listings begin with a delete, causing a failure and triggering heuristics.

-s Patches silently unless an error occurs.
-v Prints the revision header and patch level. If the -v flag is used with other flags, the other flags are ignored.
-x Number Sets internal debugging flags. This flag is only for patch command developers.

Exit Status

The following exit values are returned:
0 Successful completion.
1 An error occurred.

Examples

1. To apply diff listings in the difflisting file to the enigma_main.cpp file, enter:

patch -i difflisting enigma_main.cpp

2. To save the original version of the enigma_main.cpp file, enter:

patch -b -i difflisting enigma_main.cpp

This applies changes to enigma_main.cpp and saves the original contents of enigma_main.cpp in the file enigma_main.cpp.orig.
3. To patch the enigma_main.cpp file without altering the original version, enter:

patch -i difflisting -o enigma_main.new enigma_main.cpp

This uses enigma_main.cpp as a source file, but the changed version is written to a file named enigma_main.new.

This is all for this chapter.

Stay tuned. : multi :
 

westkill

DW Member +
Joined
Dec 8, 2005
Messages
1,212
Likes
7
#4
so a patch has to be made when adding anything to the image

then a .diff file is created to use with the patch

depending on what the diff is going to be used for


just trying to understand it lol

so a patch was made for the infobar.diff
using : patch -p1 < infobar.diff

so making another patch it would be
patch -p2 < anything.diff


dont you dare laugh if this is wrong lol
 

osborne82

DW Regular
Joined
Nov 16, 2005
Messages
1,293
Likes
25
#6
as a example lets say you have made a few changes to

enigma.cpp and you would like to share your changes with the world :) you can either just post your modified enigma.cpp file for all to use or you can make a diff so people can use the

patch -p1 < command and aply your changes

to do this you have two files the original enigma.cpp with no chages by u and the enigma.cpp u changed

so you would type

Code:
diff -u enigma.cpp /home/osborne/tuxbox-cvs/apps/tuxbox/enigma/src/enigma.cpp
this would make a diff file for you with your changes u made so you could then post your chages easyly :)


not that a diff isnt need always if theres only one or two edits to make as you may find it easier just to open up the file with a text editor and manual make the edits but if thers many edits to make then its piece of piss to just patch -p1< hehe
cheers
 
Last edited:

ellie1998

DW Member ++
Joined
May 7, 2005
Messages
5,744
Likes
67
#7
as a example lets say you have made a few changes to

enigma.cpp and you would like to share your changes with the world :) you can either just post your modified enigma.cpp file for all to use or you can make a diff so people can use the

patch -p1 < command and aply your changes

to do this you have two files the original enigma.cpp with no chages by u and the enigma.cpp u changed

so you would type

Code:
diff -u enigma.cpp /home/osborne/tuxbox-cvs/apps/tuxbox/enigma/src/enigma.cpp
this would make a diff file for you with your changes u made so you could then post your chages easyly :)


not that a diff isnt need always if theres only one or two edits to make as you may find it easier just to open up the file with a text editor and manual make the edits but if thers many edits to make then its piece of piss to just patch -p1< hehe
cheers
This assumes they have made a copy of the file before it is edited, after a virgin compile I would right click the tuxbox-cvs and select copy
Go to the desktop, right click paste then I would have something to diff against.

I didn't do this in the linux that I posted but I thought it may have been mentioned before any cvs edits.
 

fergy

Member +
Joined
Jan 11, 2007
Messages
170
Likes
3
#8
lol
I was missed this post's. :)
Guys, command is:

Code:
diff -[B]u --recursive --new-file[/B] [COLOR="Yellow"]enigma_main_orig.cpp[/COLOR] [COLOR="Lime"]enigma_main.cpp[/COLOR] > [COLOR="Cyan"]enigma_main.new.txt[/COLOR]
and original command without colors:

Code:
diff -u --recursive --new-file enigma_main_orig.cpp enigma_main.cpp > enigma_main.new.txt
in case that We have both files: enigma_main.cpp and enigma_main_orig.cpp in same folder. Also, diff file ( ready for patching ) enigma_main.new.txt will be in same folder.
Cheers : multi :