8

TortoiseSVN (as well as other Tortoise clients) include a script to diff notebook files in Mathematica. Diff functionality for Mathematica is implemented in the AuthorTools package (perhaps there is something better?)

The script currently works by creating a small notebook file in the temp directory, and opening it in the front end. The notebook has a big button that will do the diff and has the file names to be diffed hard coded.

A disadvantage is that the notebook with the diff code will be left in the temp directory, and won't be cleaned up. It also seems unnecessary to have an auxiliary notebook open every time we do a diff.

Is it possible to launch the diff functionality from the command line to avoid going through the temporary notebook? Or is there any other robust way to improve this process and avoid littering the temp folder with auxiliary notebooks?

Any suggestions to improve the diffing experience are welcome!

Note that since TortoiseSVN is a Windows program, I am primarily interested in Windows-based solutions.


Here's an example notebook that the script generates. I realize it's in need of cleanup, but last time I checked it worked in version 5 too (!), so I did not want to touch it unnecessarily (without visibly improving something).

Notebook[{ 
  Cell[BoxData[ButtonBox["\<\"Compare Notebooks\"\>", 
       ButtonFrame->"DialogBox", Active->True, ButtonEvaluator->Automatic,
       ButtonFunction:>(Needs["AuthorTools`"]; NotebookPut[Symbol["NotebookDiff"]["one.nb", "two.nb"]])
  ]], NotebookDefault] },
  Saveable->False, Editable->False, Selectable->False, WindowToolbars->{}, 
  WindowFrame->ModelessDialog, WindowElements->{}, 
  WindowFrameElements->CloseBox, WindowTitle->"Diff", 
  ShowCellBracket->False, WindowSize->{Fit,Fit}
]
gdelfino
  • 11,053
  • 6
  • 44
  • 48
Szabolcs
  • 24,728
  • 9
  • 85
  • 174
  • 2
    Interesting reputation: http://i.stack.imgur.com/2ze1M.png – Mr.Wizard Nov 29 '11 at 20:48
  • Version control of a Mma notebook is not easy. I normally follow the advice given by Michael Pilat in [this question](http://stackoverflow.com/q/2816628/421225). I.e. turn off the cache and history, then use a standard text-based diff. – Simon Nov 29 '11 at 21:38
  • @Simon `NotebookDiff` seems to work okay, did you have problems with it? – Szabolcs Nov 29 '11 at 22:07
  • `NotebookDiff` can be handy for humans - but it doesn't show you what your version control system will be seeing. – Simon Nov 29 '11 at 22:20

1 Answers1

4

Here's a simple example of producing the notebook diff using a Mathematica script.

Save the following as diff.m

Needs["AuthorTools`"]
If[Length[$ScriptCommandLine]>=3, 
    {f1, f2} = $ScriptCommandLine[[{2,3}]], 
    {f1, f2} = {"one.nb", "two.nb"}]
diff = FileNameJoin[{$TemporaryDirectory, "diff.nb"}]
Put[NotebookDiff[f1, f2], diff]
Run["Mathematica " <> diff]
DeleteFile[diff]
Exit[]

Then call it from the command line using MathematicaScript -script diff.m "one.nb" "two.nb". This works on my system (Ubuntu 11.10, Mathematica 8.0.1) and should be platform independent. If you're using a version of Mathematica older than v8, then you'd have to use MathKernel -noprompt -run < diff.m instead of MathematicaScript and the default values for {f1, f2} will be used.

Simon
  • 14,631
  • 4
  • 41
  • 101
  • Actually, this doesn't seem to work on version 7. In both versions, if `NotebookDiff` is given notebook objects, then it calls ``AuthorTools`NotebookDiff`Private`notebookDiff``. If given expressions with head `Notebook` it uses `NotebookPut` on them, then calls `NotebookDiff` again. Otherwise, it tries to use ``AuthorTools`NotebookDiff`Private`NotebookDiffFiles``, which works with version 8 but not version 7... I'm not sure why. – Simon Nov 29 '11 at 23:45
  • 1
    The main difference compared to the original version I linked to is that you wrap calling the Front End by a script. When the Front End finishes, the script deletes the file. This is possible from the original VBScript version too. However, it just won't work on Windows because usually only a single instance of the Front End is allowed to run: if the newly started Front End detects an already running one, it just passes the notebook to be opened to it, and exits. (Actually I find it quite annoying that this does not happen on Linux.) – Szabolcs Nov 30 '11 at 08:01
  • 1
    @Szabolcs: I thought the main difference was that you didn't need to press the "Compare Notebooks" button. As for the problem you mentioned due to Windows not allowing more than one frontend instance, maybe you delete the file by hooking into `FrontEndEventActions`. For example: `SetOptions[$FrontEndSession, FrontEndEventActions -> {"WindowClose" :> (DeleteFile["diff.file"]; SetOptions[$FrontEndSession, FrontEndEventActions -> Automatic])}]`. This would need some finessing... maybe you're better off with your current script! – Simon Nov 30 '11 at 13:34