开发者

Revision Changes - Visually showing changes

Rollback of an article


I have deleted a lot of the body of this question because I realised I should rephrase it. Here it the rephrase:

How can I implement something with strike throughs? Comparing one revision update to the previous. I don't want revision or version contro开发者_JAVA技巧l per se, because I can just handle that in my mySQL database, but I want to be able to visually identify changes with green and red strike through updates on an almost changelog like page (should the user wish to see it).

I have seen something similar on the revision changes on SO, and would like to have something like this?

I think my question now is fundamentally different from the original, sorry

But here: https://stackoverflow.com/posts/2326658/revisions


Part-1: data structure (from original question):

  1. One row per version -VS- all versions in one row:
    Store one revision per row, do not pack all revisions into one row as XML or any other multi-value supporting types. Initially the article might be edited few times and the revisions will be asked for by the author(s), but later on only the most recent version will be requested by your application. In this case there is no point in loading all the change history.

  2. One table -VS- two tables:
    Third_normal_form would suggest using 2 tables:
    - Article[ActicleID(int,PK), AuthorID(int,FK), ...]
    - ArticleRevisions[ArticleID(int,UK), RevisionID(int,UK), Content, RevisionComment, RevisionTimeStamp, ...]
    In any case store complete articles and do not play with delta-type implementation - your use case does not call for the complexity, but for simplicity. Also you might redundantly store the LatestRevisionID in the Article table for easier retrieval of latest revision.
    You might opt for the solution with one table. For an example look at line 76 (Table('wiki'...) in the database schema of Trac. Also you might take a look how Trac does it for its simple Wikis by looking at example of their revision history and revision diff, which are quite similar to those on StackOverflow.

Part-2: detecting and presenting differences between two revisions:
First of all, one does not visually identifies the changes, but rather programmatically. What you need is a library which given two files (strings/lists of strings) will provide you will a diff result. In many cases one opts for line-by-line comparison, as did stackoverflow). Then you need a mean of presenting those results to the use (with greens, reds, strikeouts etc).

Although I have little knowledge about PHP and its libraries, following links should get you started:

  • meta.SO: What revision library does stackoverflow use? with links to the C# implementation and the algorithm explanation
  • SO: Calculate text diffs in PHP
  • 8.4. difflib — Helpers for computing deltas - difflib for python, which is used by Trac
  • jsdifflib demo - text diff for javascript


Your suggestion sounds entirely sensible to me: one table with a row per revision, and one table with a row per "displayable article" which effectively links to the current revision within the revisions table. What's verbose about that?

You could fake it with some sort of "current" column in a single table, but then you'd have to make sure that only one revision was current for any particular article, which sounds pretty nasty to me.


Try storing it as an XML

As far as I can understand the problem. It can be solved if we store each line as a row. But that will be bad because number of rows increases tremendously.

So store data in a row as

<row num=1>How would you structure something like this. I want to allow my authors to create articles. However, </row>
<row num=2>should they choose, I would like to be able to allow each save to be a new revision and then allow each </row>
............

Everything in one row but in xml format. When u retrieve it, you can compare rows using num attribute.


Your question could be summarized as "how is version control implemented?" The usual is that each revision is stored as a diff from the old version instead of the whole text over again (though there are lots of variations). Most systems can/will store all the versions complete for non-text formats that they can't isolate changes into "lines".


If I understand your tags correctly, you are looking for an implementation of diff in PHP. Correct? How you store it in your database depends on factors we can't really see right now - we don't know what you plan to do with multiple languages and such. Anyway, what will remain is that every revision is going to be a mysql text field somehow, in a record. You would then compare two of those revisions using diff.

Here are some interesting-looking PHP implementations. I have not worked with any of those, so I can't tell you how good they are and whether they meet your requirements, but they may be at least a starting point:

  • There's a PEAR text diff engine you would have to install it to see what kind of results it produces, seems to have no online demo

  • Based on that, there's PHP inline diff - tool to produce inline diffs with some sample output that looks very promising.

Depending on your server configuration, you may also be able to use Linux command-line diff for example.


I can't tell whether you're dealing with diffs of code or more general documents. I did an implementation a few years back that displayed diffs of versions of wiki documents, with the two versions side by side, deletions marked in red on the older version, additions in green on the newer version. All this was done in javascript, first extracting just the text parts of the HTML, diffing those (using diff_match_patch.js), and then using the diff results to determine what to highlight (using styles to change background colors). It was pretty tricky, not perfect (but close enough) and involved quite a bit of DOM manipulation. So, doable, but not easy.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