Context-aware merge?
Asked Answered
L

8

34

Is there any diff/merge tool for programming languages, that works in a syntax-aware way (like XML Diff Tool), doing more than compare line-by-line (and optionally ignoring whitespace).

I'm interested in a program actually following the language syntax and delimeters, suggesting changes without breaking syntactic correctness, or bundling statements separated over multiple lines. Example behavior would be:

*upon finding an if(){ which introduces an extra nesting level automatically bundle the closing brace } several lines below with it.)

*keep matching syntax elements together, avoid silliness like removing a block tends to create:

 int function_A()
 { 
     int ret;
     ret = something;
     ret += something_else;

      return ret;
  }

  int function_B()
  { 
     if(valid)
     {
         int ret;
         ret = something;
         ret += something_else;

          return ret;
      }

       else return -1;
  }

Personally, I'd love to find software capable of handling C++ syntax, but knowing about solutions for other languages would be interesting too.

Lexicology answered 21/2, 2011 at 15:32 Comment(0)
W
9

Beyond Compare does some of what you're asking. It doesn't maintain syntactical correctness or compare language blocks at a time, but it can do the following:

  • Some understanding of language syntax, so it can do syntax highlighting of compared files, and it can also recognize and optionally ignore unimportant differences (like comments, including multiline comments).
  • Support for using external conversion programs for loading and saving data. Out of the box, it supports using this to prettify XML and HTML before comparing it. You could set up GNU Indent to standardize syntax before comparing two C files.
  • Optional line weights to let you give a higher weight to matching, e.g., closing braces. I've not tried this feature.
  • Replacements, to ignore for a single session every place where old_variable_name on the left was replaced with new_variable_name on the right.

It's by far the best diff-and-merge tool that I've used. It's also cross platform, cheap ($30 for standard, $50 for pro), and has a very generous evaluation period, so it's worth a try.

