static void git_status_command_finalize (GObject *object) { GitStatusCommand *self; GList *current_status; self = GIT_STATUS_COMMAND (object); current_status = self->priv->status_queue->head; while (current_status) { g_object_unref (current_status->data); current_status = g_list_next (current_status); } g_queue_free (self->priv->status_queue); g_hash_table_destroy (self->priv->path_lookup_table); g_regex_unref (self->priv->status_regex); g_regex_unref (self->priv->untracked_files_regex); g_regex_unref (self->priv->section_commit_regex); g_regex_unref (self->priv->section_not_updated_regex); g_regex_unref (self->priv->section_untracked_regex); g_free (self->priv); G_OBJECT_CLASS (git_status_command_parent_class)->finalize (object); }
static void on_not_updated_status_data_arrived (AnjutaCommand *command, GitStatusPane *self) { GtkTreeStore *status_model; GQueue *output; 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)); add_status_items (output, status_model, &(self->priv->not_updated_iter), STATUS_TYPE_NOT_UPDATED); }
static gboolean git_status_command_start_automatic_monitor (AnjutaCommand *command) { 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); g_signal_connect (G_OBJECT (self->priv->head_monitor), "changed", G_CALLBACK (on_file_monitor_changed), command); g_signal_connect (G_OBJECT (self->priv->index_monitor), "changed", G_CALLBACK (on_file_monitor_changed), command); g_free (git_head_path); g_free (git_index_path); g_object_unref (git_head_file); g_object_unref (git_index_file); return TRUE; }
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); }
static void on_status_command_data_arrived (AnjutaCommand *command, IAnjutaVcsStatusCallback callback) { GQueue *status_queue; GitStatus *status; gchar *path; gchar *full_path; GFile *file; status_queue = git_status_command_get_status_queue (GIT_STATUS_COMMAND (command)); while (g_queue_peek_head (status_queue)) { status = g_queue_pop_head (status_queue); if (git_status_is_working_directory_descendant (status)) { path = git_status_get_path (status); full_path = g_strconcat (g_object_get_data (G_OBJECT (command), "working-directory"), G_DIR_SEPARATOR_S, path, NULL); file = g_file_new_for_path (full_path); DEBUG_PRINT ("Working directory: %s\n", (gchar *) g_object_get_data (G_OBJECT (command), "working-directory")); DEBUG_PRINT ("File %s Status %i\n", full_path, git_status_get_vcs_status (status)); if (file) { callback (file, git_status_get_vcs_status (status), g_object_get_data (G_OBJECT (command), "user-data")); g_object_unref (file); } g_free (path); g_free (full_path); } g_object_unref (status); } }
static void git_status_command_stop_automatic_monitor (AnjutaCommand *command) { GitStatusCommand *self; self = GIT_STATUS_COMMAND (command); 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; } if (self->priv->index_monitor) { g_file_monitor_cancel (self->priv->index_monitor); g_object_unref (self->priv->index_monitor); self->priv->index_monitor = NULL; } }
static void git_status_command_handle_output (GitCommand *git_command, const gchar *output) { GitStatusCommand *self; GMatchInfo *match_info; GitStatus *status_object; gchar *status; gchar *path; self = GIT_STATUS_COMMAND (git_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); }
static void git_status_command_data_arrived (AnjutaCommand *command) { git_status_command_clear_output (GIT_STATUS_COMMAND (command)); }
static void git_status_command_handle_output (GitCommand *git_command, const gchar *output) { GitStatusCommand *self; GMatchInfo *match_info; GitStatus *status_object; gchar *status; gchar *path; self = GIT_STATUS_COMMAND (git_command); /* See if the section has changed */ if (g_regex_match (self->priv->section_commit_regex, output, 0, NULL)) { self->priv->current_section = GIT_STATUS_SECTION_COMMIT; self->priv->current_section_regex = self->priv->status_regex; return; } else if (g_regex_match (self->priv->section_not_updated_regex, output, 0, NULL)) { self->priv->current_section = GIT_STATUS_SECTION_NOT_UPDATED; self->priv->current_section_regex = self->priv->status_regex; return; } else if (g_regex_match (self->priv->section_untracked_regex, output, 0, NULL)) { self->priv->current_section = GIT_STATUS_SECTION_UNTRACKED; self->priv->current_section_regex = self->priv->untracked_files_regex; return; } if (self->priv->sections & self->priv->current_section) { if (g_regex_match (self->priv->current_section_regex, output, 0, &match_info)) { if (self->priv->current_section_regex == self->priv->status_regex) { status = g_match_info_fetch (match_info, 1); path = g_match_info_fetch (match_info, 2); } else { status = g_strdup ("untracked"); path = g_match_info_fetch (match_info, 1); } /* Git sometimes mentions paths twice in status output. This can * happen, for example, where there is a conflict, in which case a * path would show up as both "unmerged" and "modified." */ g_strchug (path); if (!g_hash_table_lookup_extended (self->priv->path_lookup_table, path, NULL, NULL)) { status_object = git_status_new (path, status); g_queue_push_tail (self->priv->status_queue, status_object); g_hash_table_insert (self->priv->path_lookup_table, g_strdup (path), NULL); anjuta_command_notify_data_arrived (ANJUTA_COMMAND (git_command)); } g_free (status); g_free (path); } g_match_info_free (match_info); } }