Diff merging files




















The best answers are voted up and rise to the top. Stack Overflow for Teams — Collaborate and share knowledge with a private group. Create a free Team What is Teams? Learn more. Asked 8 years, 11 months ago.

Active 1 year, 9 months ago. Viewed 38k times. I guess its pretty simple, so to show my problem take these two files: a. Improve this question. Rafael T Rafael T 3 3 gold badges 8 8 silver badges 15 15 bronze badges.

So no, they are not particularly suitable for this task. You might want to have a look at wdiff but the solution probably requires a custom script. Why all the answers with custom scripts? Merging is a standard and complex problem, and there are good tools for it. Don't reinvent the wheel. Add a comment. Active Oldest Votes. The first character of output is - for deleted lines, for added lines, and a space for unchanged lines.

The formats contain newline characters where newlines are desired on output. You should quote format , since it often contains shell metacharacters. This format ignores whether the line is incomplete; See Incomplete Lines. If a line is incomplete, this format preserves its incompleteness.

F n where F is a printf conversion specification, stands for the line number formatted with F. See Line Group Formats , for more about printf conversion specifications.

Taken together, the line and line group formats let you specify many different formats. For example, the following command uses a format similar to normal diff format. You can tailor this command to get fine control over diff output. For each hunk of differences in the merged output format, if the hunk contains only lines from the first file, diff uses the old line group format; if the hunk contains only lines from the second file, diff uses the new group format; otherwise, diff uses the changed group format.

The old, new, and unchanged line formats specify the output format of lines from the first file, lines from the second file, and lines common to both files, respectively. If they don't, you must make corrections manually. It is a good idea to carefully check the resulting code anyway to make sure that it really does what you want it to; depending on how the input files were produced, the output might contain duplicate or otherwise incorrect code.

The patch -D name option behaves like the diff -D name option, except it operates on a file and a diff to produce a merged file; See patch Options. All other lines are called full lines and end in a newline character. Incomplete lines do not match full lines unless differences in white space are ignored see White Space. Finally, with the ed and forward ed output formats see Output Formats diff cannot represent an incomplete line, so it pretends there was a newline and reports an error.

For example, suppose F and G are one-byte files that contain just f and g , respectively. Normally diff is silent about pairs of files that contain no differences, but if you use the -s or --report-identical-files option, it reports pairs of identical files. Normally diff reports subdirectories common to both directories without comparing subdirectories' files, but if you use the -r or --recursive option, it compares every corresponding pair of files in the directory trees, as many levels deep as they go.

For file names that are in only one of the directories, diff normally does not show the contents of the file that exists; it reports only that the file exists in that directory and not in the other. You can make diff act as though the file existed but was empty in the other directory, so that it outputs the entire contents of the file that actually exists. It is output as either an insertion or a deletion, depending on whether it is in the first or the second directory given.

To do this, use the -N or --new-file option. If the older directory contains one or more large files that are not in the newer directory, you can make the patch smaller by using the --unidirectional-new-file option instead of -N. This option is like -N except that it only inserts the contents of files that appear in the second directory but not the first that is, files that were added. At the top of the patch, write instructions for the user applying the patch to remove the files that were deleted before applying the patch.

See Making Patches , for more discussion of making patches for distribution. This option ignores any files or subdirectories whose base names match the shell pattern pattern. Unlike in the shell, a period at the start of the base of a file name matches a wildcard at the start of a pattern.

You should enclose pattern in quotes so that the shell does not expand it. This option accumulates if you specify it more than once. If you have been comparing two directories and stopped partway through, later you might want to continue where you left off.

This compares only the file file and all alphabetically later files in the topmost directory level. If two directories differ only in that file names are lower case in one directory and upper case in the upper, diff normally reports many differences because it compares file names in a case sensitive way. With the --ignore-file-name-case option, diff ignores case differences in file names, so that for example the contents of the file Tao in one directory are compared to the contents of the file TAO in the other.

The --no-ignore-file-name-case option cancels the effect of the --ignore-file-name-case option, reverting to the default behavior. These adjustments can be applied to any output format. Tabs : Preserving the alignment of tab stops. Pagination : Page numbering and time-stamping diff output. Node: Tabs , Next: Pagination , Up: Adjusting Output Preserving Tab Stop Alignment The lines of text in some of the diff output formats are preceded by one or two characters that indicate whether the text is inserted, deleted, or changed.

The addition of those characters can cause tabs to move to the next tab stop, throwing off the alignment of columns in the line.

GNU diff provides two ways to make tab-aligned columns line up correctly. The first way is to have diff convert all tabs into the correct number of spaces before outputting them; select this method with the -t or --expand-tabs option.