Wax answered 2/3, 2011 at 16:28 Comment(3)
Thank you. While others suggest some interesting solutions, there is only one merge tool suggested (which offers more flexibility in telling it what I want, but doesn't have much more "smarts" itself, and other answers are strictly diff tools - and I'm more in need of a merge tool than a diff tool. It seems like your suggestion is the most practical.Lexicology
@SF.: Beyond Compare also lets you tell it what you want (under the Edit menu, using the "Align With" and "Isolate" options), although I've never used those features. (I didn't know it could do that until I saw hlovdal's answer about KDiff3 and looked to see if Beyond Compare could do the same.)Wax
I've used Araxis Merge for some years. I use the linking in the center to clean up difficult compares and make the appropriate items align. I've use BC2 & BC3 as a corporate standard, and I find Araxis Merge to be a standout tool over those (Although BC3 was a major improvement).Heraclea
A
20

Semantic Merge.
Languages supported, from the website:

We started with C# and Vb.net, then added Java. Now C is already supported and then we’ll focus on C++, Objective-C and JavaScript, depending on your feedback

Antonio answered 17/4, 2013 at 21:2 Comment(2)
certificate on that link is expired, is it the same as docs.plasticscm.com/semanticmerge ?Raasch
If I recall correctly it was from PlasticCSM (I never ended up purchasing it so haven't looked at it in over 10 years)Antonio
C
14

While KDiff3 does not compare syntax elements in a grammar context, it does have a higher granularity than "the whole line changed", and it will highlighting exactly what parts within a line that is changed.

And in my experience it has a very good algorithm for detecting changes. Given your example above, it correctly compares function_A and function_B out of the box:

Comparision of function_A and function_B

And even so, should the algorithm fail to match what you want, for instance like the following:

Comparision of old and new function_A

you can always override manually by placing sync marks where you want to have it perform the comparision.

Alternative 1:

Comparision of old and new function_A with sync1

Alternative 2:

Comparision of old and new function_A with sync2

Classicist answered 25/2, 2011 at 12:28 Comment(0)
F
11

Sounds like you'd be interested in Bram Cohen's (BitTorrent creator) Patience Diff algorithm (which is used in the bazaar version control system).

See The diff problem has been solved and especially Patience Diff Advantages:

Excerpt from second link:

Another advantage of patience diff is that it frequently doesn't match lines which just plain shouldn't match. For example, if you've completely rewritten a section of code it shouldn't match up the blank lines in each version, as this example shows. Finally, there's this example:

 void func1() {
     x += 1
 }

+void functhreehalves() {
+    x += 1.5
+}
+
 void func2() {
     x += 2
 }

Which is straightforward and obvious, but frequently diff algorithms will interpret it like this:

 void func1() {
     x += 1
+}
+
+void functhreehalves() {
+    x += 1.5
 }

 void func2() {
     x += 2
 }
Feline answered 3/3, 2011 at 6:59 Comment(0)
W
9

Beyond Compare does some of what you're asking. It doesn't maintain syntactical correctness or compare language blocks at a time, but it can do the following:

  • Some understanding of language syntax, so it can do syntax highlighting of compared files, and it can also recognize and optionally ignore unimportant differences (like comments, including multiline comments).
  • Support for using external conversion programs for loading and saving data. Out of the box, it supports using this to prettify XML and HTML before comparing it. You could set up GNU Indent to standardize syntax before comparing two C files.
  • Optional line weights to let you give a higher weight to matching, e.g., closing braces. I've not tried this feature.
  • Replacements, to ignore for a single session every place where old_variable_name on the left was replaced with new_variable_name on the right.

It's by far the best diff-and-merge tool that I've used. It's also cross platform, cheap ($30 for standard, $50 for pro), and has a very generous evaluation period, so it's worth a try.

Wax answered 2/3, 2011 at 16:28 Comment(3)
Thank you. While others suggest some interesting solutions, there is only one merge tool suggested (which offers more flexibility in telling it what I want, but doesn't have much more "smarts" itself, and other answers are strictly diff tools - and I'm more in need of a merge tool than a diff tool. It seems like your suggestion is the most practical.Lexicology
@SF.: Beyond Compare also lets you tell it what you want (under the Edit menu, using the "Align With" and "Isolate" options), although I've never used those features. (I didn't know it could do that until I saw hlovdal's answer about KDiff3 and looked to see if Beyond Compare could do the same.)Wax
I've used Araxis Merge for some years. I use the linking in the center to clean up difficult compares and make the appropriate items align. I've use BC2 & BC3 as a corporate standard, and I find Araxis Merge to be a standout tool over those (Although BC3 was a major improvement).Heraclea
S
6

See our SmartDifferencer tools.

SmartDifferencers are language specific, driven by production quality language parsers, build ASTs, and compare the trees. This makes them completely indepedent of text layout and intervening comments; remarkably, they are immune to changes in the text of literals (radix, move decimal point+change exponent, different escape sequences) if the actual value represented by the literal isn't different. The result is reported in language syntax terms, and plausible editing actions (move, copy, insert, delete, rename-identifier-within-block).

There are versions for C#, Java, C++, Python, and a variety of other languages. There are examples of each of these at the website.

A SmartDifferencer exists for C, but parsing C files without the full compiler command line is sometimes problematic, so sometimes it fails and you have to fall back to more primitive compare tools, like diff. We are working to improve this situation.

Screwdriver answered 26/2, 2011 at 3:57 Comment(9)
Some screenshots with a couple of examples wouldn't hurt.Anode
It isn't a merge tool. Its a diff tool.Screwdriver
Enterprise software :( Always sad to see a huge registration form blocking a download. I have to be pretty damn desperate before I jump through that hoop.Ritz
@boxed: Huge? It has maybe 5 fields you have to fill in. I'm always surprised at the tradeoffs people make, a few boxes now vs the potential to save some of their time everyday.Screwdriver
Tried it. Did not ignore simple changes like adding braces to one line if.Champac
@TomasTintera: I assume you are complaining about it not ignoring IF COND STMT vs. IF COND { STMT }. This is a change of syntax that happens to have the same semantics. The SmartDiff tool as presently realized checks for the same syntax regardless of layout, so it will identify this as a difference, true. (Is this your only criteria for a good tool?) But there are lots of other "simple syntax changes" that it won't detect like ** A+ B ** vs ** A - (- B) **. To do this properly, it has to have full undersanding of the language semantics. Our tool presently does not...Screwdriver
... In fact, I don't know of any tools that ignore syntax changes that are semantically identical. We could add special cases like the IF example; and that might be a good idea but we aren't there yet. AFAIK, none of the other "langauge aware" tools really use a full language parser to compute the differences accurately.Screwdriver
@Ira baxter: I'm looking for tool check two C++11 files/projects are same (ignoring formatting changes). So is IF COND STMT vs. IF COND { STMT } as long as STMT is not macro including for example two statements. Looking at compilers and their options now.Champac
@TomasTintera: As I pointed out, adding {...} around as single statement as a THEN clause is NOT a format change; it is a real syntax change. If this is necessary for your task, you could normalize all such statements to have or not have the braces. Our DMS Software Reengineering Tookit can do this allmost trivally,but it is rather big cannon for this task.You might be better off running the smart differencer,and ignoring any place where it claims to see a statement inserted into { ... }. Did you check the Smart Diff's output? THis should be pretty easy to see/eliminate.Screwdriver
J
6

Please look at Compare++.

It can do language-aware structured comparison for C/C++, Java, C#, Javascript, CSS, ... and Optionally ignore comment, pure formatted, white-space and case changes and have unique ability to align moved sections such as C++ function, Java namespace, C# method, CSS selector, ...

Janiuszck answered 7/3, 2012 at 9:37 Comment(2)
Compare++ has also polished user interface.Champac
No longer availablePaige
Y
3

If you are using eclipse, the integrated compare editor provides syntax aware diff/merge, at least for Java. Check "Open Structure Compare automatically" under the "General/Compare/Patch" preferences, then choose "Java Structure Compare" in the compare editor.

Yl answered 3/3, 2011 at 17:4 Comment(1)
OTOH it is truly abysmal for other languages. I saw it remove 1000 lines from left and reinsert the same 1000 lines as "new" over two whitespace differences 1000 lines apart.Lexicology
C
1

Look at https://en.wikipedia.org/wiki/Comparison_of_file_comparison_tools especially column Structured comparison.

Currently there are only two tools who understand language structure.

  • Compare++ (Works great for C++)
  • Pretty Diff (Language aware code comparison tool for several web based languages. It also beautifies, minifies, and a few other things..)

Unfortunately many tools have this column still empty.

Champac answered 4/9, 2017 at 10:59 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.