From c0cabc82f6149db2b8bc568b47d6b5a45e21c6f8 Mon Sep 17 00:00:00 2001 From: "James E. Blair" Date: Sun, 19 Apr 2015 14:34:48 -0400 Subject: [PATCH] Attach comments to files Since each revision now has files, associate comments with the file relation rather than revisions so that the path is not stored twice in the database. Also correct a problem where comments could be left on empty files or lines that are not in a file in the unified view. The SQLAlchemy constraints API seems to have changed between 0.9.9 and 1.0.4. Support both behaviors to be user-friendly even though we now specify 1.0.4. Change-Id: If6593d279a432ea8a48f4bd74a157e4978e69eaa --- .../254ac5fc3941_attach_comments_to_files.py | 64 +++++++++++++ gertty/db.py | 69 +++++++++----- gertty/dbsupport.py | 16 ++++ gertty/gitrepo.py | 19 +++- gertty/search/parser.py | 10 +- gertty/sync.py | 63 ++++++------ gertty/view/change.py | 6 +- gertty/view/diff.py | 95 +++++++++++++------ gertty/view/side_diff.py | 39 ++++---- gertty/view/unified_diff.py | 13 +-- 10 files changed, 277 insertions(+), 117 deletions(-) create mode 100644 gertty/alembic/versions/254ac5fc3941_attach_comments_to_files.py diff --git a/gertty/alembic/versions/254ac5fc3941_attach_comments_to_files.py b/gertty/alembic/versions/254ac5fc3941_attach_comments_to_files.py new file mode 100644 index 0000000..f807629 --- /dev/null +++ b/gertty/alembic/versions/254ac5fc3941_attach_comments_to_files.py @@ -0,0 +1,64 @@ +"""attach comments to files + +Revision ID: 254ac5fc3941 +Revises: 50344aecd1c2 +Create Date: 2015-04-13 15:52:07.104397 + +""" + +# revision identifiers, used by Alembic. +revision = '254ac5fc3941' +down_revision = '50344aecd1c2' + +import sys +import warnings + +from alembic import op +import sqlalchemy as sa + +from gertty.dbsupport import sqlite_alter_columns, sqlite_drop_columns + + +def upgrade(): + with warnings.catch_warnings(): + warnings.simplefilter("ignore") + op.add_column('comment', sa.Column('file_key', sa.Integer())) + sqlite_alter_columns('comment', [ + sa.Column('file_key', sa.Integer(), sa.ForeignKey('file.key')) + ]) + + update_query = sa.text('update comment set file_key=:file_key where key=:key') + file_query = sa.text('select f.key from file f where f.revision_key=:revision_key and f.path=:path') + + file_insert_query = sa.text('insert into file (key, revision_key, path, old_path, status, inserted, deleted) ' + ' values (NULL, :revision_key, :path, NULL, NULL, NULL, NULL)') + + conn = op.get_bind() + + countres = conn.execute('select count(*) from comment') + comments = countres.fetchone()[0] + + comment_res = conn.execute('select p.name, c.number, c.status, r.key, r.number, m.file, m.key ' + 'from project p, change c, revision r, comment m ' + 'where m.revision_key=r.key and r.change_key=c.key and ' + 'c.project_key=p.key order by p.name') + + count = 0 + for (pname, cnumber, cstatus, rkey, rnumber, mfile, mkey) in comment_res.fetchall(): + count += 1 + sys.stdout.write('Comment %s / %s\r' % (count, comments)) + sys.stdout.flush() + + file_res = conn.execute(file_query, revision_key=rkey, path=mfile) + file_key = file_res.fetchone() + if not file_key: + conn.execute(file_insert_query, revision_key=rkey, path=mfile) + file_res = conn.execute(file_query, revision_key=rkey, path=mfile) + file_key = file_res.fetchone() + fkey = file_key[0] + file_res = conn.execute(update_query, file_key=fkey, key=mkey) + sqlite_drop_columns('comment', ['revision_key', 'file']) + print + +def downgrade(): + pass diff --git a/gertty/db.py b/gertty/db.py index 418d45c..eb579db 100644 --- a/gertty/db.py +++ b/gertty/db.py @@ -95,12 +95,11 @@ message_table = Table( comment_table = Table( 'comment', metadata, Column('key', Integer, primary_key=True), - Column('revision_key', Integer, ForeignKey("revision.key"), index=True), + Column('file_key', Integer, ForeignKey("file.key"), index=True), Column('account_key', Integer, ForeignKey("account.key"), index=True), Column('id', String(255), index=True), #, unique=True, nullable=False), Column('in_reply_to', String(255)), Column('created', DateTime, index=True, nullable=False), - Column('file', Text, nullable=False), Column('parent', Boolean, nullable=False), Column('line', Integer), Column('message', Text, nullable=False), @@ -347,15 +346,6 @@ class Revision(object): session.flush() return m - def createComment(self, *args, **kw): - session = Session.object_session(self) - args = [self] + list(args) - c = Comment(*args, **kw) - self.comments.append(c) - session.add(c) - session.flush() - return c - def createPendingCherryPick(self, *args, **kw): session = Session.object_session(self) args = [self] + list(args) @@ -372,8 +362,17 @@ class Revision(object): self.files.append(f) session.add(f) session.flush() + if hasattr(self, '_file_cache'): + self._file_cache[f.path] = f return f + def getFile(self, path): + if not hasattr(self, '_file_cache'): + self._file_cache = {} + for f in self.files: + self._file_cache[f.path] = f + return self._file_cache.get(path, None) + def getPendingMessage(self): for m in self.messages: if m.pending: @@ -410,13 +409,12 @@ class Message(object): return author_name class Comment(object): - def __init__(self, revision, id, author, in_reply_to, created, file, parent, line, message, draft=False): - self.revision_key = revision.key + def __init__(self, file, id, author, in_reply_to, created, parent, line, message, draft=False): + self.file_key = file.key self.account_key = author.key self.id = id self.in_reply_to = in_reply_to self.created = created - self.file = file self.parent = parent self.line = line self.message = message @@ -489,7 +487,22 @@ class File(object): break post = ''.join(post) mid = '{%s => %s}' % (self.old_path[start:0-end+1], self.path[start:0-end+1]) - return pre + mid + post + if pre and post: + mid = '{%s => %s}' % (self.old_path[start:0-end+1], + self.path[start:0-end+1]) + return pre + mid + post + else: + return '%s => %s' % (self.old_path, self.path) + + def createComment(self, *args, **kw): + session = Session.object_session(self) + args = [self] + list(args) + c = Comment(*args, **kw) + self.comments.append(c) + session.add(c) + session.flush() + return c + mapper(Account, account_table) mapper(Project, project_table, properties=dict( @@ -535,20 +548,22 @@ mapper(Change, change_table, properties=dict( )) mapper(Revision, revision_table, properties=dict( messages=relationship(Message, backref='revision'), - comments=relationship(Comment, backref='revision', - order_by=(comment_table.c.line, - comment_table.c.created)), - draft_comments=relationship(Comment, - primaryjoin=and_(revision_table.c.key==comment_table.c.revision_key, - comment_table.c.draft==True), - order_by=(comment_table.c.line, - comment_table.c.created)), files=relationship(File, backref='revision'), pending_cherry_picks=relationship(PendingCherryPick, backref='revision'), )) mapper(Message, message_table, properties=dict( author=relationship(Account))) -mapper(File, file_table) +mapper(File, file_table, properties=dict( + comments=relationship(Comment, backref='file', + order_by=(comment_table.c.line, + comment_table.c.created)), + draft_comments=relationship(Comment, + primaryjoin=and_(file_table.c.key==comment_table.c.file_key, + comment_table.c.draft==True), + order_by=(comment_table.c.line, + comment_table.c.created)), + )) + mapper(Comment, comment_table, properties=dict( author=relationship(Account))) mapper(Label, label_table) @@ -748,6 +763,12 @@ class DatabaseSession(object): except sqlalchemy.orm.exc.NoResultFound: return None + def getFile(self, key): + try: + return self.session().query(File).filter_by(key=key).one() + except sqlalchemy.orm.exc.NoResultFound: + return None + def getComment(self, key): try: return self.session().query(Comment).filter_by(key=key).one() diff --git a/gertty/dbsupport.py b/gertty/dbsupport.py index 45182af..ff94b28 100644 --- a/gertty/dbsupport.py +++ b/gertty/dbsupport.py @@ -133,6 +133,22 @@ def sqlite_drop_columns(table_name, drop_columns): new_columns.append(col_copy) for key in meta.tables[table_name].foreign_keys: + # If this is a single column constraint for a dropped column, + # don't copy it. + if isinstance(key.constraint.columns, sqlalchemy.sql.base.ColumnCollection): + # This is needed for SQLAlchemy >= 1.0.4 + columns = [c.name for c in key.constraint.columns] + else: + # This is needed for SQLAlchemy <= 0.9.9. This is + # backwards compat code just in case someone updates + # Gertty without updating SQLAlchemy. This is simple + # enough to check and will hopefully avoid leaving the + # user's db in an inconsistent state. Remove this after + # Gertty 1.2.0. + columns = key.constraint.columns + if (len(columns)==1 and columns[0] in drop_columns): + continue + # Otherwise, recreate the constraint. constraint = key.constraint con_copy = constraint.copy() new_columns.append(con_copy) diff --git a/gertty/gitrepo.py b/gertty/gitrepo.py index 3599db3..c11474e 100644 --- a/gertty/gitrepo.py +++ b/gertty/gitrepo.py @@ -170,6 +170,8 @@ class DiffFile(object): def __init__(self): self.newname = 'Unknown File' self.oldname = 'Unknown File' + self.old_empty = False + self.new_empty = False self.chunks = [] self.current_chunk = None self.old_lineno = 0 @@ -389,8 +391,10 @@ class Repo(object): # f.newname = diff_context.b_path if diff_context.new_file: f.oldname = 'Empty file' + f.old_empty = True if diff_context.deleted_file: f.newname = 'Empty file' + f.new_empty = True files.append(f) if diff_context.rename_from: f.oldname = diff_context.rename_from @@ -468,6 +472,16 @@ class Repo(object): continue if not last_line: raise Exception("Unhandled line: %s" % line) + if not diff_context.diff: + # There is no diff, possibly because this is simply a + # rename. Include context lines so that comments may + # appear. + newc = repo.commit(new) + blob = newc.tree[f.newname] + f.old_lineno = 1 + f.new_lineno = 1 + for line in blob.data_stream.read().splitlines(): + f.addContextLine(line) f.finalize() return files @@ -479,7 +493,10 @@ class Repo(object): f.new_lineno = 1 repo = git.Repo(self.path) newc = repo.commit(new) - blob = newc.tree[path] + try: + blob = newc.tree[path] + except KeyError: + return None for line in blob.data_stream.read().splitlines(): f.addContextLine(line) f.finalize() diff --git a/gertty/search/parser.py b/gertty/search/parser.py index d2e4600..9548908 100644 --- a/gertty/search/parser.py +++ b/gertty/search/parser.py @@ -298,11 +298,13 @@ def SearchParser(): def p_file_term(p): '''file_term : OP_FILE string''' if p[2].startswith('^'): - p[0] = or_(func.matches(p[2], gertty.db.file_table.c.path), - func.matches(p[2], gertty.db.file_table.c.old_path)) + p[0] = and_(or_(func.matches(p[2], gertty.db.file_table.c.path), + func.matches(p[2], gertty.db.file_table.c.old_path)), + gertty.db.file_table.c.status is not None) else: - p[0] = or_(gertty.db.file_table.c.path == p[2], - gertty.db.file_table.c.old_path == p[2]) + p[0] = and_(or_(gertty.db.file_table.c.path == p[2], + gertty.db.file_table.c.old_path == p[2]), + gertty.db.file_table.c.status is not None) def p_status_term(p): '''status_term : OP_STATUS string''' diff --git a/gertty/sync.py b/gertty/sync.py index 63d6c24..ae22849 100644 --- a/gertty/sync.py +++ b/gertty/sync.py @@ -618,16 +618,21 @@ class SyncChangeTask(Task): parent_commits.add(revision.parent) result.updateRelatedChanges(session, change) - filemap = {} + f = revision.getFile('/COMMIT_MSG') + if f is None: + f = revision.createFile('/COMMIT_MSG', None, + None, None, None) for remote_path, remote_file in remote_revision['files'].items(): - if remote_file.get('binary'): - inserted = deleted = None - else: - inserted = remote_file.get('lines_inserted', 0) - deleted = remote_file.get('lines_deleted', 0) - f = revision.createFile(remote_path, remote_file.get('status', 'M'), - remote_file.get('old_path'), inserted, deleted) - filemap[remote_path] = f + f = revision.getFile(remote_path) + if f is None: + if remote_file.get('binary'): + inserted = deleted = None + else: + inserted = remote_file.get('lines_inserted', 0) + deleted = remote_file.get('lines_deleted', 0) + f = revision.createFile(remote_path, remote_file.get('status', 'M'), + remote_file.get('old_path'), + inserted, deleted) remote_comments_data = remote_revision['_gertty_remote_comments_data'] for remote_file, remote_comments in remote_comments_data.items(): @@ -643,11 +648,12 @@ class SyncChangeTask(Task): parent = False if remote_comment.get('side', '') == 'PARENT': parent = True - comment = revision.createComment(remote_comment['id'], account, - remote_comment.get('in_reply_to'), - created, - remote_file, parent, remote_comment.get('line'), - remote_comment['message']) + fileobj = revision.getFile(remote_file) + comment = fileobj.createComment(remote_comment['id'], account, + remote_comment.get('in_reply_to'), + created, + parent, remote_comment.get('line'), + remote_comment['message']) self.log.info("Created new comment %s for revision %s in local DB.", comment.key, revision.key) else: @@ -1124,21 +1130,20 @@ class UploadReviewTask(Task): for approval in change.draft_approvals: data['labels'][approval.category] = approval.value session.delete(approval) - if revision.draft_comments: - data['comments'] = {} - last_file = None - comment_list = [] - for comment in revision.draft_comments: - if comment.file != last_file: - last_file = comment.file - comment_list = [] - data['comments'][comment.file] = comment_list - d = dict(line=comment.line, - message=comment.message) - if comment.parent: - d['side'] = 'PARENT' - comment_list.append(d) - session.delete(comment) + comments = {} + for file in revision.files: + if file.draft_comments: + comment_list = [] + for comment in file.draft_comments: + d = dict(line=comment.line, + message=comment.message) + if comment.parent: + d['side'] = 'PARENT' + comment_list.append(d) + session.delete(comment) + comments[file.path] = comment_list + if comments: + data['comments'] = comments session.delete(message) # Inside db session for rollback sync.post('changes/%s/revisions/%s/review' % (change.id, revision.commit), diff --git a/gertty/view/change.py b/gertty/view/change.py index 31fe316..659714f 100644 --- a/gertty/view/change.py +++ b/gertty/view/change.py @@ -237,6 +237,8 @@ class RevisionRow(urwid.WidgetWrap): total_added = 0 total_removed = 0 for rfile in revision.files: + if rfile.status is None: + continue added = rfile.inserted or 0 removed = rfile.deleted or 0 total_added += added @@ -279,13 +281,13 @@ class RevisionRow(urwid.WidgetWrap): def update(self, revision): line = [('revision-name', 'Patch Set %s ' % revision.number), ('revision-commit', revision.commit)] - num_drafts = len(revision.draft_comments) + num_drafts = sum([len(f.draft_comments) for f in revision.files]) if num_drafts: pending_message = revision.getPendingMessage() if not pending_message: line.append(('revision-drafts', ' (%s draft%s)' % ( num_drafts, num_drafts>1 and 's' or ''))) - num_comments = len(revision.comments) - num_drafts + num_comments = sum([len(f.comments) for f in revision.files]) - num_drafts if num_comments: line.append(('revision-comments', ' (%s inline comment%s)' % ( num_comments, num_comments>1 and 's' or ''))) diff --git a/gertty/view/diff.py b/gertty/view/diff.py index 4b792ff..21e9b64 100644 --- a/gertty/view/diff.py +++ b/gertty/view/diff.py @@ -84,17 +84,16 @@ class PatchsetDialog(urwid.WidgetWrap): return old, new class LineContext(object): - def __init__(self, old_revision_key, new_revision_key, - old_revision_num, new_revision_num, - old_fn, new_fn, old_ln, new_ln): - self.old_revision_key = old_revision_key - self.new_revision_key = new_revision_key - self.old_revision_num = old_revision_num - self.new_revision_num = new_revision_num + def __init__(self, old_file_key, new_file_key, + old_fn, new_fn, old_ln, new_ln, + header=False): + self.old_file_key = old_file_key + self.new_file_key = new_file_key self.old_fn = old_fn self.new_fn = new_fn self.old_ln = old_ln self.new_ln = new_ln + self.header = header class BaseDiffCommentEdit(urwid.Columns): pass @@ -172,20 +171,33 @@ class BaseDiffView(urwid.WidgetWrap): del self._w.contents[:] with self.app.db.getSession() as session: new_revision = session.getRevision(self.new_revision_key) + old_comments = [] + new_comments = [] + self.old_file_keys = {} + self.new_file_keys = {} if self.old_revision_key is not None: old_revision = session.getRevision(self.old_revision_key) self.old_revision_num = old_revision.number old_str = 'patchset %s' % self.old_revision_num self.base_commit = old_revision.commit - old_comments = old_revision.comments + for f in old_revision.files: + old_comments += f.comments + self.old_file_keys[f.path] = f.key show_old_commit = True else: old_revision = None self.old_revision_num = None old_str = 'base' self.base_commit = new_revision.parent - old_comments = [] show_old_commit = False + # The old files are the same as the new files since we + # are diffing from base -> change, however, we should + # use the old file names for file lookup. + for f in new_revision.files: + if f.old_path: + self.old_file_keys[f.old_path] = f.key + else: + self.old_file_keys[f.path] = f.key self.title = u'Diff of %s change %s from %s to patchset %s' % ( new_revision.change.project.name, new_revision.change.number, @@ -194,19 +206,25 @@ class BaseDiffView(urwid.WidgetWrap): self.change_key = new_revision.change.key self.project_name = new_revision.change.project.name self.commit = new_revision.commit + for f in new_revision.files: + new_comments += f.comments + self.new_file_keys[f.path] = f.key comment_lists = {} comment_filenames = set() - for comment in new_revision.comments: + for comment in new_comments: + path = comment.file.path if comment.parent: if old_revision: # we're not looking at the base continue key = 'old' + if comment.file.old_path: + path = comment.file.old_path else: key = 'new' if comment.draft: key += 'draft' key += '-' + str(comment.line) - key += '-' + str(comment.file) + key += '-' + path comment_list = comment_lists.get(key, []) if comment.draft: message = comment.message @@ -215,15 +233,16 @@ class BaseDiffView(urwid.WidgetWrap): ('comment', u': '+comment.message)] comment_list.append((comment.key, message)) comment_lists[key] = comment_list - comment_filenames.add(comment.file) + comment_filenames.add(path) for comment in old_comments: if comment.parent: continue + path = comment.file.path key = 'old' if comment.draft: key += 'draft' key += '-' + str(comment.line) - key += '-' + str(comment.file) + key += '-' + path comment_list = comment_lists.get(key, []) if comment.draft: message = comment.message @@ -232,7 +251,7 @@ class BaseDiffView(urwid.WidgetWrap): ('comment', u': '+comment.message)] comment_list.append((comment.key, message)) comment_lists[key] = comment_list - comment_filenames.add(comment.file) + comment_filenames.add(path) repo = self.app.getRepo(self.project_name) self._w.contents.append((self.app.header, ('pack', 1))) self.file_reminder = self.makeFileReminder() @@ -250,7 +269,10 @@ class BaseDiffView(urwid.WidgetWrap): # that contain the full text. for filename in comment_filenames: diff = repo.getFile(self.base_commit, self.commit, filename) - diffs.append(diff) + if diff: + diffs.append(diff) + else: + self.log.debug("Unable to find file %s in commit %s" % (filename, self.commit)) for i, diff in enumerate(diffs): if i > 0: lines.append(urwid.Text('')) @@ -297,6 +319,11 @@ class BaseDiffView(urwid.WidgetWrap): oldnew = gitrepo.OLD else: oldnew = gitrepo.NEW + file_diffs = self.file_diffs[oldnew] + if path not in file_diffs: + self.log.error("Unable to display comment: %s" % key) + del comment_lists[key] + continue diff = self.file_diffs[oldnew][path] for chunk in diff.chunks: if (chunk.range[oldnew][gitrepo.START] <= lineno and @@ -341,6 +368,21 @@ class BaseDiffView(urwid.WidgetWrap): else: chunk.button.update() + def makeContext(self, diff, old_ln, new_ln, header=False): + old_key = None + new_key = None + if not diff.old_empty: + if diff.oldname in self.old_file_keys: + old_key = self.old_file_keys[diff.oldname] + elif diff.newname in self.old_file_keys: + old_key = self.old_file_keys[diff.newname] + if not diff.new_empty: + new_key = self.new_file_keys[diff.newname] + return LineContext( + old_key, new_key, + diff.oldname, diff.newname, + old_ln, new_ln, header) + def makeLines(self, diff, lines_to_add, comment_lists): raise NotImplementedError @@ -431,28 +473,25 @@ class BaseDiffView(urwid.WidgetWrap): session.delete(comment) def saveComment(self, context, text, new=True): - if (not new) and (not context.old_revision_num): + if (not new) and (not self.old_revision_num): parent = True - revision_key = context.new_revision_key else: parent = False - if new: - revision_key = context.new_revision_key - else: - revision_key = context.old_revision_key if new: line_num = context.new_ln - filename = context.new_fn + file_key = context.new_file_key else: line_num = context.old_ln - filename = context.old_fn + file_key = context.old_file_key + if file_key is None: + raise Exception("Comment is not associated with a file") with self.app.db.getSession() as session: - revision = session.getRevision(revision_key) + fileojb = session.getFile(file_key) account = session.getAccountByUsername(self.app.config.username) - comment = revision.createComment(None, account, None, - datetime.datetime.utcnow(), - filename, parent, - line_num, text, draft=True) + comment = fileojb.createComment(None, account, None, + datetime.datetime.utcnow(), + parent, + line_num, text, draft=True) key = comment.key return key diff --git a/gertty/view/side_diff.py b/gertty/view/side_diff.py index 493f65c..cb56985 100644 --- a/gertty/view/side_diff.py +++ b/gertty/view/side_diff.py @@ -17,7 +17,6 @@ import urwid from gertty import keymap from gertty.view.diff import BaseDiffComment, BaseDiffCommentEdit, BaseDiffLine from gertty.view.diff import BaseFileHeader, BaseFileReminder, BaseDiffView -from gertty.view.diff import LineContext LN_COL_WIDTH = 5 @@ -32,20 +31,32 @@ class SideDiffCommentEdit(BaseDiffCommentEdit): self.old = urwid.Edit(edit_text=old, multiline=True) self.new = urwid.Edit(edit_text=new, multiline=True) self.contents.append((urwid.Text(u''), ('given', LN_COL_WIDTH, False))) - self.contents.append((urwid.AttrMap(self.old, 'draft-comment'), ('weight', 1, False))) + if context.old_ln is not None or context.header: + self.contents.append((urwid.AttrMap(self.old, 'draft-comment'), ('weight', 1, False))) + else: + self.contents.append((urwid.Text(u''), ('weight', 1, False))) self.contents.append((urwid.Text(u''), ('given', LN_COL_WIDTH, False))) - self.contents.append((urwid.AttrMap(self.new, 'draft-comment'), ('weight', 1, False))) - self.focus_position = 3 + if context.new_ln is not None or context.header: + self.contents.append((urwid.AttrMap(self.new, 'draft-comment'), ('weight', 1, False))) + else: + self.contents.append((urwid.Text(u''), ('weight', 1, False))) + if context.new_ln is not None or context.header: + self.focus_position = 3 + else: + self.focus_position = 1 def keypress(self, size, key): r = super(SideDiffCommentEdit, self).keypress(size, key) commands = self.app.config.keymap.getCommands(r) if ((keymap.NEXT_SELECTABLE in commands) or (keymap.PREV_SELECTABLE in commands)): - if self.focus_position == 3: - self.focus_position = 1 - else: - self.focus_position = 3 + if ((self.context.old_ln is not None and + self.context.new_ln is not None) or + self.context.header): + if self.focus_position == 3: + self.focus_position = 1 + else: + self.focus_position = 3 return None return r @@ -117,11 +128,7 @@ class SideDiffView(BaseDiffView): def makeLines(self, diff, lines_to_add, comment_lists): lines = [] for old, new in lines_to_add: - context = LineContext( - self.old_revision_key, self.new_revision_key, - self.old_revision_num, self.new_revision_num, - diff.oldname, diff.newname, - old[0], new[0]) + context = self.makeContext(diff, old[0], new[0]) lines.append(SideDiffLine(self.app, context, old, new, callback=self.onSelect)) # see if there are any comments for this line @@ -159,11 +166,7 @@ class SideDiffView(BaseDiffView): return SideFileReminder() def makeFileHeader(self, diff, comment_lists): - context = LineContext( - self.old_revision_key, self.new_revision_key, - self.old_revision_num, self.new_revision_num, - diff.oldname, diff.newname, - None, None) + context = self.makeContext(diff, None, None, header=True) lines = [] lines.append(SideFileHeader(self.app, context, diff.oldname, diff.newname, callback=self.onSelect)) diff --git a/gertty/view/unified_diff.py b/gertty/view/unified_diff.py index 714a30a..5c00f79 100644 --- a/gertty/view/unified_diff.py +++ b/gertty/view/unified_diff.py @@ -18,7 +18,6 @@ import urwid from gertty import gitrepo from gertty.view.diff import BaseDiffCommentEdit, BaseDiffComment, BaseDiffLine from gertty.view.diff import BaseFileHeader, BaseFileReminder, BaseDiffView -from gertty.view.diff import LineContext LN_COL_WIDTH = 5 @@ -121,11 +120,7 @@ class UnifiedDiffView(BaseDiffView): def makeLines(self, diff, lines_to_add, comment_lists): lines = [] for old, new in lines_to_add: - context = LineContext( - self.old_revision_key, self.new_revision_key, - self.old_revision_num, self.new_revision_num, - diff.oldname, diff.newname, - old[0], new[0]) + context = self.makeContext(diff, old[0], new[0]) if context.old_ln is not None: lines.append(UnifiedDiffLine(self.app, context, gitrepo.OLD, old, new, callback=self.onSelect)) @@ -169,11 +164,7 @@ class UnifiedDiffView(BaseDiffView): return UnifiedFileReminder() def makeFileHeader(self, diff, comment_lists): - context = LineContext( - self.old_revision_key, self.new_revision_key, - self.old_revision_num, self.new_revision_num, - diff.oldname, diff.newname, - None, None) + context = self.makeContext(diff, None, None, header=True) lines = [] lines.append(UnifiedFileHeader(self.app, context, gitrepo.OLD, diff.oldname, diff.newname,