To use this form of output with patch , you must give patch the -l or --ignore-white-space option see Changed White Space , for more information. The other method for making tabs line up correctly is to add a tab character instead of a space after the indicator character at the beginning of the line. This ensures that all following tab characters are in the same position relative to tab stops that they were in the original files, so that the output is aligned correctly. Its disadvantage is that it can make long lines too long to fit on one line of the screen or the paper.

It also does not work with the unified output format, which does not have a space character after the change type indicator character. Select this method with the -T or --initial-tab option. The -l and --paginate options do this by sending the diff output through the pr program. Here is what the page header might look like for diff -lc lao tzu : diff -lc lao tzu Page 1 Node: diff Performance , Next: Comparing Three Files , Previous: Adjusting Output , Up: Top diff Performance Tradeoffs GNU diff runs quite efficiently; however, in some circumstances you can cause it to run faster or produce a more compact set of changes.

One way to improve diff performance is to use hard or symbolic links to files instead of copies. This improves performance because diff normally does not need to read two hard or symbolic links to the same file, since their contents must be identical.

For example, suppose you copy a large directory hierarchy, make a few changes to the copy, and then often use diff -r to compare the original to the copy.

If the original files are read-only, you can greatly improve performance by creating the copy using hard or symbolic links e. Before editing a file in the copy for the first time, you should break the link and replace it with a regular copy. You can also affect the performance of GNU diff by giving it options that change the way it compares files. Performance has more than one dimension. These options improve one aspect of performance at the cost of another, or they improve performance in some cases while hurting it in others.

The way that GNU diff determines which lines have changed always comes up with a near-minimal set of differences. Usually it is good enough for practical purposes. If the diff output is large, you might want diff to use a modified algorithm that sometimes produces a smaller set of differences. The -d or --minimal option does this; however, it can also cause diff to run more slowly than usual, so it is not the default behavior. When the files you are comparing are large and have small groups of changes scattered throughout them, you can use the --speed-large-files option to make a different modification to the algorithm that diff uses.

If the input files have a constant small density of changes, this option speeds up the comparisons without changing the output. If not, diff might produce a larger set of differences; however, the output will still be correct. Normally diff discards the prefix and suffix that is common to both files before it attempts to find a minimal set of differences.

This makes diff run faster, but occasionally it may produce non-minimal output. This gives diff further opportunities to find a minimal output. Suppose a run of changed lines includes a sequence of lines at one end and there is an identical sequence of lines just outside the other end. The diff command is free to choose which identical sequence is included in the hunk.

In this case, diff normally shifts the hunk's boundaries when this merges adjacent hunks, or shifts a hunk's lines towards the end of the file. Merging hunks can make the output look nicer in some cases. The "normal" diff3 output format shows each hunk of differences without surrounding context. Hunks are labeled depending on whether they are two-way or three-way, and lines are annotated by their location in the input files.

See Invoking diff3 , for more information on how to run diff3. Sample diff3 Input : Sample diff3 input for examples. Detailed diff3 Normal : A detailed description of normal output format. Example diff3 Normal : Sample output in the normal format.

The first two files are the same that we used for diff see Sample diff Input. This is the third sample file, called tao : The Way that can be told of is not the eternal Way; The name that can be named is not the eternal name. The Nameless is the origin of Heaven and Earth; The named is the mother of all things. Therefore let there always be non-being, so we may see their subtlety, And let there always be being, so we may see their result.

The hunks contain copies of two or three sets of input lines each preceded by one or two commands identifying where the lines came from. Normally, two spaces precede each copy of an input line to distinguish it from the commands.

But with the -T or --initial-tab option, diff3 uses a tab instead of two spaces; this lines up tabs correctly. See Tabs , for more information. Commands take the following forms: file : l a This hunk appears after line l of file file , and contains no lines in that file. To edit this file to yield the other files, one must append hunk lines taken from the other files.

For example, a means that the hunk follows line 11 in the first file and contains no lines from that file. The range r is a comma-separated pair of line numbers, or just one number if the range is a singleton. To edit this file to yield the other files, one must change the specified lines to be the lines taken from the other files.

For example, ,13c means that the hunk contains lines 11 through 13 from the second file. If all three input files differ in a diff3 hunk, the hunk is called a three-way hunk ; if just two input files differ, it is a two-way hunk.

As with diff , several solutions are possible. When comparing the files A , B , and C , diff3 normally finds diff3 hunks by merging the two-way hunks output by the two commands diff A B and diff A C. This does not necessarily minimize the size of the output, but exceptions should be rare. For example, suppose F contains the three lines a , b , f , G contains the lines g , b , g , and H contains the lines a , b , h. Notice that it shows only the lines that are different among the three files.

