[gitg] Show parents for commits with more than one parent



commit 3242eeebba6264e59b12265c29a356c36606cd93
Author: Jesse van den Kieboom <jessevdk gmail com>
Date:   Sun Dec 14 20:16:00 2014 +0100

    Show parents for commits with more than one parent
    
    This adds links to the commit header for each parent allowing
    to quickly jump to a parent.

 gitg/history/gitg-history.vala           |   18 +++++++++++++
 libgitg-ext/gitg-ext-history.vala        |    2 +
 libgitg/gitg-commit-model.vala           |   28 +++++++++++++++++++++
 libgitg/gitg-diff-view-request-diff.vala |   18 +++++++++++++
 libgitg/gitg-diff-view.vala              |   13 ++++++++++
 libgitg/resources/diff-view.css          |   11 ++++++++
 libgitg/resources/diff-view.html         |    2 +
 libgitg/resources/diff-view.js           |   39 +++++++++++++++++++++++++++++-
 plugins/diff/gitg-diff.vala              |   17 +++++++++++++
 9 files changed, 147 insertions(+), 1 deletions(-)
---
diff --git a/gitg/history/gitg-history.vala b/gitg/history/gitg-history.vala
index 3b72922..d5edf88 100644
--- a/gitg/history/gitg-history.vala
+++ b/gitg/history/gitg-history.vala
@@ -94,6 +94,24 @@ namespace GitgHistory
                        });
                }
 
+               public void select(Gitg.Commit commit)
+               {
+                       var model = (Gitg.CommitModel)d_main.commit_list_view.model;
+                       var path = model.path_from_commit(commit);
+
+                       if (path != null)
+                       {
+                               var sel = d_main.commit_list_view.get_selection();
+                               sel.select_path(path);
+
+                               d_main.commit_list_view.scroll_to_cell(path, null, true, 0.5f, 0);
+                       }
+                       else
+                       {
+                               stderr.printf("Failed to lookup tree path for commit '%s'\n", 
commit.get_id().to_string());
+                       }
+               }
+
                construct
                {
                        d_settings = new Settings("org.gnome.gitg.preferences.history");
diff --git a/libgitg-ext/gitg-ext-history.vala b/libgitg-ext/gitg-ext-history.vala
index f95ad36..9e62d49 100644
--- a/libgitg-ext/gitg-ext-history.vala
+++ b/libgitg-ext/gitg-ext-history.vala
@@ -27,6 +27,8 @@ public interface History : Object, Activity
 
        public signal void selection_changed();
        public abstract void foreach_selected(ForeachCommitSelectionFunc func);
+
+  public abstract void select(Gitg.Commit commit);
 }
 
 }
diff --git a/libgitg/gitg-commit-model.vala b/libgitg/gitg-commit-model.vala
index 7cfcd05..ba88f30 100644
--- a/libgitg/gitg-commit-model.vala
+++ b/libgitg/gitg-commit-model.vala
@@ -72,6 +72,7 @@ namespace Gitg
                private uint d_idleid;
                private Lanes d_lanes;
                private Ggit.SortMode d_sortmode;
+               private Gee.HashMap<Ggit.OId, int> d_id_hash;
 
                private Ggit.OId[] d_include;
                private Ggit.OId[] d_exclude;
@@ -149,6 +150,8 @@ namespace Gitg
                        d_ids = new Commit[0];
                        d_advertized_size = 0;
 
+                       d_id_hash = new Gee.HashMap<Ggit.OId, int>();
+
                        emit_started();
                        finished();
                }
@@ -301,6 +304,11 @@ namespace Gitg
 
                                Timer timer = new Timer();
 
+                               lock(d_id_hash)
+                               {
+                                       d_id_hash = new Gee.HashMap<Ggit.OId, int>((i) => { return i.hash(); 
}, (a, b) => { return a.equal(b); });
+                               }
+
                                while (true)
                                {
                                        Ggit.OId? id;
@@ -323,6 +331,11 @@ namespace Gitg
                                                commit = d_repository.lookup<Commit>(id);
                                        } catch { break; }
 
