From 2c9750cc8b902a55669183e05533207dd7ec71fd Mon Sep 17 00:00:00 2001 From: "Aneesh Kumar K.V" Date: Thu, 19 Apr 2007 22:26:03 +0530 Subject: [PATCH] gitview: annotation support List files modifed as a part of the commit in the diff window Support annotation of the file listed in the diff window Support history browsing in the annotation window. Signed-off-by: Aneesh Kumar K.V Signed-off-by: Junio C Hamano --- contrib/gitview/gitview | 260 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 256 insertions(+), 4 deletions(-) diff --git a/contrib/gitview/gitview b/contrib/gitview/gitview index 521b2fcd32..2d80e2bad2 100755 --- a/contrib/gitview/gitview +++ b/contrib/gitview/gitview @@ -10,7 +10,8 @@ GUI browser for git repository This program is based on bzrk by Scott James Remnant """ __copyright__ = "Copyright (C) 2006 Hewlett-Packard Development Company, L.P." -__author__ = "Aneesh Kumar K.V " +__copyright__ = "Copyright (C) 2007 Aneesh Kumar K.V 0): + # set at result_line + count-1 the sha1 as commit_sha1 + self.count = self.count - 1 + iter = self.model.iter_nth_child(None, self.result_line + self.count-1) + self.model.set(iter, 0, self.commit_sha1, 1, filename, 3, self.source_line) + + + def annotate(self, filename, commit_sha1, line_num): + # verify the commit_sha1 specified has this filename + + fp = os.popen("git ls-tree "+ commit_sha1 + " -- " + filename) + line = string.strip(fp.readline()) + if line == '': + # pop up the message the file is not there as a part of the commit + fp.close() + dialog = gtk.MessageDialog(parent=None, flags=0, + type=gtk.MESSAGE_WARNING, buttons=gtk.BUTTONS_CLOSE, + message_format=None) + dialog.set_markup("The file %s is not present in the parent commit %s" % (filename, commit_sha1)) + dialog.run() + dialog.destroy() + return + + fp.close() + + vpan = gtk.VPaned(); + self.window.add(vpan); + vpan.show() + + scrollwin = gtk.ScrolledWindow() + scrollwin.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) + scrollwin.set_shadow_type(gtk.SHADOW_IN) + vpan.pack1(scrollwin, True, True); + scrollwin.show() + + self.model = gtk.TreeStore(str, str, str, int) + self.treeview = gtk.TreeView(self.model) + self.treeview.set_rules_hint(True) + self.treeview.set_search_column(0) + self.treeview.connect("cursor-changed", self._treeview_cursor_cb) + self.treeview.connect("row-activated", self._treeview_row_activated) + scrollwin.add(self.treeview) + self.treeview.show() + + cell = gtk.CellRendererText() + cell.set_property("width-chars", 10) + cell.set_property("ellipsize", pango.ELLIPSIZE_END) + column = gtk.TreeViewColumn("Commit") + column.set_resizable(True) + column.pack_start(cell, expand=True) + column.add_attribute(cell, "text", 0) + self.treeview.append_column(column) + + cell = gtk.CellRendererText() + cell.set_property("width-chars", 20) + cell.set_property("ellipsize", pango.ELLIPSIZE_END) + column = gtk.TreeViewColumn("File Name") + column.set_resizable(True) + column.pack_start(cell, expand=True) + column.add_attribute(cell, "text", 1) + self.treeview.append_column(column) + + cell = gtk.CellRendererText() + cell.set_property("width-chars", 20) + cell.set_property("ellipsize", pango.ELLIPSIZE_END) + column = gtk.TreeViewColumn("Data") + column.set_resizable(True) + column.pack_start(cell, expand=True) + column.add_attribute(cell, "text", 2) + self.treeview.append_column(column) + + # The commit message window + scrollwin = gtk.ScrolledWindow() + scrollwin.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) + scrollwin.set_shadow_type(gtk.SHADOW_IN) + vpan.pack2(scrollwin, True, True); + scrollwin.show() + + commit_text = gtk.TextView() + self.commit_buffer = gtk.TextBuffer() + commit_text.set_buffer(self.commit_buffer) + scrollwin.add(commit_text) + commit_text.show() + + self.window.show() + + self.add_file_data(filename, commit_sha1, line_num) + + fp = os.popen("git blame --incremental -- " + filename + " " + commit_sha1) + flags = fcntl.fcntl(fp.fileno(), fcntl.F_GETFL) + fcntl.fcntl(fp.fileno(), fcntl.F_SETFL, flags | os.O_NONBLOCK) + self.io_watch_tag = gobject.io_add_watch(fp, gobject.IO_IN, self.data_ready) + + class DiffWindow: """Diff window. This object represents and manages a single window containing the @@ -355,6 +537,7 @@ class DiffWindow: height = int(monitor.height * 0.66) self.window.set_default_size(width, height) + self.construct() def construct(self): @@ -371,10 +554,12 @@ class DiffWindow: vbox.pack_start(menu_bar, expand=False, fill=True) menu_bar.show() + hpan = gtk.HPaned() + scrollwin = gtk.ScrolledWindow() scrollwin.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) scrollwin.set_shadow_type(gtk.SHADOW_IN) - vbox.pack_start(scrollwin, expand=True, fill=True) + hpan.pack1(scrollwin, True, True) scrollwin.show() if have_gtksourceview: @@ -388,11 +573,77 @@ class DiffWindow: self.buffer = gtk.TextBuffer() sourceview = gtk.TextView(self.buffer) + sourceview.set_editable(False) sourceview.modify_font(pango.FontDescription("Monospace")) scrollwin.add(sourceview) sourceview.show() + # The file hierarchy: a scrollable treeview + scrollwin = gtk.ScrolledWindow() + scrollwin.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) + scrollwin.set_shadow_type(gtk.SHADOW_IN) + scrollwin.set_size_request(20, -1) + hpan.pack2(scrollwin, True, True) + scrollwin.show() + + self.model = gtk.TreeStore(str, str, str) + self.treeview = gtk.TreeView(self.model) + self.treeview.set_search_column(1) + self.treeview.connect("cursor-changed", self._treeview_clicked) + scrollwin.add(self.treeview) + self.treeview.show() + + cell = gtk.CellRendererText() + cell.set_property("width-chars", 20) + column = gtk.TreeViewColumn("Select to annotate") + column.pack_start(cell, expand=True) + column.add_attribute(cell, "text", 0) + self.treeview.append_column(column) + + vbox.pack_start(hpan, expand=True, fill=True) + hpan.show() + + def _treeview_clicked(self, *args): + """Callback for when the treeview cursor changes.""" + (path, col) = self.treeview.get_cursor() + specific_file = self.model[path][1] + commit_sha1 = self.model[path][2] + if specific_file == None : + return + elif specific_file == "" : + specific_file = None + + window = AnnotateWindow(); + window.annotate(specific_file, commit_sha1, 1) + + + def commit_files(self, commit_sha1, parent_sha1): + self.model.clear() + add = self.model.append(None, [ "Added", None, None]) + dele = self.model.append(None, [ "Deleted", None, None]) + mod = self.model.append(None, [ "Modified", None, None]) + diff_tree = re.compile('^(:.{6}) (.{6}) (.{40}) (.{40}) (A|D|M)\s(.+)$') + fp = os.popen("git diff-tree -r --no-commit-id " + parent_sha1 + " " + commit_sha1) + while 1: + line = string.strip(fp.readline()) + if line == '': + break + m = diff_tree.match(line) + if not m: + continue + + attr = m.group(5) + filename = m.group(6) + if attr == "A": + self.model.append(add, [filename, filename, commit_sha1]) + elif attr == "D": + self.model.append(dele, [filename, filename, commit_sha1]) + elif attr == "M": + self.model.append(mod, [filename, filename, commit_sha1]) + fp.close() + + self.treeview.expand_all() def set_diff(self, commit_sha1, parent_sha1, encoding): """Set the differences showed by this window. @@ -406,6 +657,7 @@ class DiffWindow: fp = os.popen("git diff-tree -p " + parent_sha1 + " " + commit_sha1) self.buffer.set_text(unicode(fp.read(), encoding).encode('utf-8')) fp.close() + self.commit_files(commit_sha1, parent_sha1) self.window.show() def save_menu_response(self, widget, string): @@ -425,7 +677,7 @@ class DiffWindow: class GitView: """ This is the main class """ - version = "0.8" + version = "0.9" def __init__(self, with_diff=0): self.with_diff = with_diff @@ -590,7 +842,7 @@ class GitView: dialog = gtk.AboutDialog() dialog.set_name("Gitview") dialog.set_version(GitView.version) - dialog.set_authors(["Aneesh Kumar K.V "]) + dialog.set_authors(["Aneesh Kumar K.V "]) dialog.set_website("http://www.kernel.org/pub/software/scm/git/") dialog.set_copyright("Use and distribute under the terms of the GNU General Public License") dialog.set_wrap_license(True)