Wing-tsit Chan Node: diff3 Merging , Next: Interactive Merging , Previous: Comparing Three Files , Up: Top Merging From a Common Ancestor When two people have made changes to copies of the same file, diff3 can produce a merged output that contains both sets of changes together with warnings about conflicts. One might imagine programs with names like diff4 and diff5 to compare more than three files simultaneously, but in practice the need rarely arises. You can use diff3 to merge three or more sets of changes to a file by merging two change sets at a time.

This lets you merge the sets of changes represented by the two newer files. Specify the common ancestor version as the second argument and the two newer versions as the first and third arguments, like this: diff3 mine older yours You can remember the order of the arguments by noting that they are in alphabetical order.

You can think of this as subtracting older from yours and adding the result to mine , or as merging into mine the changes that would turn older into yours. This merging is well-defined as long as mine and older match in the neighborhood of each such change. This fails to be true when all three input files differ or when only older differs; we call this a conflict. When all three input files differ, we call the conflict an overlap. However, it is usually better to have diff3 generate the merged output directly; this bypasses some problems with ed.

Which Changes : Selecting changes to incorporate. Marking Conflicts : Marking conflicts. Bypassing ed : Generating merged output directly. Merging Incomplete Lines : How diff3 merges incomplete lines. You can select only the nonoverlapping unmerged changes with -3 or --easy-only , and you can select only the overlapping changes with -x or --overlap-only.

The -e , -3 and -x options select only unmerged changes , i. If this assumption is not a safe one, you can use the -A or --show-all option see Marking Conflicts. Here is the output of the command diff3 with each of these three options see Sample diff3 Input , for the complete contents of the files.

Notice that -e outputs the union of the disjoint sets of changes output by -3 and -x. Output of diff3 -e lao tzu tao : 11a -- The Way of Lao-Tzu, tr. Wing-tsit Chan. Output of diff3 -3 lao tzu tao : 8c so we may see their result.

Output of diff3 -x lao tzu tao : 11a -- The Way of Lao-Tzu, tr. Thus the -E option acts like the -e option, except that it brackets the first and third files from three-way overlapping changes. Similarly, -X acts like -x , except it brackets all its necessarily overlapping changes. This option can be given up to three times, once for each input file. This is more efficient than using ed to generate it, and works even with non-text files that ed would reject.

If you specify -m without an ed script option, -A --show-all is assumed. Without -m , if an ed script option is specified and an incomplete line is found, diff3 generates a warning and acts as if a newline had been present. System V diff3 generates these extra commands. GNU diff3 normally behaves like traditional Unix diff3 , but with the -i option it behaves like System V diff3 and appends the w and q commands.

The -i option requires one of the ed script options -AeExX3 , and is incompatible with the merged output option -m. See Invoking sdiff , for more details on the options to sdiff. Another way to merge files interactively is to use the Emacs Lisp package emerge. See emerge , for more information. Merge Commands : Merging two files interactively. See diff Options , for the use of these options.

The -l option is equivalent to the --left-column option, and similarly -s is equivalent to --suppress-common-lines. Invoke a text editor on an empty temporary file, then copy the resulting file to the output.

This is the default. The default is system-dependent. Node: Merging with patch , Next: Making Patches , Previous: Interactive Merging , Up: Top Merging with patch patch takes comparison output produced by diff and applies the differences to a copy of the original file, producing a patched version.

With patch , you can distribute just the changes to a set of files instead of distributing the entire file set; your correspondents can apply patch to update their copy of the files with your changes. This lets your correspondents feed a mail message containing a difference listing directly to patch.

It saves any patches that it could not apply. It can also maintain a patchlevel. It applies diff hunks see Hunks one by one. If a hunk does not exactly match the original file, patch uses heuristics to try to patch the file as well as it can. If no approximate match can be found, patch rejects the hunk and skips to the next hunk. See Invoking patch , for detailed information on the options to patch. Imperfect : Dealing with imperfect patches. Creating and Removing : Creating and removing files with a patch.

Patching Time Stamps : Updating time stamps on patched files. Multiple Patches : Handling multiple patches in a file. Backups : Whether backup files are made. Backup Names : Backup file names. Reject Names : Reject file names. Node: patch Input , Next: Revision Control , Up: Merging with patch Selecting the patch Input Format patch normally determines which diff format the patch file uses by examining its contents.

For patch files that contain particularly confusing leading text, you might need to use one of the following options to force patch to interpret the patch file as a certain format of diff. The output formats listed here are the only ones that patch can understand. Node: Revision Control , Next: Imperfect , Previous: patch Input , Up: Merging with patch Revision Control If a nonexistent input file is under a revision control system supported by patch , patch normally asks the user whether to get or check out the file from the revision control system.

If num is positive, patch gets the file without asking the user; if zero, patch neither asks the user nor gets the file; and if negative, patch asks the user before getting the file. Node: Imperfect , Next: Creating and Removing , Previous: Revision Control , Up: Merging with patch Applying Imperfect Patches patch tries to skip any leading text in the patch file, apply the diff, and then skip any trailing text.

