[anjuta/libgit2-glib] git: Port the status command to libgit2-glib
- From: James Liggett <jrliggett src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [anjuta/libgit2-glib] git: Port the status command to libgit2-glib
- Date: Mon, 22 Jul 2013 23:18:33 +0000 (UTC)
commit dd400b5717893623e59f7beb1148b2ea80a7be4a
Author: James Liggett <jrliggett cox net>
Date: Mon Jul 22 15:37:31 2013 -0700
git: Port the status command to libgit2-glib
plugins/git/git-status-command.c | 299 +++++++-------------------------------
plugins/git/git-status-command.h | 19 +--
plugins/git/git-status-pane.c | 135 ++++++++---------
plugins/git/git-status.c | 42 +++++-
plugins/git/git-status.h | 5 +-
plugins/git/git-vcs-interface.c | 45 ++++---
plugins/git/plugin.c | 38 +----
plugins/git/plugin.h | 3 +-
8 files changed, 199 insertions(+), 387 deletions(-)
---
diff --git a/plugins/git/git-status-command.c b/plugins/git/git-status-command.c
index 7679985..eef39e8 100644
--- a/plugins/git/git-status-command.c
+++ b/plugins/git/git-status-command.c
@@ -24,310 +24,111 @@
#include "git-status-command.h"
-#define STATUS_REGEX "((M|A|D|U|\\?|\\s){2}) (.*)"
-
struct _GitStatusCommandPriv
{
- GQueue *status_queue;
+ GAsyncQueue *status_queue;
GitStatusSections sections;
- GHashTable *status_codes;
- GHashTable *conflict_codes;
- GRegex *status_regex;
- GFileMonitor *head_monitor;
- GFileMonitor *index_monitor;
+ gchar *path;
};
-G_DEFINE_TYPE (GitStatusCommand, git_status_command, GIT_TYPE_PROCESS_COMMAND);
+G_DEFINE_TYPE (GitStatusCommand, git_status_command, GIT_TYPE_COMMAND);
-static guint
-git_status_command_run (AnjutaCommand *command)
+static void
+git_status_command_init (GitStatusCommand *self)
{
- git_process_command_add_arg (GIT_PROCESS_COMMAND (command), "status");
- git_process_command_add_arg (GIT_PROCESS_COMMAND (command), "--porcelain");
-
- return 0;
+ self->priv = g_new0 (GitStatusCommandPriv, 1);
+ self->priv->status_queue = g_async_queue_new_full (g_object_unref);
}
static void
-git_status_command_handle_output (GitProcessCommand *git_process_command, const gchar *output)
+git_status_command_finalize (GObject *object)
{
GitStatusCommand *self;
- GMatchInfo *match_info;
- GitStatus *status_object;
- gchar *status;
- gchar *path;
- self = GIT_STATUS_COMMAND (git_process_command);
- status_object = NULL;
-
- if (g_regex_match (self->priv->status_regex, output, 0, &match_info))
- {
- /* Determine which section this entry goes in */
- status = g_match_info_fetch (match_info, 1);
- path = g_match_info_fetch (match_info, 3);
-
- if (status[0] == ' ')
- {
- /* Changed but not updated */
- if (self->priv->sections & GIT_STATUS_SECTION_NOT_UPDATED)
- {
- status_object = git_status_new(path,
- GPOINTER_TO_INT (g_hash_table_lookup
(self->priv->status_codes,
-
GINT_TO_POINTER (status[1]))));
- }
- }
- else if (status[1] == ' ')
- {
- /* Added to commit */
- if (self->priv->sections & GIT_STATUS_SECTION_COMMIT)
- {
- status_object = git_status_new(path,
- GPOINTER_TO_INT (g_hash_table_lookup
(self->priv->status_codes,
-
GINT_TO_POINTER (status[0]))));
- }
- }
- else
- {
- /* File may have been added to the index and then changed again in
- * the working tree, or it could be a conflict */
-
- /* Unversioned files */
- if (status[0] == '?')
- {
- if (self->priv->sections & GIT_STATUS_SECTION_UNTRACKED)
- {
- status_object = git_status_new(path,
- ANJUTA_VCS_STATUS_UNVERSIONED);
- }
- }
- else if (g_hash_table_lookup_extended (self->priv->conflict_codes, status,
- NULL, NULL))
- {
- /* Conflicts are put in the changed but not updated section */
- if (self->priv->sections & GIT_STATUS_SECTION_NOT_UPDATED)
- {
- status_object = git_status_new (path,
- ANJUTA_VCS_STATUS_CONFLICTED);
- }
- }
- else
- {
- status_object = git_status_new(path,
- GPOINTER_TO_INT(g_hash_table_lookup
(self->priv->status_codes,
-
GINT_TO_POINTER (status[0]))));
- }
-
- }
-
-
-
- g_free (status);
- g_free (path);
-
- if (status_object)
- {
- g_queue_push_tail (self->priv->status_queue, status_object);
- anjuta_command_notify_data_arrived (ANJUTA_COMMAND (self));
- }
-
- }
-
- g_match_info_free (match_info);
+ self = GIT_STATUS_COMMAND (object);
-}
-
-static void
-git_status_command_init (GitStatusCommand *self)
-{
- self->priv = g_new0 (GitStatusCommandPriv, 1);
- self->priv->status_queue = g_queue_new ();
+ g_async_queue_unref (self->priv->status_queue);
+ g_free (self->priv->path);
- self->priv->status_regex = g_regex_new (STATUS_REGEX, 0, 0, NULL);
- self->priv->status_codes = g_hash_table_new (g_direct_hash, g_direct_equal);
- self->priv->conflict_codes = g_hash_table_new (g_str_hash, g_str_equal);
-
- /* Initialize status code hash tables */
- g_hash_table_insert (self->priv->status_codes,
- GINT_TO_POINTER ('M'),
- GINT_TO_POINTER (ANJUTA_VCS_STATUS_MODIFIED));
-
- g_hash_table_insert (self->priv->status_codes,
- GINT_TO_POINTER ('A'),
- GINT_TO_POINTER (ANJUTA_VCS_STATUS_ADDED));
-
- g_hash_table_insert (self->priv->status_codes,
- GINT_TO_POINTER ('D'),
- GINT_TO_POINTER (ANJUTA_VCS_STATUS_MODIFIED));
-
- /* TODO: Handle each conflict case individually so that we can eventually
- * give the user more information about the conflict */
- g_hash_table_insert (self->priv->conflict_codes, "DD", NULL);
- g_hash_table_insert (self->priv->conflict_codes, "AU", NULL);
- g_hash_table_insert (self->priv->conflict_codes, "UD", NULL);
- g_hash_table_insert (self->priv->conflict_codes, "UA", NULL);
- g_hash_table_insert (self->priv->conflict_codes, "DU", NULL);
- g_hash_table_insert (self->priv->conflict_codes, "AA", NULL);
- g_hash_table_insert (self->priv->conflict_codes, "UU", NULL);
-}
+ g_free (self->priv);
-static void
-on_file_monitor_changed (GFileMonitor *monitor, GFile *file, GFile *other_file,
- GFileMonitorEvent event, AnjutaCommand *command)
-{
- /* Handle created and modified events just to cover all possible cases.
- * Sometimes git does some odd things... */
- if (event == G_FILE_MONITOR_EVENT_CHANGED ||
- event == G_FILE_MONITOR_EVENT_CREATED)
- {
- anjuta_command_start (command);
- }
+ G_OBJECT_CLASS (git_status_command_parent_class)->finalize (object);
}
-static gboolean
-git_status_command_start_automatic_monitor (AnjutaCommand *command)
+static gint
+git_status_command_status_callback (const gchar *file, GgitStatusFlags flags,
+ GitStatusCommand *self)
{
- GitStatusCommand *self;
- gchar *working_directory;
- gchar *git_head_path;
- gchar *git_index_path;
- GFile *git_head_file;
- GFile *git_index_file;
-
- self = GIT_STATUS_COMMAND (command);
-
- g_object_get (self, "working-directory", &working_directory, NULL);
-
- /* Watch for changes to the HEAD file and the index file, so that we can
- * at least detect commits and index changes. */
- git_head_path = g_strjoin (G_DIR_SEPARATOR_S,
- working_directory,
- ".git",
- "HEAD",
- NULL);
- git_index_path = g_strjoin (G_DIR_SEPARATOR_S,
- working_directory,
- ".git",
- "index",
- NULL);
- git_head_file = g_file_new_for_path (git_head_path);
- git_index_file = g_file_new_for_path (git_index_path);
- self->priv->head_monitor = g_file_monitor_file (git_head_file, 0, NULL,
- NULL);
- self->priv->index_monitor = g_file_monitor_file (git_index_file, 0, NULL,
- NULL);
+ GitStatus *status;
- g_signal_connect (G_OBJECT (self->priv->head_monitor), "changed",
- G_CALLBACK (on_file_monitor_changed),
- command);
+ status = git_status_new (file, flags);
- g_signal_connect (G_OBJECT (self->priv->index_monitor), "changed",
- G_CALLBACK (on_file_monitor_changed),
- command);
+ g_async_queue_push (self->priv->status_queue, status);
+ anjuta_task_notify_data_arrived (ANJUTA_TASK (self));
- g_free (git_head_path);
- g_free (git_index_path);
- g_object_unref (git_head_file);
- g_object_unref (git_index_file);
-
- return TRUE;
+ return 0;
}
static void
-git_status_command_stop_automatic_monitor (AnjutaCommand *command)
+git_status_command_run (AnjutaTask *task)
{
GitStatusCommand *self;
+ GgitRepository *repository;
+ GgitStatusOptions *options;
+ GgitStatusOption option_flags;
+ const gchar *paths[2];
- self = GIT_STATUS_COMMAND (command);
+ self = GIT_STATUS_COMMAND (task);;
- if (self->priv->head_monitor)
- {
- g_file_monitor_cancel (self->priv->head_monitor);
- g_object_unref (self->priv->head_monitor);
- self->priv->head_monitor = NULL;
- }
+ g_object_get (self, "repository", &repository, NULL);
- if (self->priv->index_monitor)
+ if (repository)
{
- g_file_monitor_cancel (self->priv->index_monitor);
- g_object_unref (self->priv->index_monitor);
- self->priv->index_monitor = NULL;
- }
-}
+ option_flags = 0;
-static void
-git_status_command_clear_output (GitStatusCommand *self)
-{
- GList *current_output;
+ if (self->priv->sections & GIT_STATUS_SECTION_UNTRACKED)
+ option_flags |= GGIT_STATUS_OPTION_INCLUDE_UNTRACKED;
- current_output = self->priv->status_queue->head;
+ paths[0] = self->priv->path;
+ paths[1] = NULL;
- while (current_output)
- {
- g_object_unref (current_output->data);
- current_output = g_list_next (current_output);
- }
+ options = ggit_status_options_new (option_flags, 0, paths);
- g_queue_clear (self->priv->status_queue);
-}
+ ggit_repository_file_status_foreach (repository, options,
+ (GgitStatusCallback) git_status_command_status_callback,
+ self, NULL);
-static void
-git_status_command_data_arrived (AnjutaCommand *command)
-{
- git_status_command_clear_output (GIT_STATUS_COMMAND (command));
-}
-
-
-static void
-git_status_command_finalize (GObject *object)
-{
- GitStatusCommand *self;
-
- self = GIT_STATUS_COMMAND (object);
-
- git_status_command_clear_output (self);
- git_status_command_stop_automatic_monitor (ANJUTA_COMMAND (self));
-
- g_queue_free (self->priv->status_queue);
- g_regex_unref (self->priv->status_regex);
-
- g_free (self->priv);
-
- G_OBJECT_CLASS (git_status_command_parent_class)->finalize (object);
+ ggit_status_options_free (options);
+ }
}
static void
git_status_command_class_init (GitStatusCommandClass *klass)
{
GObjectClass* object_class = G_OBJECT_CLASS (klass);
- GitProcessCommandClass* parent_class = GIT_PROCESS_COMMAND_CLASS (klass);
- AnjutaCommandClass* command_class = ANJUTA_COMMAND_CLASS (klass);
+ AnjutaTaskClass* task_class = ANJUTA_TASK_CLASS (klass);
object_class->finalize = git_status_command_finalize;
- parent_class->output_handler = git_status_command_handle_output;
- command_class->run = git_status_command_run;
- command_class->data_arrived = git_status_command_data_arrived;
- command_class->start_automatic_monitor = git_status_command_start_automatic_monitor;
- command_class->stop_automatic_monitor = git_status_command_stop_automatic_monitor;
+ task_class->run = git_status_command_run;
}
-GitStatusCommand *
-git_status_command_new (const gchar *working_directory,
- GitStatusSections sections)
+GitCommand *
+git_status_command_new (GitStatusSections sections, const gchar *path)
{
GitStatusCommand *self;
- self = g_object_new (GIT_TYPE_STATUS_COMMAND,
- "working-directory", working_directory,
- "single-line-output", TRUE,
- NULL);
+ self = g_object_new (GIT_TYPE_STATUS_COMMAND, NULL);
self->priv->sections = sections;
+ self->priv->path = g_strdup (path);
+
+ g_print ("Given path: %s\n", path);
- return self;
+ return GIT_COMMAND (self);
}
-GQueue *
+GAsyncQueue *
git_status_command_get_status_queue (GitStatusCommand *self)
{
return self->priv->status_queue;
diff --git a/plugins/git/git-status-command.h b/plugins/git/git-status-command.h
index 551990b..778c71f 100644
--- a/plugins/git/git-status-command.h
+++ b/plugins/git/git-status-command.h
@@ -26,7 +26,8 @@
#define _GIT_STATUS_COMMAND_H_
#include <glib-object.h>
-#include "git-process-command.h"
+#include <libgit2-glib/ggit-status-options.h>
+#include "git-command.h"
#include "git-status.h"
G_BEGIN_DECLS
@@ -44,29 +45,25 @@ typedef struct _GitStatusCommandPriv GitStatusCommandPriv;
typedef enum
{
- GIT_STATUS_SECTION_COMMIT = 1 << 0,
- GIT_STATUS_SECTION_NOT_UPDATED = 1 << 1,
- GIT_STATUS_SECTION_UNTRACKED = 1 << 2,
- GIT_STATUS_SECTION_MODIFIED = (GIT_STATUS_SECTION_COMMIT |
- GIT_STATUS_SECTION_NOT_UPDATED)
+ GIT_STATUS_SECTION_UNTRACKED = 1 << 0,
} GitStatusSections;
struct _GitStatusCommandClass
{
- GitProcessCommandClass parent_class;
+ GitCommandClass parent_class;
};
struct _GitStatusCommand
{
- GitProcessCommand parent_instance;
+ GitCommand parent_instance;
GitStatusCommandPriv *priv;
};
GType git_status_command_get_type (void) G_GNUC_CONST;
-GitStatusCommand *git_status_command_new (const gchar *working_directory,
- GitStatusSections sections);
-GQueue *git_status_command_get_status_queue (GitStatusCommand *self);
+GitCommand *git_status_command_new (GitStatusSections sections,
+ const gchar *path);
+GAsyncQueue *git_status_command_get_status_queue (GitStatusCommand *self);
G_END_DECLS
diff --git a/plugins/git/git-status-pane.c b/plugins/git/git-status-pane.c
index 6f74de7..4004045 100644
--- a/plugins/git/git-status-pane.c
+++ b/plugins/git/git-status-pane.c
@@ -302,62 +302,58 @@ on_selected_renderer_toggled (GtkCellRendererToggle *renderer, gchar *tree_path,
}
static void
-add_status_items (GQueue *output, GtkTreeStore *status_model,
- GtkTreeIter *parent_iter, StatusType type)
+add_status_item (GtkTreeStore *status_model, GtkTreeIter *parent_iter,
+ StatusType type, const gchar *path, AnjutaVcsStatus status)
{
- GitStatus *status_object;
- AnjutaVcsStatus status;
- gchar *path;
GtkTreeIter iter;
- while (g_queue_peek_head (output))
- {
- status_object = g_queue_pop_head (output);
- status = git_status_get_vcs_status (status_object);
- path = git_status_get_path (status_object);
-
- gtk_tree_store_append (status_model, &iter, parent_iter);
- gtk_tree_store_set (status_model, &iter,
- COL_SELECTED, FALSE,
- COL_STATUS, status,
- COL_PATH, path,
- COL_TYPE, type,
- -1);
- g_free (path);
- g_object_unref (status_object);
- }
+ gtk_tree_store_append (status_model, &iter, parent_iter);
+ gtk_tree_store_set (status_model, &iter,
+ COL_SELECTED, FALSE,
+ COL_STATUS, status,
+ COL_PATH, path,
+ COL_TYPE, type,
+ -1);
}
static void
-on_commit_status_data_arrived (AnjutaCommand *command,
- GitStatusPane *self)
+on_status_command_data_arrived (AnjutaTask *task, GitStatusPane *self)
{
GtkTreeStore *status_model;
- GQueue *output;
+ GAsyncQueue *status_queue;
+ GitStatus *status;
+ gchar *path;
+ AnjutaVcsStatus index_status;
+ AnjutaVcsStatus working_tree_status;
- status_model = GTK_TREE_STORE (gtk_builder_get_object (self->priv->builder,
- "status_model"));
- output = git_status_command_get_status_queue (GIT_STATUS_COMMAND (command));
+ g_print ("Data arrived.\n");
- add_status_items (output, status_model, &(self->priv->commit_iter),
- STATUS_TYPE_COMMIT);
+ status_model = GTK_TREE_STORE (gtk_builder_get_object (self->priv->builder,
+ "status_model"));
+ status_queue = git_status_command_get_status_queue (GIT_STATUS_COMMAND (task));
-}
+ while ((status = g_async_queue_try_pop (status_queue)))
+ {
+ path = git_status_get_path (status);
+ index_status = git_status_get_index_status (status);
+ working_tree_status = git_status_get_working_tree_status (status);
-static void
-on_not_updated_status_data_arrived (AnjutaCommand *command,
- GitStatusPane *self)
-{
- GtkTreeStore *status_model;
- GQueue *output;
+ if (index_status)
+ {
+ add_status_item (status_model, &(self->priv->commit_iter),
+ STATUS_TYPE_COMMIT, path, index_status);
+ }
- status_model = GTK_TREE_STORE (gtk_builder_get_object (self->priv->builder,
- "status_model"));
- output = git_status_command_get_status_queue (GIT_STATUS_COMMAND (command));
+ if (working_tree_status)
+ {
+ add_status_item (status_model, &(self->priv->not_updated_iter),
+ STATUS_TYPE_NOT_UPDATED, path, working_tree_status);
+ }
- add_status_items (output, status_model, &(self->priv->not_updated_iter),
- STATUS_TYPE_NOT_UPDATED);
+ g_free (path);
+ g_object_unref (status);
+ }
}
static void
@@ -714,11 +710,35 @@ git_status_pane_finalize (GObject *object)
static void
git_status_pane_refresh (AnjutaDockPane *pane)
{
+ GitStatusPane *self;
Git *plugin;
+ GitCommand *status_command;
+ GtkTreeView *status_view;
+ self = GIT_STATUS_PANE (pane);
plugin = ANJUTA_PLUGIN_GIT (anjuta_dock_pane_get_plugin (pane));
+ status_command = git_status_command_new (0, NULL);
+ status_view = GTK_TREE_VIEW (gtk_builder_get_object (self->priv->builder,
+ "status_view"));
+
+ git_status_pane_clear (self);
+
+ g_signal_connect (G_OBJECT (status_command), "data-arrived",
+ G_CALLBACK (on_status_command_data_arrived),
+ pane);
- anjuta_command_start (ANJUTA_COMMAND (plugin->commit_status_command));
+ /* Expand the placeholders so something is visible to the user after
+ * refreshing */
+ g_signal_connect_swapped (G_OBJECT (status_command),
+ "finished",
+ G_CALLBACK (gtk_tree_view_expand_all),
+ status_view);
+
+ g_signal_connect (G_OBJECT (status_command), "finished",
+ G_CALLBACK (g_object_unref),
+ NULL);
+
+ git_thread_pool_push (plugin->thread_pool, status_command);
}
@@ -747,36 +767,7 @@ git_status_pane_class_init (GitStatusPaneClass *klass)
AnjutaDockPane *
git_status_pane_new (Git *plugin)
{
- GitStatusPane *self;
- GtkTreeView *status_view;
-
- self = g_object_new (GIT_TYPE_STATUS_PANE, "plugin", plugin, NULL);
- status_view = GTK_TREE_VIEW (gtk_builder_get_object (self->priv->builder,
-
"status_view"));
-
- g_signal_connect_swapped (G_OBJECT (plugin->commit_status_command),
- "command-started",
- G_CALLBACK (git_status_pane_clear),
- self);
-
- /* Expand the placeholders so something is visible to the user after
- * refreshing */
- g_signal_connect_swapped (G_OBJECT (plugin->not_updated_status_command),
- "command-finished",
- G_CALLBACK (gtk_tree_view_expand_all),
- status_view);
-
- g_signal_connect (G_OBJECT (plugin->commit_status_command),
- "data-arrived",
- G_CALLBACK (on_commit_status_data_arrived),
- self);
-
- g_signal_connect (G_OBJECT (plugin->not_updated_status_command),
- "data-arrived",
- G_CALLBACK (on_not_updated_status_data_arrived),
- self);
-
- return ANJUTA_DOCK_PANE (self);
+ return g_object_new (GIT_TYPE_STATUS_PANE, "plugin", plugin, NULL);;
}
static void
diff --git a/plugins/git/git-status.c b/plugins/git/git-status.c
index 5f2307a..deae6c5 100644
--- a/plugins/git/git-status.c
+++ b/plugins/git/git-status.c
@@ -27,7 +27,8 @@
struct _GitStatusPriv
{
gchar *path;
- AnjutaVcsStatus status;
+ AnjutaVcsStatus index_status;
+ AnjutaVcsStatus working_tree_status;
};
G_DEFINE_TYPE (GitStatus, git_status, G_TYPE_OBJECT);
@@ -60,14 +61,27 @@ git_status_class_init (GitStatusClass *klass)
}
GitStatus *
-git_status_new (const gchar *path, AnjutaVcsStatus status)
+git_status_new (const gchar *path, GgitStatusFlags status)
{
GitStatus *self;
self = g_object_new (GIT_TYPE_STATUS, NULL);
self->priv->path = g_strdup (path);
- self->priv->status = status;
+
+ /* Map GgitStatusFlags to AnjutaVcsStatus:
+ * 1. Swap bits 1 and 2 to map modified and added in the index
+ * 2. Swap bits 8 and 9 to map modified and added in the working tree
+ * 3. Make sure that bits 3 (removed in index) and 10 (removed in
+ * working tree) are preserved because they map to AnjutaVcsStatus
+ * without changes.
+ */
+ status = (status & 0x0102) >> 1 | (status & 0x0081) << 1 | (status & 0x0204);
+
+ /* The index values are in the lower three bytes; the working tree values
+ * are in bits 8-10. */
+ self->priv->index_status = (status & 0x0007);
+ self->priv->working_tree_status = (status & 0x0380) >> 7;
return self;
}
@@ -79,8 +93,28 @@ git_status_get_path (GitStatus *self)
}
AnjutaVcsStatus
+git_status_get_index_status (GitStatus *self)
+{
+ return self->priv->index_status;
+}
+
+AnjutaVcsStatus
+git_status_get_working_tree_status (GitStatus *self)
+{
+ return self->priv->working_tree_status;
+}
+
+AnjutaVcsStatus
git_status_get_vcs_status (GitStatus *self)
{
- return self->priv->status;
+ /* A "new" status in the working tree section means the file is untracked */
+ if (self->priv->working_tree_status & ANJUTA_VCS_STATUS_ADDED)
+ return ANJUTA_VCS_STATUS_UNVERSIONED;
+ else
+ {
+ /* Otherwise, favor the index value over the working tree value */
+ return self->priv->index_status == 0 ? self->priv->working_tree_status :
+ self->priv->index_status;
+ }
}
diff --git a/plugins/git/git-status.h b/plugins/git/git-status.h
index c931bdd..2b0ea31 100644
--- a/plugins/git/git-status.h
+++ b/plugins/git/git-status.h
@@ -27,6 +27,7 @@
#include <glib-object.h>
#include <libanjuta/anjuta-vcs-status-tree-view.h>
+#include <libgit2-glib/ggit-repository.h>
G_BEGIN_DECLS
@@ -54,9 +55,11 @@ struct _GitStatus
};
GType git_status_get_type (void) G_GNUC_CONST;
-GitStatus *git_status_new (const gchar *path, AnjutaVcsStatus status);
+GitStatus *git_status_new (const gchar *path, GgitStatusFlags status);
gchar *git_status_get_path (GitStatus *self);
AnjutaVcsStatus git_status_get_vcs_status (GitStatus *self);
+AnjutaVcsStatus git_status_get_index_status (GitStatus *self);
+AnjutaVcsStatus git_status_get_working_tree_status (GitStatus *self);
G_END_DECLS
diff --git a/plugins/git/git-vcs-interface.c b/plugins/git/git-vcs-interface.c
index 5f1eca5..b9748c7 100644
--- a/plugins/git/git-vcs-interface.c
+++ b/plugins/git/git-vcs-interface.c
@@ -190,7 +190,7 @@ static void
on_status_command_data_arrived (AnjutaCommand *command,
IAnjutaVcsStatusCallback callback)
{
- GQueue *status_queue;
+ GAsyncQueue *status_queue;
GitStatus *status;
const gchar *working_directory;
gchar *path;
@@ -199,9 +199,8 @@ on_status_command_data_arrived (AnjutaCommand *command,
status_queue = git_status_command_get_status_queue (GIT_STATUS_COMMAND (command));
- while (g_queue_peek_head (status_queue))
+ while ((status = g_async_queue_try_pop (status_queue)))
{
- status = g_queue_pop_head (status_queue);
working_directory = g_object_get_data (G_OBJECT (command),
"working-directory");
path = git_status_get_path (status);
@@ -234,23 +233,39 @@ git_ivcs_query_status (IAnjutaVcs *obj, GFile *file,
gpointer user_data, GCancellable *cancel,
AnjutaAsyncNotify *notify, GError **err)
{
+ Git *plugin;
gchar *path;
- GitStatusCommand *status_command;
+ const gchar *project_root_directory;
+ GitCommand *status_command;
+
+ plugin = ANJUTA_PLUGIN_GIT (obj);
+
+ g_return_if_fail (plugin->thread_pool);
+
+ path = g_file_get_relative_path (plugin->project_root_file, file);
+ project_root_directory = ANJUTA_PLUGIN_GIT (obj)->project_root_directory;
+ status_command = git_status_command_new (GIT_STATUS_SECTION_UNTRACKED,
+ path);
- path = g_file_get_path (file);
- status_command = git_status_command_new (path, ~0);
+ g_object_set_data (G_OBJECT (status_command), "user-data", user_data);
+ g_object_set_data_full (G_OBJECT (status_command), "working-directory",
+ g_strdup (project_root_directory), g_free);
g_free (path);
- g_object_set_data (G_OBJECT (status_command), "user-data", user_data);
- g_object_set_data (G_OBJECT (status_command), "working-directory",
- ANJUTA_PLUGIN_GIT (obj)->project_root_directory);
g_signal_connect (G_OBJECT (status_command), "data-arrived",
G_CALLBACK (on_status_command_data_arrived),
callback);
- g_signal_connect (G_OBJECT (status_command), "command-finished",
+ if (notify)
+ {
+ g_signal_connect_swapped (G_OBJECT (status_command), "finished",
+ G_CALLBACK (anjuta_async_notify_notify_finished),
+ notify);
+ }
+
+ g_signal_connect (G_OBJECT (status_command), "finished",
G_CALLBACK (g_object_unref),
NULL);
@@ -263,15 +278,7 @@ git_ivcs_query_status (IAnjutaVcs *obj, GFile *file,
}
#endif
- if (notify)
- {
- g_signal_connect_swapped (G_OBJECT (status_command), "command-finished",
- G_CALLBACK (anjuta_async_notify_notify_finished),
- notify);
- }
-
- anjuta_command_queue_push (ANJUTA_PLUGIN_GIT (obj)->command_queue,
- ANJUTA_COMMAND (status_command));
+ git_thread_pool_push (plugin->thread_pool, status_command);
}
void
diff --git a/plugins/git/plugin.c b/plugins/git/plugin.c
index 4d2daae..503bc43 100644
--- a/plugins/git/plugin.c
+++ b/plugins/git/plugin.c
@@ -641,17 +641,16 @@ on_project_root_added (AnjutaPlugin *plugin, const gchar *name,
{
Git *git_plugin;
gchar *project_root_uri;
- GFile *file;
GFile *repository_file;
git_plugin = ANJUTA_PLUGIN_GIT (plugin);
g_free (git_plugin->project_root_directory);
project_root_uri = g_value_dup_string (value);
- file = g_file_new_for_uri (project_root_uri);
- repository_file = g_file_get_child (file, ".git");
+ git_plugin->project_root_file = g_file_new_for_uri (project_root_uri);
+ repository_file = g_file_get_child (git_plugin->project_root_file, ".git");
- git_plugin->project_root_directory = g_file_get_path (file);
+ git_plugin->project_root_directory = g_file_get_path (git_plugin->project_root_file);
git_plugin->repository = ggit_repository_open (repository_file, NULL);
if (git_plugin->repository)
@@ -661,7 +660,6 @@ on_project_root_added (AnjutaPlugin *plugin, const gchar *name,
gtk_widget_set_sensitive (git_plugin->command_bar, TRUE);
}
- g_object_unref (file);
g_object_unref (repository_file);
g_free (project_root_uri);
@@ -672,12 +670,6 @@ on_project_root_added (AnjutaPlugin *plugin, const gchar *name,
g_object_set (G_OBJECT (git_plugin->remote_branch_list_command),
"working-directory", git_plugin->project_root_directory,
NULL);
- g_object_set (G_OBJECT (git_plugin->commit_status_command),
- "working-directory", git_plugin->project_root_directory,
- NULL);
- g_object_set (G_OBJECT (git_plugin->not_updated_status_command),
- "working-directory", git_plugin->project_root_directory,
- NULL);
g_object_set (G_OBJECT (git_plugin->remote_list_command),
"working-directory", git_plugin->project_root_directory,
NULL);
@@ -692,13 +684,11 @@ on_project_root_added (AnjutaPlugin *plugin, const gchar *name,
NULL);
anjuta_command_start_automatic_monitor (ANJUTA_COMMAND (git_plugin->local_branch_list_command));
- anjuta_command_start_automatic_monitor (ANJUTA_COMMAND (git_plugin->commit_status_command));
anjuta_command_start_automatic_monitor (ANJUTA_COMMAND (git_plugin->remote_list_command));
anjuta_command_start_automatic_monitor (ANJUTA_COMMAND (git_plugin->tag_list_command));
anjuta_command_start_automatic_monitor (ANJUTA_COMMAND (git_plugin->stash_list_command));
anjuta_command_start_automatic_monitor (ANJUTA_COMMAND (git_plugin->ref_command));
anjuta_command_start (ANJUTA_COMMAND (git_plugin->local_branch_list_command));
- anjuta_command_start (ANJUTA_COMMAND (git_plugin->commit_status_command));
anjuta_command_start (ANJUTA_COMMAND (git_plugin->remote_list_command));
anjuta_command_start (ANJUTA_COMMAND (git_plugin->tag_list_command));
anjuta_command_start (ANJUTA_COMMAND (git_plugin->stash_list_command));
@@ -731,12 +721,12 @@ on_project_root_removed (AnjutaPlugin *plugin, const gchar *name,
}
anjuta_command_stop_automatic_monitor (ANJUTA_COMMAND (git_plugin->local_branch_list_command));
- anjuta_command_stop_automatic_monitor (ANJUTA_COMMAND (git_plugin->commit_status_command));
anjuta_command_stop_automatic_monitor (ANJUTA_COMMAND (git_plugin->remote_list_command));
anjuta_command_stop_automatic_monitor (ANJUTA_COMMAND (git_plugin->tag_list_command));
anjuta_command_stop_automatic_monitor (ANJUTA_COMMAND (git_plugin->stash_list_command));
anjuta_command_stop_automatic_monitor (ANJUTA_COMMAND (git_plugin->ref_command));
+ g_clear_object (&git_plugin->project_root_file);
g_free (git_plugin->project_root_directory);
git_plugin->project_root_directory = NULL;
@@ -954,13 +944,6 @@ git_activate_plugin (AnjutaPlugin *plugin)
G_CALLBACK (on_branch_list_command_data_arrived),
plugin);
- /* Create the status list commands. The different commands correspond to
- * the two different sections in status output: Changes to be committed
- * (staged) and Changed but not updated (unstaged.) */
- git_plugin->commit_status_command = git_status_command_new (NULL,
- GIT_STATUS_SECTION_COMMIT);
- git_plugin->not_updated_status_command = git_status_command_new (NULL,
- GIT_STATUS_SECTION_NOT_UPDATED);
/* Remote list command */
git_plugin->remote_list_command = git_remote_list_command_new (NULL);
@@ -968,12 +951,6 @@ git_activate_plugin (AnjutaPlugin *plugin)
/* Ref list command. used to keep the log up to date */
git_plugin->ref_command = git_ref_command_new (NULL);
- /* Always run the not updated commmand after the commmit command. */
- g_signal_connect (G_OBJECT (git_plugin->commit_status_command),
- "command-finished",
- G_CALLBACK (run_next_command),
- git_plugin->not_updated_status_command);
-
/* Tag list command */
git_plugin->tag_list_command = git_tag_list_command_new (NULL);
@@ -1077,13 +1054,12 @@ git_deactivate_plugin (AnjutaPlugin *plugin)
g_object_unref (git_plugin->local_branch_list_command);
g_object_unref (git_plugin->remote_branch_list_command);
- g_object_unref (git_plugin->commit_status_command);
- g_object_unref (git_plugin->not_updated_status_command);
g_object_unref (git_plugin->remote_list_command);
g_object_unref (git_plugin->tag_list_command);
g_object_unref (git_plugin->stash_list_command);
g_object_unref (git_plugin->ref_command);
+ g_clear_object (&git_plugin->project_root_file);
g_free (git_plugin->project_root_directory);
g_free (git_plugin->current_editor_filename);
@@ -1098,6 +1074,8 @@ git_finalize (GObject *obj)
git_plugin = ANJUTA_PLUGIN_GIT (obj);
g_object_unref (git_plugin->command_queue);
+
+ git_threads_shutdown ();
G_OBJECT_CLASS (parent_class)->finalize (obj);
}
@@ -1123,6 +1101,8 @@ git_instance_init (GObject *obj)
{
Git *plugin = ANJUTA_PLUGIN_GIT (obj);
+ git_threads_init ();
+
plugin->command_queue = anjuta_command_queue_new (ANJUTA_COMMAND_QUEUE_EXECUTE_AUTOMATIC);
plugin->settings = g_settings_new (SETTINGS_SCHEMA);
diff --git a/plugins/git/plugin.h b/plugins/git/plugin.h
index cbf0a1d..8368d4a 100644
--- a/plugins/git/plugin.h
+++ b/plugins/git/plugin.h
@@ -61,6 +61,7 @@ struct _Git
{
AnjutaPlugin parent;
+ GFile *project_root_file;
gchar *project_root_directory;
gchar *current_editor_filename;
@@ -95,8 +96,6 @@ struct _Git
* way of handling project (working directory) changes */
GitBranchListCommand *local_branch_list_command;
GitBranchListCommand *remote_branch_list_command;
- GitStatusCommand *commit_status_command;
- GitStatusCommand *not_updated_status_command;
GitRemoteListCommand *remote_list_command;
GitTagListCommand *tag_list_command;
GitStashListCommand *stash_list_command;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]