Patch diff linux
>>> Опубликовано: - 10.09.2017 - 405 Просмотров
Original_file where original_file is the filename of the original file and new_file is the filename of the new file (the one containing your edits). The series file is present in the patches/ directory. Diff + patch,: diff patch patch patch Diff Patch diff -Naur file1 file2 > project. Diff [options] orig-file modified-file > patchfile.
As you may have noticed, I omitted explaining what the 3 -'s are for. They indicate the end of the lines that should be replaced and the beginning of the lines that should replace them. They separate the old and the new lines. You will only see these when replacing content (a "c" between the line numbers). If we want to create a patch, we should put the output of diff into a file. Of course, you could do this by copying the output from your console and, after pasting it in your favourite text editor, saving the file, but there is a shorter way.
We can let bash write diff's output to a file for us this way: [rechosen@localhost ~]$ diff originalfile updatedfile > patchfile. Again, replace the filenames with the ones appropiate in your case. You might like to know that telling bash to write a command's output to a file using > works with every command. This can be very useful to save to output of a command to a (log) file. Well then, did we just create a patch? The short answer is: yes, we did.
We can use the patchfile to change a copy of originalfile to a copy of updatedfile. Of course, it wouldn't make that much sense to apply the patch on the files we created the patch from. Therefore, copy the original file and the patchfile to an other place, and go to that place. Then, try applying the patch this way: [rechosen@localhost ~]$ patch originalfile -i patchfile. Again, replace the filenames where necessary.
Личные заметки из области web-разработки, программирования, администрирования, IT
If all went well, the file updatedfile just created by patch should be identical to the one you had at first, when creating the patch with diff. Replace the part between [ and ] with the path to the original update file. For example, if the updatedfile you used when creating the patch is located in the parent directory of your current directory, replace "[/path/to/the/original/updatedfile]" with ". " (bash understands this as the parent directory of the current working directory).
And of course, also replace the filenames again where appropiate. If diff reported the files to be equal, you just succesfully created and used a patch! However, the patch format we just used is not the only one.
In the next chapter, I will explain about an other patch format. In the first chapter, we created a patch using diff's normal format. This format, however, doesn't provide any of the lines of context around the ones to be replaced, and therefore, a change in the line numbers (one or more extra newlines somewhere, or some deleted lines) would make it very difficult for the patch program to determine which lines to change instead. Also, if a different file that is being patched by accident contains the same lines as the original file at the right places, patch will happily apply the patchfile's changes to this file.
This could result in broken code and other unwanted side-effects. Fortunately, diff supports other formats than the normal one. By now, it should be clear that you should replace the filenames where necessary =). You should get an output like this: *** originalfile 2007-02-03 22:15:48.
These are a few words. These still are just a few words.
how to include a new file into a patch
As you can see, the filenames are included. This will save us some typing when applying the patch. The timestamps you can see next to the filenames are the date and time of the last modification of the file. The line with 15 *'s indicates the starting of a hunk.
A hunk describes which changes, like replacements, additions and deletions, should be made to a certain block of text. The two numbers 1 are line numbers (again, these can also be line ranges (12,15 means line 12 to line 15)), and! Means that the line should be replaced. Before the three -'s (hey, where did we see those before? Should be replaced by the second line with a! After the three -'s (of course, the! Itself will not be included; it's context format syntax). As you can see, there aren't any c's, a's and d's here. The action to perform is determined by the character in front of the line.
As explained, means that the line should be replaced. The other available characters are +, - and " " (a space). The + means add (or append), the - means delete, and the " " means nothing: patch will only use it as context to be sure it's modifying the right part of the file. Applying this patch is a bit easier: under the same circumstances as before (let bash write the diff output to a file again, then copy the patchfile and the original file to an other location), you'll need to run: [rechosen@localhost ~]$ patch -i patchfile.
You'll probably think now: why do we still have to specify the new filename?
Сравнение и объединение файловdiff, diff3, sdiff, cmp, patch
Well, that's because patch was made with the intention to update existing files in mind, not to create new updated files. This usually comes in handy when patching source trees of programs, which is pretty much the main use of patch. And that brings us to our next subject: to patch a whole source tree, multiple files should included in the patchfile. The next chapter will tell how to do this. The easiest way to get the differences between multiple files is to put them all in a directory and to let diff compare the whole directories. Note: if the directories you're comparing also include subdirectories, you should add the -r option to make diff compare the files in subdirectories, too.
This is the first updated file. This is the second updated file. This is line has been added to this updated file. Note: for this example, I created some example files. You can download an archive containing these files here:. As you can see, the normal output format only specifies filenames when comparing multiple files. You can also see examples of the addition and deletion of lines. This is the first original file. This is the first updated file. This is the second original file.
how to include a new file into a patch
This is the second updated file. We're going to add something in this file and to delete this line. This is line has been added to this updated file.
Something will be added above this line. The first thing you should notice is increase in length; the context format provides more information than the normal format. This wasn't that visible in the first example, as there wasn't any context to include. However, this time there was context, and that surely lenghtens the patch a lot. You might also have noticed that the filenames are mentioned twice every time. This is probably done either to make it easier for patch to recognize when to start patching the next file, or to provide better backwards-compatibility (or both). The other way to let diff compare multiple files is writing a shell script that runs diff multiple times and correctly adds all output to one file, including the lines with the diff commands.
I will not tell you how to do this as the other way (putting the files in a directory) is a lot easier and is used widely. Creating this patch with diff was considerably easy, but the use of directories kicks in a new problem: will patch just patch the mentioned files in the current working directory and forget about the directory they were in when creating the patch, or will it patch the files inside the directories specified in the patch? Have a look at the next chapter to find out! In the chapter before this one, we created a patch that can be used to patch multiple files.
If you haven't done so already, save diff's output to an actual patchfile in a way like this: [rechosen@localhost ~]$ diff -c originaldirectory/ updateddirectory/ > patchfile. Note: we'll be using the context format patch here as it generally is good practice to use a format that provides context. It's time to try using our patchfile. Copy the original directory and the patchfile to an other location, go to that other location, and apply the patch with this command: [rechosen@localhost ~]$ patch -i patchfile.
It reports that it cannot find the file to patch! It is trying to find the file file1 in the current directory (patch defaultly strips away all directories in front of the filename). Of course, this file isn't there because we're trying to update the file in the directory originaldirectory. For this reason, we should tell patch not to strip away any directories in the filenames. That can be done this way: [rechosen@localhost ~]$ patch -p0 -i patchfile. Note: you might think you could also just move into originaldirectory and run the patch command there.
This is bad practice: if the patchfile includes any files to patch in subdirectories, patch will look for them in the working directory, and, obviously, not find them or find the wrong ones. Use the -p option to make patch look in subdirectories as it should. The -p options tells patch how many slashes (including what's before them, usually directories) it should strip away before the filename (note that, when using the option -p0, patch looks for the files to patch in both originaldirectory and updateddirectory, in our case). In this case, we set it to 0 (do not strip away any slash), but you can also set it to 1 (to strip away the first slash including anything before it), or 2 (to strip away the first two slashes including everything before it), or any other amount.
This can be very useful if you've got a patch which uses a different directory structure than you.
Как использовать патчи, созданные в Windows (с CRLF) в linux I
For example: if you'd have a patch that uses a directory structure like this: (. Home/username/sources/program/originaldirectory/file1 2007-02-04 16:17:57. Home/username/sources/program/updateddirectory/file1 2007-02-04 16:18:33. You could just count the slashes (/ (1) home/ (2) username/ (3) sources/ (4) program/ (5)) and give that value with the -p option. If you're using -p5, patch would look for both originaldirectory/file1 and updateddirectory/file1. Please do note that patch considers two slashes next to each other (like in /home/username//sources) as a single slash.
This is because scripts sometimes (accidently or not) put an extra slash between directories. Sometimes a patch is applied while it shouldn't have been. For example: a patch introduces a new bug in some code, and a fixed patch is released. However, you already applied the old, buggy patch, and you can't think of a quick way to get the original files again (maybe they were already patched dozens of times). You can then apply the buggy patch in a reversive way.
The patch command will try to undo all changes it did by swapping the hunks. You can tell patch to try reversing by passing it the -R option: [rechosen@localhost ~]$ patch -p0 -R -i patchfile. Usually, this operation will succeed, and you'll get back the original files you had.
By the way, there is another reason why you'd want to reverse a patch: sometimes (especially when sleepy), people release a patch with the files swapped. You've got a big chance that patch will detect this automatically and ask you if you want it to try patching reversively. Sometimes, however, patch will not detect it and wonder why the files don't seem to match. You can then try applying the patch in a reversed way manually, by passing the -R option to patch.