Edgewall Software

Ticket #781: 781.diff

File 781.diff, 16.2 KB (added by markus, 3 years ago)
  • templates/changeset.cs

     
    2222</div> 
    2323 
    2424<div id="content" class="changeset"> 
    25 <h1>Changeset <?cs var:changeset.revision ?></h1> 
     25<h1><a href="<?cs var:changeset.href ?>">Changeset <?cs var:changeset.revision ?></a></h1> 
    2626 
    2727<?cs each:change = changeset.changes ?><?cs 
    2828 if:len(change.diff) ?><?cs 
     
    100100  /if ?> 
    101101<?cs /def ?> 
    102102 
    103 <dl id="overview"> 
    104  <dt class="time">Timestamp:</dt> 
    105  <dd class="time"><?cs var:changeset.time ?></dd> 
    106  <dt class="author">Author:</dt> 
    107  <dd class="author"><?cs var:changeset.author ?></dd> 
    108  <dt class="message">Message:</dt> 
    109  <dd class="message" id="searchable"><?cs 
    110   alt:changeset.message ?>&nbsp;<?cs /alt ?></dd> 
    111  <dt class="files">Files:</dt> 
    112  <dd class="files"> 
    113   <ul><?cs each:item = changeset.changes ?> 
    114    <li><?cs 
    115     if:item.change == 'add' ?><?cs 
    116      call:node_change(item, 'add', 'added') ?><?cs 
    117     elif:item.change == 'delete' ?><?cs 
    118      call:node_change(item, 'rem', 'deleted') ?><?cs 
    119     elif:item.change == 'copy' ?><?cs 
    120      call:node_change(item, 'cp', 'copied') ?><?cs 
    121     elif:item.change == 'move' ?><?cs 
    122      call:node_change(item, 'mv', 'moved') ?><?cs 
    123     elif:item.change == 'edit' ?><?cs 
    124      call:node_change(item, 'mod', 'modified') ?><?cs 
    125     /if ?> 
    126    </li> 
    127   <?cs /each ?></ul> 
    128  </dd> 
    129 </dl> 
     103<?cs if:changeset.mode == "view" ?> 
     104 <dl id="overview"> 
     105  <dt class="time">Timestamp:</dt> 
     106  <dd class="time"><?cs var:changeset.time ?></dd> 
     107  <dt class="author">Author:</dt> 
     108  <dd class="author"><?cs var:changeset.author ?></dd> 
     109  <dt class="message"><a href="?action=edit" title="Edit Message">Message:</a></dt> 
     110  <dd class="message" id="searchable"><?cs 
     111   alt:changeset.message_html ?>&nbsp;<?cs /alt ?></dd> 
     112  <dt class="files">Files:</dt> 
     113  <dd class="files"> 
     114   <ul><?cs each:item = changeset.changes ?> 
     115    <li><?cs 
     116     if:item.change == 'add' ?><?cs 
     117      call:node_change(item, 'add', 'added') ?><?cs 
     118     elif:item.change == 'delete' ?><?cs 
     119      call:node_change(item, 'rem', 'deleted') ?><?cs 
     120     elif:item.change == 'copy' ?><?cs 
     121      call:node_change(item, 'cp', 'copied') ?><?cs 
     122     elif:item.change == 'move' ?><?cs 
     123      call:node_change(item, 'mv', 'moved') ?><?cs 
     124     elif:item.change == 'edit' ?><?cs 
     125      call:node_change(item, 'mod', 'modified') ?><?cs 
     126     /if ?> 
     127    </li> 
     128   <?cs /each ?></ul> 
     129  </dd> 
     130 </dl> 
    130131 
    131 <div class="diff"> 
    132  <div id="legend"> 
    133   <h3>Legend:</h3> 
    134   <dl> 
    135    <dt class="unmod"></dt><dd>Unmodified</dd> 
    136    <dt class="add"></dt><dd>Added</dd> 
    137    <dt class="rem"></dt><dd>Removed</dd> 
    138    <dt class="mod"></dt><dd>Modified</dd> 
    139    <dt class="cp"></dt><dd>Copied</dd> 
    140    <dt class="mv"></dt><dd>Moved</dd> 
    141   </dl> 
     132 <div class="diff"> 
     133  <div id="legend"> 
     134   <h3>Legend:</h3> 
     135   <dl> 
     136    <dt class="unmod"></dt><dd>Unmodified</dd> 
     137    <dt class="add"></dt><dd>Added</dd> 
     138    <dt class="rem"></dt><dd>Removed</dd> 
     139    <dt class="mod"></dt><dd>Modified</dd> 
     140    <dt class="cp"></dt><dd>Copied</dd> 
     141    <dt class="mv"></dt><dd>Moved</dd> 
     142   </dl> 
     143  </div> 
     144  <ul class="entries"><?cs 
     145  each:item = changeset.changes ?><?cs 
     146   if:len(item.diff) || len(item.props) ?><li class="entry" id="file<?cs 
     147    var:name(item) ?>"><h2><a href="<?cs 
     148    var:item.browser_href.new ?>" title="Show new revision <?cs 
     149    var:item.rev.new ?> of this file in browser"><?cs 
     150    var:item.path.new ?></a></h2><?cs 
     151    if:len(item.props) ?><ul class="props"><?cs 
     152     each:prop = item.props ?><li>Property <strong><?cs 
     153      var:name(prop) ?></strong> <?cs 
     154      if:prop.old && prop.new ?>changed from <?cs 
     155      elif:!prop.old ?>set<?cs 
     156      else ?>deleted<?cs 
     157      /if ?><?cs 
     158      if:prop.old && prop.new ?><em><tt><?cs var:prop.old ?></tt></em><?cs /if ?><?cs 
     159      if:prop.new ?> to <em><tt><?cs var:prop.new ?></tt></em><?cs /if ?></li><?cs 
     160     /each ?></ul><?cs 
     161    /if ?><?cs 
     162    if:len(item.diff) ?><table class="<?cs 
     163     var:diff.style ?>" summary="Differences" cellspacing="0"><?cs 
     164     if:diff.style == 'sidebyside' ?> 
     165      <colgroup class="l"><col class="lineno" /><col class="content" /></colgroup> 
     166      <colgroup class="r"><col class="lineno" /><col class="content" /></colgroup> 
     167      <thead><tr> 
     168       <th colspan="2"><a href="<?cs 
     169        var:item.browser_href.old ?>" title="Show old rev. <?cs 
     170        var:item.rev.old ?> of <?cs var:item.path.old ?>">Revision <?cs 
     171        var:item.rev.old ?></a></th> 
     172       <th colspan="2"><a href="<?cs 
     173        var:item.browser_href.new ?>" title="Show new rev. <?cs 
     174        var:item.rev.new ?> of <?cs var:item.path.new ?>">Revision <?cs 
     175        var:item.rev.new ?></a></th> 
     176       </tr> 
     177      </thead><?cs 
     178      each:change = item.diff ?><tbody><?cs 
     179       call:diff_display(change, diff.style) ?></tbody><?cs 
     180       if:name(change) < len(item.diff) - 1 ?><tbody class="skipped"><tr> 
     181        <th>&hellip;</th><td>&nbsp;</td><th>&hellip;</th><td>&nbsp;</td> 
     182       </tr></tbody><?cs /if ?><?cs 
     183      /each ?><?cs 
     184     else ?> 
     185      <colgroup><col class="lineno" /><col class="lineno" /><col class="content" /></colgroup> 
     186      <thead><tr> 
     187       <th title="Revision <?cs var:item.rev.old ?>"><a href="<?cs 
     188        var:item.browser_href.old ?>" title="Show old version of <?cs 
     189        var:item.path.old ?>">r<?cs var:item.rev.old ?></a></th> 
     190       <th title="Revision <?cs var:item.rev.new ?>"><a href="<?cs 
     191        var:item.browser_href.new ?>" title="Show new version of <?cs 
     192        var:item.path.new ?>">r<?cs var:item.rev.new ?></a></th> 
     193       <th>&nbsp;</th></tr> 
     194      </thead><?cs 
     195      each:change = item.diff ?><?cs 
     196       call:diff_display(change, diff.style) ?><?cs 
     197       if:name(change) < len(item.diff) - 1 ?><tbody class="skipped"><tr> 
     198        <th>&hellip;</th><th>&hellip;</th><td>&nbsp;</td> 
     199       </tr></tbody><?cs /if ?><?cs 
     200      /each ?><?cs 
     201     /if ?></table><?cs 
     202    /if ?></li><?cs 
     203   /if ?><?cs 
     204  /each ?></ul> 
    142205 </div> 
    143  <ul class="entries"><?cs 
    144  each:item = changeset.changes ?><?cs 
    145   if:len(item.diff) || len(item.props) ?><li class="entry" id="file<?cs 
    146    var:name(item) ?>"><h2><a href="<?cs 
    147    var:item.browser_href.new ?>" title="Show new revision <?cs 
    148    var:item.rev.new ?> of this file in browser"><?cs 
    149    var:item.path.new ?></a></h2><?cs 
    150    if:len(item.props) ?><ul class="props"><?cs 
    151     each:prop = item.props ?><li>Property <strong><?cs 
    152      var:name(prop) ?></strong> <?cs 
    153      if:prop.old && prop.new ?>changed from <?cs 
    154      elif:!prop.old ?>set<?cs 
    155      else ?>deleted<?cs 
    156      /if ?><?cs 
    157      if:prop.old && prop.new ?><em><tt><?cs var:prop.old ?></tt></em><?cs /if ?><?cs 
    158      if:prop.new ?> to <em><tt><?cs var:prop.new ?></tt></em><?cs /if ?></li><?cs 
    159     /each ?></ul><?cs 
    160    /if ?><?cs 
    161    if:len(item.diff) ?><table class="<?cs 
    162     var:diff.style ?>" summary="Differences" cellspacing="0"><?cs 
    163     if:diff.style == 'sidebyside' ?> 
    164      <colgroup class="l"><col class="lineno" /><col class="content" /></colgroup> 
    165      <colgroup class="r"><col class="lineno" /><col class="content" /></colgroup> 
    166      <thead><tr> 
    167       <th colspan="2"><a href="<?cs 
    168        var:item.browser_href.old ?>" title="Show old rev. <?cs 
    169        var:item.rev.old ?> of <?cs var:item.path.old ?>">Revision <?cs 
    170        var:item.rev.old ?></a></th> 
    171       <th colspan="2"><a href="<?cs 
    172        var:item.browser_href.new ?>" title="Show new rev. <?cs 
    173        var:item.rev.new ?> of <?cs var:item.path.new ?>">Revision <?cs 
    174        var:item.rev.new ?></a></th> 
    175       </tr> 
    176      </thead><?cs 
    177      each:change = item.diff ?><tbody><?cs 
    178       call:diff_display(change, diff.style) ?></tbody><?cs 
    179       if:name(change) < len(item.diff) - 1 ?><tbody class="skipped"><tr> 
    180        <th>&hellip;</th><td>&nbsp;</td><th>&hellip;</th><td>&nbsp;</td> 
    181       </tr></tbody><?cs /if ?><?cs 
    182      /each ?><?cs 
    183     else ?> 
    184      <colgroup><col class="lineno" /><col class="lineno" /><col class="content" /></colgroup> 
    185      <thead><tr> 
    186       <th title="Revision <?cs var:item.rev.old ?>"><a href="<?cs 
    187        var:item.browser_href.old ?>" title="Show old version of <?cs 
    188        var:item.path.old ?>">r<?cs var:item.rev.old ?></a></th> 
    189       <th title="Revision <?cs var:item.rev.new ?>"><a href="<?cs 
    190        var:item.browser_href.new ?>" title="Show new version of <?cs 
    191        var:item.path.new ?>">r<?cs var:item.rev.new ?></a></th> 
    192       <th>&nbsp;</th></tr> 
    193      </thead><?cs 
    194      each:change = item.diff ?><?cs 
    195       call:diff_display(change, diff.style) ?><?cs 
    196       if:name(change) < len(item.diff) - 1 ?><tbody class="skipped"><tr> 
    197        <th>&hellip;</th><th>&hellip;</th><td>&nbsp;</td> 
    198       </tr></tbody><?cs /if ?><?cs 
    199      /each ?><?cs 
    200     /if ?></table><?cs 
    201    /if ?></li><?cs 
    202   /if ?><?cs 
    203  /each ?></ul> 
    204 </div> 
     206<?cs elif:changeset.mode == "edit" ?> 
     207 <table id="chglist" class="listing"> 
     208  <thead> 
     209   <tr> 
     210    <th class="date">Date</th> 
     211    <th class="author">Author</th> 
     212    <th class="summary">Log Message</th> 
     213   </tr> 
     214  </thead> 
     215  <tbody> 
     216   <?cs each change = changeset.change ?> 
     217     <tr class="<?cs if:name(change) % #2 ?>even<?cs else ?>odd<?cs /if ?>"> 
     218    <td><?cs var:change.time ?></td> 
     219    <td><?cs var:change.author ?></td> 
     220    <td><?cs var:change.msg ?></td></tr> 
     221   <?cs /each ?> 
     222  </tbody> 
     223 </table> 
     224 <br /> 
     225 <form class="mod" id="modcomp" method="post"> 
     226  <fieldset> 
     227   <legend>Change Log Message:</legend> 
     228   <div class="field"> 
     229    <fieldset class="iefix"> 
     230     <label for="message">New Message (you may use <a tabindex="42" href="<?cs 
     231       var:trac.href.wiki ?>/WikiFormatting">WikiFormatting</a> here):</label> 
     232     <p><textarea id="message" name="message" class="wikitext" rows="6" cols="60"><?cs 
     233     var:changeset.message ?></textarea></p> 
     234    </fieldset> 
     235   </div> 
     236   <script type="text/javascript" src="<?cs 
     237     var:chrome.href ?>/common/js/wikitoolbar.js"></script> 
     238   <div class="buttons"> 
     239    <input type="submit" name="save" value="Save" /> 
     240   </div> 
     241  </fieldset> 
     242 </form> 
     243<?cs /if ?> 
    205244 
    206245</div> 
    207246<?cs include "footer.cs"?> 
  • trac/db_default.py

     
    8383        Column('author'), 
    8484        Column('message'), 
    8585        Index(['time'])], 
     86    Table('log_change', key=('rev', 'time'))[ 
     87        Column('rev'), 
     88        Column('time', type='int'), 
     89        Column('author'), 
     90        Column('message'), 
     91        Index(['rev', 'time'])], 
    8692    Table('node_change', key=('rev', 'path', 'change'))[ 
    8793        Column('rev'), 
    8894        Column('path'), 
  • trac/versioncontrol/cache.py

     
    125125    def normalize_rev(self, rev): 
    126126        return self.repos.normalize_rev(rev) 
    127127 
     128    def change_log(self, rev, message, author): 
     129        # update svn fs 
     130        self.repos.get_changeset(rev).change_log(self.db, message, author) 
     131        # update cached repo 
     132        cursor = self.db.cursor() 
     133        cursor.execute("UPDATE revision SET message=%s WHERE rev=%s", (message, rev)) 
     134        self.db.commit() 
    128135 
    129136class CachedChangeset(Changeset): 
    130137 
     
    153160            kind = _kindmap[kind] 
    154161            change = _actionmap[change] 
    155162            yield path, kind, change, base_path, base_rev 
     163 
     164    def last_modified(self): 
     165            cursor = self.db.cursor() 
     166            cursor.execute("SELECT time FROM log_change WHERE rev=%s", (self.rev,)) 
     167            rows = cursor.fetchall() or [] 
     168 
     169            def cmp_func(a, b): 
     170                return cmp(b[0], a[0]) 
     171 
     172            rows.sort(cmp_func) 
     173            return rows[0][0] or self.date 
     174 No newline at end of file 
  • trac/versioncontrol/svn_fs.py

     
    1616 
    1717from __future__ import generators 
    1818 
    19 from trac.util import TracError 
     19from trac.util import TracError, get_reporter_id 
    2020from trac.versioncontrol import Changeset, Node, Repository 
    2121 
    2222import os.path 
     
    504504        for change in changes: 
    505505            yield tuple(change) 
    506506 
     507    def change_log(self, db, message, author): 
     508        fs.change_rev_prop(self.fs_ptr, self.rev, core.SVN_PROP_REVISION_LOG, message, self.pool()) 
     509        cursor = db.cursor() 
     510        cursor.execute("INSERT INTO log_change (rev,time,author,message) " 
     511                       "VALUES (%s,%s,%s,%s)", (str(self.rev), 
     512                       int(time.time()), author, self.message)) 
     513 
    507514    def _get_prop(self, name): 
    508         return fs.revision_prop(self.fs_ptr, self.rev, name, self.pool()) 
     515        return fs.revision_prop(self.fs_ptr, self.rev, name, self.pool()) 
     516 No newline at end of file 
  • trac/versioncontrol/web_ui/changeset.py

     
    7272            req.redirect(self.env.href.changeset(rev)) 
    7373 
    7474        chgset = repos.get_changeset(rev) 
    75         req.check_modified(chgset.date, 
     75        req.check_modified(chgset.last_modified(), 
    7676                           diff_options[0] + ''.join(diff_options[1])) 
    7777 
     78        action = req.args.get('action') 
     79 
     80        if req.method == 'POST': 
     81            # test for message change 
     82            if req.args.get('message') != chgset.message: 
     83                repos.change_log(rev, req.args.get('message'), util.get_reporter_id(req)) 
     84            req.redirect(self.env.href.changeset(rev)) 
     85 
    7886        format = req.args.get('format') 
    7987        if format == 'diff': 
    8088            self._render_diff(req, repos, chgset, diff_options) 
     
    155163            'revision': chgset.rev, 
    156164            'time': util.format_datetime(chgset.date), 
    157165            'author': util.escape(chgset.author or 'anonymous'), 
    158             'message': wiki_to_html(chgset.message or '--', self.env, req, 
    159                                     escape_newlines=True) 
     166            'message_html': wiki_to_html(chgset.message or '--', self.env, req, 
     167                                         escape_newlines=True), 
     168            'message': chgset.message or '--', 
     169            'href': self.env.href.changeset(chgset.rev) 
    160170        } 
    161171 
     172        action = req.args.get('action') 
     173        req.hdf['changeset.mode'] = action or 'view' 
     174 
     175        if action == 'edit': 
     176            rev = req.args.get('rev') 
     177            db = self.env.get_db_cnx() 
     178            cursor = db.cursor() 
     179            cursor.execute("SELECT time, author, message FROM log_change WHERE rev=%s", (rev,)) 
     180            rows = cursor.fetchall() or [] 
     181 
     182            # sort log message history by date (descending) 
     183            def cmp_func(a, b): 
     184                return cmp(b[0], a[0]) 
     185 
     186            rows.sort(cmp_func) 
     187 
     188            idx = 0 
     189            last_message = chgset.message 
     190            for date, author, msg in rows: 
     191                req.hdf['changeset.change.%d.time' % idx] = time.strftime('%x %X', time.localtime(date)) 
     192                req.hdf['changeset.change.%d.author' % idx] = author 
     193                req.hdf['changeset.change.%d.msg' % idx] = wiki_to_oneliner(util.shorten_line(last_message), self.env, db) 
     194                last_message = msg 
     195                idx = idx + 1 
     196            req.hdf['changeset.change.%d.time' % idx] = util.format_datetime(chgset.date) 
     197            req.hdf['changeset.change.%d.author' % idx] = chgset.author or 'anonymous' 
     198            req.hdf['changeset.change.%d.msg' % idx] = wiki_to_oneliner(util.shorten_line(last_message), self.env, db) 
     199 
    162200        oldest_rev = repos.oldest_rev 
    163201        if chgset.rev != oldest_rev: 
    164202            add_link(req, 'first', self.env.href.changeset(oldest_rev),