+                                       lock(d_id_hash)
+                                       {
+                                               d_id_hash.set(id, d_ids.length);
+                                       }
+
                                        // Add the id
                                        if (d_ids.length == size)
                                        {
@@ -538,6 +551,21 @@ namespace Gitg
                        return this[idx];
                }
 
+               public Gtk.TreePath? path_from_commit(Commit commit)
+               {
+                       lock(d_id_hash)
+                       {
+                               var id = commit.get_id();
+
+                               if (!d_id_hash.has_key(id))
+                               {
+                                       return null;
+                               }
+
+                               return new Gtk.TreePath.from_indices(d_id_hash.get(commit.get_id()));
+                       }
+               }
+
                public Commit? commit_from_path(Gtk.TreePath path)
                {
                        int[] indices = path.get_indices();
diff --git a/libgitg/gitg-diff-view-request-diff.vala b/libgitg/gitg-diff-view-request-diff.vala
index 1cab3f9..dd0f492 100644
--- a/libgitg/gitg-diff-view-request-diff.vala
+++ b/libgitg/gitg-diff-view-request-diff.vala
@@ -240,6 +240,24 @@ namespace Gitg
                                builder.add_string_value(note.get_message());
                        }
 
+                       builder.set_member_name("parents");
+                       builder.begin_array();
+
+                       foreach (var parent in commit.get_parents())
+                       {
+                               builder.begin_object();
+
+                               builder.set_member_name("id");
+                               builder.add_string_value(parent.get_id().to_string());
+
+                               builder.set_member_name("subject");
+                               builder.add_string_value(parent.get_subject());
+
+                               builder.end_object();
+                       }
+
+                       builder.end_array();
+
                        builder.end_object();
                }
 
diff --git a/libgitg/gitg-diff-view.vala b/libgitg/gitg-diff-view.vala
index f2a7c81..be90c86 100644
--- a/libgitg/gitg-diff-view.vala
+++ b/libgitg/gitg-diff-view.vala
@@ -39,6 +39,9 @@ namespace Gitg
                                                case "loaded":
                                                        d_view.loaded();
                                                        break;
+                                               case "load-parent":
+                                                       d_view.load_parent(parameter("value"));
+                                                       break;
                                        }
 
                                        return false;
@@ -48,6 +51,8 @@ namespace Gitg
                        }
                }
 
+               public signal void request_select_commit(string id);
+
                private Ggit.Diff? d_diff;
                private Commit? d_commit;
                private Settings? d_fontsettings;
@@ -118,6 +123,7 @@ namespace Gitg
                public bool wrap { get; set; default = true; }
                public bool staged { get; set; default = false; }
                public bool unstaged { get; set; default = false; }
+               public bool show_parents { get; set; default = false; }
 
                int d_tab_width;
 
@@ -223,6 +229,7 @@ namespace Gitg
                        o.set_boolean_member("unstaged", unstaged);
                        o.set_boolean_member("debug", Environment.get_variable("GITG_GTK_DIFF_VIEW_DEBUG") != 
null);
                        o.set_boolean_member("changes_inline", changes_inline);
+                       o.set_boolean_member("show_parents", show_parents);
 
                        var strings = new Json.Object();
 
@@ -230,6 +237,7 @@ namespace Gitg
                        strings.set_string_member("unstage", _("unstage"));
                        strings.set_string_member("loading_diff", _("Loading diff…"));
                        strings.set_string_member("notes", _("Notes:"));
+                       strings.set_string_member("parents", _("Parents:"));
 
                        o.set_object_member("strings", strings);
 
@@ -527,6 +535,11 @@ namespace Gitg
                        }
                }
 
