[anjuta] git: Support viewing the log of any branch, not just the currently active one
- From: James Liggett <jrliggett src gnome org>
- To: svn-commits-list gnome org
- Subject: [anjuta] git: Support viewing the log of any branch, not just the currently active one
- Date: Sun, 24 May 2009 03:35:41 -0400 (EDT)
commit 2d608c2db2b81ff7a689eb784ab7124490851241
Author: James Liggett <jrliggett cox net>
Date: Sat May 23 22:04:23 2009 -0700
git: Support viewing the log of any branch, not just the currently active one
---
plugins/git/anjuta-git.ui | 46 +++++++++-
plugins/git/git-log-command.c | 8 ++-
plugins/git/git-log-command.h | 1 +
plugins/git/git-log-dialog.c | 213 ++++++++++++++++++++++++++++++++++++++++-
plugins/git/git-log-dialog.h | 2 +
plugins/git/plugin.c | 3 +
plugins/git/plugin.h | 1 +
7 files changed, 269 insertions(+), 5 deletions(-)
diff --git a/plugins/git/anjuta-git.ui b/plugins/git/anjuta-git.ui
index 2124c4b..3f3541a 100644
--- a/plugins/git/anjuta-git.ui
+++ b/plugins/git/anjuta-git.ui
@@ -1975,6 +1975,48 @@
</packing>
</child>
<child>
+ <object class="GtkFrame" id="frame1">
+ <property name="visible">True</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <object class="GtkAlignment" id="alignment1">
+ <property name="visible">True</property>
+ <property name="left_padding">12</property>
+ <child>
+ <object class="GtkComboBox" id="log_branch_combo">
+ <property name="visible">True</property>
+ <property name="model">log_branch_combo_model</property>
+ <child>
+ <object class="GtkCellRendererPixbuf" id="log_branch_combo_active_icon"/>
+ <attributes>
+ <attribute name="stock-id">0</attribute>
+ </attributes>
+ </child>
+ <child>
+ <object class="GtkCellRendererText" id="log_branch_combo_name"/>
+ <attributes>
+ <attribute name="text">1</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes"><b>Branch:</b></property>
+ <property name="use_markup">True</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
<object class="GtkExpander" id="expander1">
<property name="visible">True</property>
<property name="can_focus">True</property>
@@ -2239,7 +2281,7 @@
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
- <property name="position">1</property>
+ <property name="position">2</property>
</packing>
</child>
<child>
@@ -2326,7 +2368,7 @@
</child>
</object>
<packing>
- <property name="position">2</property>
+ <property name="position">3</property>
</packing>
</child>
</object>
diff --git a/plugins/git/git-log-command.c b/plugins/git/git-log-command.c
index 5f97df0..0513933 100644
--- a/plugins/git/git-log-command.c
+++ b/plugins/git/git-log-command.c
@@ -40,6 +40,7 @@ struct _GitLogCommandPriv
GRegex *author_regex;
GRegex *time_regex;
GRegex *short_log_regex;
+ gchar *branch;
gchar *path;
/* Filters */
@@ -89,6 +90,7 @@ git_log_command_finalize (GObject *object)
g_regex_unref (self->priv->author_regex);
g_regex_unref (self->priv->time_regex);
g_regex_unref (self->priv->short_log_regex);
+ g_free (self->priv->branch);
g_free (self->priv->path);
g_free (self->priv->author);
@@ -164,6 +166,9 @@ git_log_command_run (AnjutaCommand *command)
g_string_free (commit_range, TRUE);
}
+
+ if (self->priv->branch)
+ git_command_add_arg (GIT_COMMAND (command), self->priv->branch);
else
git_command_add_arg (GIT_COMMAND (command), "HEAD");
@@ -285,7 +290,7 @@ git_log_command_class_init (GitLogCommandClass *klass)
GitLogCommand *
git_log_command_new (const gchar *working_directory,
- const gchar *path,
+ const gchar *branch, const gchar *path,
const gchar *author, const gchar *grep,
const gchar *since_date, const gchar *until_date,
const gchar *since_commit,
@@ -300,6 +305,7 @@ git_log_command_new (const gchar *working_directory,
self->priv->author = g_strdup (author);
self->priv->path = g_strdup (path);
+ self->priv->branch = g_strdup (branch);
self->priv->grep = g_strdup (grep);
self->priv->since_date = g_strdup (since_date);
self->priv->until_date = g_strdup (until_date);
diff --git a/plugins/git/git-log-command.h b/plugins/git/git-log-command.h
index e4d20a0..5d80600 100644
--- a/plugins/git/git-log-command.h
+++ b/plugins/git/git-log-command.h
@@ -57,6 +57,7 @@ struct _GitLogCommand
GType git_log_command_get_type (void) G_GNUC_CONST;
GitLogCommand *git_log_command_new (const gchar *working_directory,
+ const gchar *branch,
const gchar *path,
const gchar *author,
const gchar *grep,
diff --git a/plugins/git/git-log-dialog.c b/plugins/git/git-log-dialog.c
index e92b91b..12fdf08 100644
--- a/plugins/git/git-log-dialog.c
+++ b/plugins/git/git-log-dialog.c
@@ -242,6 +242,10 @@ on_ref_command_finished (AnjutaCommand *command, guint return_code,
{
gchar *path;
const gchar *relative_path;
+ GtkWidget *log_branch_combo;
+ GtkTreeModel *log_branch_combo_model;
+ GtkTreeIter iter;
+ gchar *branch;
GtkWidget *log_changes_view;
GtkTreeViewColumn *graph_column;
gchar *author;
@@ -274,8 +278,15 @@ on_ref_command_finished (AnjutaCommand *command, guint return_code,
* file or folder, hide the graph column, because we can't be assured that
* the graph will be correct in these cases */
log_changes_view = GTK_WIDGET (gtk_builder_get_object (data->bxml, "log_changes_view"));
+ log_branch_combo_model = GTK_TREE_MODEL (gtk_builder_get_object (data->bxml,
+ "log_branch_combo_model"));
+ log_branch_combo = GTK_WIDGET (gtk_builder_get_object (data->bxml,
+ "log_branch_combo"));
graph_column = gtk_tree_view_get_column (GTK_TREE_VIEW (log_changes_view),
1);
+
+ gtk_combo_box_get_active_iter (GTK_COMBO_BOX (log_branch_combo), &iter);
+ gtk_tree_model_get (log_branch_combo_model, &iter, 1, &branch, -1);
if (g_hash_table_size (data->filters) > 0 || path)
gtk_tree_view_column_set_visible (graph_column, FALSE);
@@ -295,7 +306,7 @@ on_ref_command_finished (AnjutaCommand *command, guint return_code,
data->refs = git_ref_command_get_refs (GIT_REF_COMMAND (command));
log_command = git_log_command_new (data->plugin->project_root_directory,
- relative_path,
+ branch, relative_path,
author, grep, since_date, until_date,
since_commit, until_commit);
@@ -792,11 +803,117 @@ setup_filters (LogData *data)
data);
}
+static void
+on_log_list_branch_command_data_arrived (AnjutaCommand *command,
+ GtkBuilder *bxml)
+{
+ GtkListStore *log_branch_combo_model;
+ GtkComboBox *log_branch_combo;
+ GHashTable *branches_table;
+ GQueue *output_queue;
+ GitBranch *branch;
+ GtkTreeIter iter;
+ gchar *name;
+
+ log_branch_combo_model = GTK_LIST_STORE (gtk_builder_get_object (bxml,
+ "log_branch_combo_model"));
+ log_branch_combo = GTK_COMBO_BOX (gtk_builder_get_object (bxml,
+ "log_branch_combo"));
+ branches_table = g_object_get_data (G_OBJECT (log_branch_combo),
+ "branches-table");
+ output_queue = git_branch_list_command_get_output (GIT_BRANCH_LIST_COMMAND (command));
+
+ while (g_queue_peek_head (output_queue))
+ {
+ branch = g_queue_pop_head (output_queue);
+ name = git_branch_get_name (branch);
+
+ gtk_list_store_append (log_branch_combo_model, &iter);
+
+ if (git_branch_is_active (branch))
+ {
+ gtk_list_store_set (log_branch_combo_model, &iter, 0,
+ GTK_STOCK_APPLY, -1);
+ gtk_combo_box_set_active_iter (log_branch_combo, &iter);
+ }
+
+ gtk_list_store_set (log_branch_combo_model, &iter, 1, name, -1);
+ g_hash_table_insert (branches_table, g_strdup (name),
+ g_memdup (&iter, sizeof (GtkTreeIter)));
+
+ g_object_unref (branch);
+ g_free (name);
+ }
+}
+
+static void
+on_log_list_branch_command_finished (AnjutaCommand *command, guint return_code,
+ GtkBuilder *bxml)
+{
+ GtkComboBox *log_branch_combo;
+ GHashTable *branches_table;
+ gchar *selected_branch;
+ GtkTreeIter *iter;
+
+ log_branch_combo = GTK_COMBO_BOX (gtk_builder_get_object (bxml,
+ "log_branch_combo"));
+ branches_table = g_object_get_data (G_OBJECT (log_branch_combo),
+ "branches-table");
+ selected_branch = g_object_get_data (G_OBJECT (log_branch_combo),
+ "selected-branch");
+
+ if (selected_branch)
+ {
+ if (g_hash_table_lookup_extended (branches_table, selected_branch, NULL,
+ (gpointer *) &iter))
+ {
+ gtk_combo_box_set_active_iter (log_branch_combo, iter);
+ }
+ }
+
+ g_object_set_data (G_OBJECT (log_branch_combo), "being-refreshed",
+ GINT_TO_POINTER (FALSE));
+
+ g_object_unref (command);
+
+}
+
+static void
+on_log_branch_combo_changed (GtkComboBox *combo_box, gpointer user_data)
+{
+ GtkTreeModel *log_branch_combo_model;
+ gchar *branch;
+ GtkTreeIter iter;
+
+ log_branch_combo_model = gtk_combo_box_get_model (combo_box);
+
+ if (gtk_combo_box_get_active_iter (combo_box, &iter))
+ {
+ gtk_tree_model_get (log_branch_combo_model, &iter, 1, &branch, -1);
+
+ g_object_set_data_full (G_OBJECT (combo_box), "selected-branch",
+ branch, (GDestroyNotify) g_free);
+ }
+}
+
+static void
+on_log_refresh_monitor_changed (GFileMonitor *file_monitor, GFile *file,
+ GFile *other_file, GFileMonitorEvent event_type,
+ Git *plugin)
+{
+ if (event_type == G_FILE_MONITOR_EVENT_CREATED ||
+ event_type == G_FILE_MONITOR_EVENT_DELETED)
+ {
+ git_log_refresh_branches (plugin);
+ }
+}
+
+
GtkWidget *
git_log_window_create (Git *plugin)
{
LogData *data;
- gchar *objects[] = {"log_window", NULL};
+ gchar *objects[] = {"log_window", "log_branch_combo_model", NULL};
GError *error;
GtkWidget *log_window;
GtkWidget *log_vbox;
@@ -806,6 +923,7 @@ git_log_window_create (Git *plugin)
GtkWidget *log_whole_project_check;
GtkWidget *log_path_entry;
GtkWidget *log_path_entry_hbox;
+ GtkWidget *log_branch_combo;
GtkTreeSelection *selection;
data = g_new0 (LogData, 1);
@@ -837,6 +955,8 @@ git_log_window_create (Git *plugin)
"log_path_entry"));
log_path_entry_hbox = GTK_WIDGET (gtk_builder_get_object (data->bxml,
"log_path_entry_hbox"));
+ log_branch_combo = GTK_WIDGET (gtk_builder_get_object (data->bxml,
+ "log_branch_combo"));
g_object_set_data (G_OBJECT (log_vbox), "log-data", data);
@@ -864,6 +984,10 @@ git_log_window_create (Git *plugin)
g_signal_connect (G_OBJECT (log_whole_project_check), "toggled",
G_CALLBACK (on_git_whole_project_toggled), plugin);
+
+ g_signal_connect (G_OBJECT (log_branch_combo), "changed",
+ G_CALLBACK (on_log_branch_combo_changed),
+ NULL);
data->list_store = gtk_list_store_new (NUM_COLS,
G_TYPE_OBJECT);
@@ -967,3 +1091,88 @@ git_log_get_path (Git *plugin)
return gtk_editable_get_chars (GTK_EDITABLE (log_path_entry), 0, -1);
}
+
+GFileMonitor *
+git_log_setup_refresh_monitor (Git *plugin)
+{
+ gchar *git_ref_path;
+ GFile *git_ref_file;
+ GFileMonitor *git_ref_monitor;
+
+ git_ref_path = g_strjoin (G_DIR_SEPARATOR_S,
+ plugin->project_root_directory,
+ ".git",
+ "refs",
+ "heads",
+ NULL);
+
+ git_ref_file = g_file_new_for_path (git_ref_path);
+ git_ref_monitor = g_file_monitor_directory (git_ref_file, 0, NULL, NULL);
+
+ g_file_monitor_set_rate_limit (git_ref_monitor, 1000);
+
+
+
+ g_signal_connect (G_OBJECT (git_ref_monitor), "changed",
+ G_CALLBACK (on_log_refresh_monitor_changed),
+ plugin);
+
+ g_free (git_ref_path);
+ g_object_unref (git_ref_file);
+
+ return git_ref_monitor;
+}
+
+void
+git_log_refresh_branches (Git *plugin)
+{
+ LogData *data;
+ GtkWidget *log_branch_combo;
+ gboolean being_refreshed;
+ GtkListStore *log_branch_combo_model;
+ GHashTable *branches_table;
+ GitBranchListCommand *branch_list_command;
+
+ data = g_object_get_data (G_OBJECT (plugin->log_viewer), "log-data");
+ log_branch_combo = GTK_WIDGET (gtk_builder_get_object (data->bxml,
+ "log_branch_combo"));
+ /* Don't refresh if another refresh is already in progress. The file monitor
+ * may trigger more than one concurrent refresh, which would populate the
+ * combo box several times. The command-finished handler will set the
+ * being-refreshed flag to FALSE when this refresh finishes,
+ * allowing the next refresh to go forward. */
+ being_refreshed = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (log_branch_combo),
+ "being-refreshed"));
+
+ if (!being_refreshed)
+ {
+ log_branch_combo_model = GTK_LIST_STORE (gtk_combo_box_get_model (GTK_COMBO_BOX (log_branch_combo)));
+ branches_table = g_hash_table_new_full (g_str_hash, g_str_equal, g_free,
+ g_free);
+ branch_list_command = git_branch_list_command_new (plugin->project_root_directory,
+ GIT_BRANCH_TYPE_ALL);
+
+ gtk_list_store_clear (log_branch_combo_model);
+
+ /* The branches table keeps track of branch names and iters in the combo
+ * model, so that the branch that was selected before we refreshed can be
+ * selected again automatically. If that branch doesn't exist, then
+ * the currently active branch will be selected. */
+ g_object_set_data_full (G_OBJECT (log_branch_combo), "branches-table",
+ branches_table, (GDestroyNotify) g_hash_table_destroy);
+
+ g_signal_connect (G_OBJECT (branch_list_command), "data-arrived",
+ G_CALLBACK (on_log_list_branch_command_data_arrived),
+ data->bxml);
+
+ g_signal_connect (G_OBJECT (branch_list_command), "command-finished",
+ G_CALLBACK (on_log_list_branch_command_finished),
+ data->bxml);
+
+ g_object_set_data (G_OBJECT (log_branch_combo), "being-refreshed",
+ GINT_TO_POINTER (TRUE));
+
+ anjuta_command_start (ANJUTA_COMMAND (branch_list_command));
+ }
+
+}
diff --git a/plugins/git/git-log-dialog.h b/plugins/git/git-log-dialog.h
index 4c2bfe3..054b555 100644
--- a/plugins/git/git-log-dialog.h
+++ b/plugins/git/git-log-dialog.h
@@ -38,5 +38,7 @@ GtkWidget *git_log_window_create (Git *plugin);
void git_log_window_clear (Git *plugin);
GitRevision *git_log_get_selected_revision (Git *plugin);
gchar *git_log_get_path (Git *plugin);
+GFileMonitor *git_log_setup_refresh_monitor (Git *plugin);
+void git_log_refresh_branches (Git *plugin);
#endif
diff --git a/plugins/git/plugin.c b/plugins/git/plugin.c
index e256eb2..328ac75 100644
--- a/plugins/git/plugin.c
+++ b/plugins/git/plugin.c
@@ -530,6 +530,8 @@ on_project_root_added (AnjutaPlugin *plugin, const gchar *name,
g_free (project_root_uri);
git_plugin->bisect_file_monitor = bisect_menus_init (git_plugin);
+ git_plugin->log_refresh_monitor = git_log_setup_refresh_monitor (git_plugin);
+ git_log_refresh_branches (git_plugin);
}
static void
@@ -561,6 +563,7 @@ on_project_root_removed (AnjutaPlugin *plugin, const gchar *name,
git_log_window_clear (git_plugin);
g_file_monitor_cancel (git_plugin->bisect_file_monitor);
+ g_file_monitor_cancel (git_plugin->log_refresh_monitor);
g_object_unref (git_plugin->bisect_file_monitor);
}
diff --git a/plugins/git/plugin.h b/plugins/git/plugin.h
index 7df0a46..e2f406c 100644
--- a/plugins/git/plugin.h
+++ b/plugins/git/plugin.h
@@ -65,6 +65,7 @@ struct _Git
/* File monitors */
GFileMonitor *bisect_file_monitor;
+ GFileMonitor *log_refresh_monitor;
};
struct _GitClass
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]