Thus you can feed a mail message directly to patch , and it should work. If the entire diff is indented by a constant amount of white space, patch automatically ignores the indentation. If a context diff contains trailing carriage return on each line, patch automatically ignores the carriage return. If a context diff has been encapsulated by prepending - to lines beginning with - as per Internet RFC , patch automatically unencapsulates the input. However, certain other types of imperfect input require user intervention or testing.

Changed White Space : When tabs and spaces don't match exactly. Reversed Patches : Applying reversed patches correctly. Inexact : Helping patch find close matches. Dry Runs : Predicting what patch will do. If this happens to a patch file or an input file, the files might look the same, but patch will not be able to match them properly.

If this problem occurs, use the -l or --ignore-white-space option, which makes patch compare blank characters i. Non-blank characters must still match exactly. Each line of the context must still match a line in the input file. This creates a diff that is "reversed". To apply such patches, give patch the -R or --reverse option.

Rejects come out in the swapped format. Often patch can guess that the patch is reversed. If the first hunk of a patch fails, patch reverses the hunk to see if it can apply it that way. If it can, patch asks you if you want to have the -R option set; if it can't, patch continues to apply the patch normally. This method cannot detect a reversed patch if it is a normal diff and the first command is an append which should have been a delete since appends always succeed, because a null context matches anywhere.

But most patches add or change lines rather than delete them, so most reversed normal diffs begin with a delete, which fails, and patch notices. If you apply a patch that you have already applied, patch thinks it is a reversed patch and offers to un-apply the patch. This could be construed as a feature.

If you did this inadvertently and you don't want to un-apply the patch, just answer n to this offer and to the subsequent "apply anyway" question--or type C-c to kill the patch process.

Node: Inexact , Next: Dry Runs , Previous: Reversed Patches , Up: Imperfect Helping patch Find Inexact Matches For context diffs, and to a lesser extent normal diffs, patch can detect when the line numbers mentioned in the patch are incorrect, and it attempts to find the correct place to apply each hunk of the patch.

As a first guess, it takes the line number mentioned in the hunk, plus or minus any offset used in applying the previous hunk. If that is not the correct place, patch scans both forward and backward for a set of lines matching the context given in the hunk.

First patch looks for a place where all lines of the context match. If it cannot find such a place, and it is reading a context or unified diff, and the maximum fuzz factor is set to 1 or more, then patch makes another scan, ignoring the first and last line of context.

If that fails, and the maximum fuzz factor is set to 2 or more, it makes another scan, ignoring the first two and last two lines of context are ignored. It continues similarly if the maximum fuzz factor is larger. This option only applies to context and unified diffs; it ignores up to lines lines while looking for the place to install a hunk. Note that a larger fuzz factor increases the odds of making a faulty patch.

The default fuzz factor is 2; there is no point to setting it to more than the number of lines of context in the diff, ordinarily 3. If patch cannot find a place to install a hunk of the patch, it writes the hunk out to a reject file see Reject Names , for information on how reject files are named.

The problem here is that diff -u only gives me a file lines of context, while I want to output the entire file in a unified format. Once there, it will prompt you with what lines you want to keep from which file.

Also man sdiff with the detailed goods. If you need to automate the process, you might want to try the util merge , which will mark conflicts in the files. However, that might put you back at square one. The easy answer is to use the -D flag to merge the files and surround the differences with C style ifdef statements. Stack Overflow for Teams — Collaborate and share knowledge with a private group. Create a free Team What is Teams?

Collectives on Stack Overflow. Learn more. Manually merge two files using diff Ask Question. Asked 8 years, 7 months ago. Another free and open source tool answers to the name of KDiff3. The project hasn't seen many updates in recent years though you may be able to find more recent releases through this page , but it remains a solid diff and merge tool that should satisfy basic needs. Much like Araxis, the DeltaWalker diff tool also lets you compare office files.

If you're regularly performing comparisons on a folder basis, it's good to know that DeltaWalker shines with great performance in this area. Perforce , the company best known for its enterprise version control platform, also offers a solid diff tool: P4Merge is free of charge and comes with a basic feature set that makes it an interesting option on Windows, macOS and Linux.

Besides offering all the standard diff and merge capabilities, Code Compare comes with some special features like syntax highlighting , semantic code comparison and a VisualStudio integration. The basic version can be used free of charge, while the Professional Edition delivers the full feature set. WinMerge is an open-source diff tool with some nice features like folder and image comparison, and three-way file comparison.

Guiffy is a full-featured tool with syntax highlighting, three-way comparisons and merges, and multiple comparison algorithms. It comes in pro and expert versions, and supports Windows, macOS and Linux.



0コメント

  • 1000 / 1000