+               public void load_parent(string id)
+               {
+                       request_select_commit(id);
+               }
+
                private PatchSet parse_patchset(Json.Node node)
                {
                        PatchSet ret = new PatchSet();
diff --git a/libgitg/resources/diff-view.css b/libgitg/resources/diff-view.css
index 4aa34d4..c0afa13 100644
--- a/libgitg/resources/diff-view.css
+++ b/libgitg/resources/diff-view.css
@@ -48,6 +48,17 @@ img.avatar {
   min-height: 50px;
 }
 
+div.commit .parents .title {
+  font-weight: bold;
+}
+
+div.commit .parents ul {
+  list-style: none;
+  margin-top: 6px;
+  margin-left: 12px;
+  padding-left: 0px;
+}
+
 div.commit {
   padding: 10px;
   font-family: sans-serif;
diff --git a/libgitg/resources/diff-view.html b/libgitg/resources/diff-view.html
index 998f2fc..56492ea 100644
--- a/libgitg/resources/diff-view.html
+++ b/libgitg/resources/diff-view.html
@@ -45,6 +45,8 @@
             <span class="notes" data-id="notes"></span><br/>
             <span class="note_message" data-id="note_message"></span>
           </p>
+          <p class="parents" data-id="parents">
+          </p>
           <div class="sha1" data-id="sha1"></div>
         </div>
       </div>
diff --git a/libgitg/resources/diff-view.js b/libgitg/resources/diff-view.js
index 0972961..217f72a 100644
--- a/libgitg/resources/diff-view.js
+++ b/libgitg/resources/diff-view.js
@@ -21,11 +21,13 @@ var settings = {
        debug: false,
        staged: false,
        unstaged: false,
+       show_parents: false,
        strings: {
                stage: 'stage',
                unstage: 'unstage',
                loading_diff: 'Loading diff...',
-               notes: 'Notes:'
+               notes: 'Notes:',
+               parents: 'Parents:'
        },
 };
 
@@ -163,6 +165,41 @@ function write_commit(content, commit)
                elems.notes_container.hide();
        }
 
+       if (commit.parents.length > 1 && settings.show_parents)
+       {
+               var d = $('<div/>');
+
+               d.append($('<div/>', {'class': 'title'}).text(settings.strings.parents));
+
+               var ul = $('<ul/>');
+
+               for (var i = 0; i < commit.parents.length; i++)
+               {
+                       var parent = commit.parents[i];
+                       var li = $('<li/>');
+
+                       var a = $('<a/>', {'href': '#'}).text(parent.id.slice(0, 6) + ': ' + parent.subject);
+                       a.on('click', (function(id, e) {
+
+                               xhr_get('internal', {'action': 'load-parent', 'value': id});
+                               e.preventDefault();
+                               e.stopPropagation();
+                       }).bind(this, parent.id));
+
+                       li.append(a);
+                       ul.append(li);
+               }
+
+               d.append(ul);
+
+               elems.parents.html(d);
+               elems.parents.show();
+       }
+       else
+       {
+               elems.parents.hide();
+       }
+
        // Sha1
        elems.sha1.text(commit.id);
 
diff --git a/plugins/diff/gitg-diff.vala b/plugins/diff/gitg-diff.vala
index 68a0b57..3088d86 100644
--- a/plugins/diff/gitg-diff.vala
+++ b/plugins/diff/gitg-diff.vala
@@ -37,6 +37,7 @@ namespace GitgDiff
                        d_sw.show();
 
                        d_diff = new Gitg.DiffView();
+                       d_diff.show_parents = true;
 
                        var settings = new Settings("org.gnome.gitg.preferences.diff");
 
@@ -72,6 +73,22 @@ namespace GitgDiff
 
                        history.selection_changed.connect(on_selection_changed);
                        on_selection_changed(history);
+
+                       d_diff.request_select_commit.connect((id) => {
+                               Gitg.Commit commit;
+
+                               try
+                               {
+                                       commit = application.repository.lookup<Gitg.Commit>(new 
Ggit.OId.from_string(id));
+                               }
+                               catch (Error e)
+                               {
+                                       stderr.printf("Failed to lookup commit '%s': %s\n", id, e.message);
+                                       return;
+                               }
+
+                               history.select(commit);
+                       });
                }
 
                public string id


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]