Example #1
0
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);
}
Example #2
0
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);
}
Example #3
0
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;
}
Example #4
0
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);
}
Example #5
0
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);
		
	}
}
Example #6
0
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;
	}
}
Example #7
0
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);
	
}
Example #8
0
static void
git_status_command_data_arrived (AnjutaCommand *command)
{
	git_status_command_clear_output (GIT_STATUS_COMMAND (command));
}
Example #9
0
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);
	}
}