From fc4446b4416bb92b422fffc08c4c244c9dea1139 Mon Sep 17 00:00:00 2001 From: James Liggett Date: Wed, 18 Jun 2008 00:58:15 -0700 Subject: [PATCH] Implement bisecting --- TODO.tasks | 10 +- plugins/git/Makefile.am | 10 +- plugins/git/anjuta-git.glade | 272 +++++++++++++++++++++------ plugins/git/anjuta-git.ui | 25 ++- plugins/git/git-bisect-dialog.c | 332 +++++++++++++++++++++++++++++++++ plugins/git/git-bisect-dialog.h | 43 +++++ plugins/git/git-bisect-reset-command.c | 75 ++++++++ plugins/git/git-bisect-reset-command.h | 58 ++++++ plugins/git/git-bisect-start-command.c | 112 +++++++++++ plugins/git/git-bisect-start-command.h | 63 +++++++ plugins/git/git-bisect-state-command.c | 110 +++++++++++ plugins/git/git-bisect-state-command.h | 69 +++++++ plugins/git/plugin.c | 75 +++++++- plugins/git/plugin.h | 3 + 14 files changed, 1186 insertions(+), 71 deletions(-) create mode 100644 plugins/git/git-bisect-dialog.c create mode 100644 plugins/git/git-bisect-dialog.h create mode 100644 plugins/git/git-bisect-reset-command.c create mode 100644 plugins/git/git-bisect-reset-command.h create mode 100644 plugins/git/git-bisect-start-command.c create mode 100644 plugins/git/git-bisect-start-command.h create mode 100644 plugins/git/git-bisect-state-command.c create mode 100644 plugins/git/git-bisect-state-command.h diff --git a/TODO.tasks b/TODO.tasks index 1dbc5fe6..720128b9 100644 --- a/TODO.tasks +++ b/TODO.tasks @@ -698,11 +698,6 @@ Fix c++/gobject class generator to allow adding members, methods, signals, prope - - Bisecting - - - Ignoring files @@ -740,6 +735,11 @@ Fix c++/gobject class generator to allow adding members, methods, signals, prope Revision filtering/searching + + + + + Bisecting diff --git a/plugins/git/Makefile.am b/plugins/git/Makefile.am index 8f7d4ec3..c8683620 100644 --- a/plugins/git/Makefile.am +++ b/plugins/git/Makefile.am @@ -139,7 +139,15 @@ libanjuta_git_la_SOURCES = \ git-rebase-dialog.c \ git-rebase-dialog.h \ git-rebase-start-command.c \ - git-rebase-start-command.h + git-rebase-start-command.h \ + git-bisect-dialog.c \ + git-bisect-dialog.h \ + git-bisect-reset-command.c \ + git-bisect-reset-command.h \ + git-bisect-start-command.c \ + git-bisect-start-command.h \ + git-bisect-state-command.c \ + git-bisect-state-command.h libanjuta_git_la_LDFLAGS = $(ANJUTA_PLUGIN_LDFLAGS) diff --git a/plugins/git/anjuta-git.glade b/plugins/git/anjuta-git.glade index c9d179b5..45999b55 100644 --- a/plugins/git/anjuta-git.glade +++ b/plugins/git/anjuta-git.glade @@ -1,6 +1,6 @@ - + @@ -1746,27 +1746,16 @@ 2 2 - - True - Author: - - - GTK_SHRINK - GTK_SHRINK - 2 - - - - + True - Grep: + True + 1 + 2 1 2 - - GTK_SHRINK - 2 + @@ -1781,16 +1770,27 @@ - + True - True + Grep: - 1 - 2 1 2 - + + GTK_SHRINK + 2 + + + + + True + Author: + + + GTK_SHRINK + GTK_SHRINK + 2 @@ -1812,57 +1812,57 @@ 2 5 - + True - False True + To + 0 + True 1 2 - 1 - 2 GTK_SHRINK GTK_SHRINK - + True - False True + From + 0 + True - 1 - 2 GTK_SHRINK GTK_SHRINK - + True + False True - From - 0 - True + 1 + 2 GTK_SHRINK GTK_SHRINK - + True + False True - To - 0 - True 1 2 + 1 + 2 GTK_SHRINK GTK_SHRINK @@ -1890,27 +1890,16 @@ 2 2 - - True - From: - - - GTK_SHRINK - GTK_SHRINK - 2 - - - - + True - To: + True + 1 + 2 1 2 - - GTK_SHRINK - 2 + @@ -1925,16 +1914,27 @@ - + True - True + To: - 1 - 2 1 2 - + + GTK_SHRINK + 2 + + + + + True + From: + + + GTK_SHRINK + GTK_SHRINK + 2 @@ -2733,4 +2733,158 @@ + + 5 + Delete Branch + GTK_WIN_POS_CENTER_ON_PARENT + GDK_WINDOW_TYPE_HINT_DIALOG + False + + + True + 2 + + + True + 0 + GTK_SHADOW_NONE + + + True + 12 + + + True + + + True + True + Head + 0 + True + True + + + + + True + + + True + True + Revision: + 0 + True + True + bisect_start_head_radio + + + + + True + False + True + 40 + + + 1 + + + + + 1 + + + + + + + + + True + <b>Bad revision:</b> + True + + + label_item + + + + + False + False + 1 + + + + + True + 0 + GTK_SHADOW_NONE + + + True + 12 + + + True + True + 40 + + + + + + + True + <b>Good revision:</b> + True + + + label_item + + + + + False + False + 2 + + + + + True + GTK_BUTTONBOX_END + + + True + True + True + gtk-cancel + True + -6 + + + + + True + True + True + gtk-ok + True + -5 + + + 1 + + + + + False + GTK_PACK_END + + + + + diff --git a/plugins/git/anjuta-git.ui b/plugins/git/anjuta-git.ui index 39d00bf4..0a314b5d 100644 --- a/plugins/git/anjuta-git.ui +++ b/plugins/git/anjuta-git.ui @@ -22,18 +22,28 @@ - + + + + + + + + + + + - + - - + + @@ -48,5 +58,12 @@ + + + + + + + diff --git a/plugins/git/git-bisect-dialog.c b/plugins/git/git-bisect-dialog.c new file mode 100644 index 00000000..260e2d55 --- /dev/null +++ b/plugins/git/git-bisect-dialog.c @@ -0,0 +1,332 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */ +/* + * anjuta + * Copyright (C) James Liggett 2008 + * + * anjuta is free software. + * + * You may redistribute it and/or modify it under the terms of the + * GNU General Public License, as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * anjuta is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with anjuta. If not, write to: + * The Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor + * Boston, MA 02110-1301, USA. + */ + +#include "git-bisect-dialog.h" + +static void +on_bisect_start_dialog_response (GtkDialog *dialog, gint response_id, + GitUIData *data) +{ + GtkWidget *bisect_start_revision_radio; + GtkWidget *bisect_start_bad_revision_entry; + GtkWidget *bisect_start_good_revision_entry; + const gchar *bad_revision; + const gchar *good_revision; + GitBisectStartCommand *bisect_command; + + if (response_id == GTK_RESPONSE_OK) + { + bisect_start_revision_radio = glade_xml_get_widget (data->gxml, + "bisect_start_revision_radio"); + bisect_start_bad_revision_entry = glade_xml_get_widget (data->gxml, + "bisect_start_bad_revision_entry"); + bisect_start_good_revision_entry = glade_xml_get_widget (data->gxml, + "bisect_start_good_revision_entry"); + bad_revision = ""; + + if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (bisect_start_revision_radio))) + { + bad_revision = gtk_entry_get_text (GTK_ENTRY (bisect_start_bad_revision_entry)); + + if (!check_input (GTK_WIDGET (dialog), bisect_start_bad_revision_entry, + bad_revision, _("Please enter a revision."))) + { + return; + } + } + + good_revision = gtk_entry_get_text (GTK_ENTRY (bisect_start_good_revision_entry)); + + /* Empty revisions means don't give it to bisect. Use gtk_entry_get_text + * so we can re-assign the pointers to NULL without worrying about + * leaks. */ + if (strlen (bad_revision) == 0) + bad_revision = NULL; + + if (strlen (good_revision) == 0) + good_revision = NULL; + + bisect_command = git_bisect_start_command_new (data->plugin->project_root_directory, + bad_revision, + good_revision); + + create_message_view (data->plugin); + + g_signal_connect (G_OBJECT (bisect_command), "command-finished", + G_CALLBACK (on_command_finished), + data->plugin); + + g_signal_connect (G_OBJECT (bisect_command), "data-arrived", + G_CALLBACK (on_command_info_arrived), + data->plugin); + + anjuta_command_start (ANJUTA_COMMAND (bisect_command)); + } + + gtk_widget_destroy (GTK_WIDGET (dialog)); + git_ui_data_free (data); +} + +static void +on_bisect_start_revision_radio_toggled (GtkToggleButton *toggle_button, + GitUIData *data) +{ + GtkWidget *bisect_start_dialog; + GtkWidget *bisect_start_revision_entry; + gboolean active; + + bisect_start_dialog = glade_xml_get_widget (data->gxml, + "bisect_start_dialog"); + bisect_start_revision_entry = glade_xml_get_widget (data->gxml, + "bisect_start_bad_revision_entry"); + + active = gtk_toggle_button_get_active (toggle_button); + gtk_widget_set_sensitive (bisect_start_revision_entry, active); + + if (active) + { + gtk_window_set_focus (GTK_WINDOW (bisect_start_dialog), + bisect_start_revision_entry); + } + +} + +static void +bisect_start_dialog (Git *plugin) +{ + GladeXML *gxml; + GtkWidget *dialog; + GtkWidget *bisect_start_revision_radio; + GitUIData *data; + + gxml = glade_xml_new (GLADE_FILE, "bisect_start_dialog", NULL); + dialog = glade_xml_get_widget (gxml, "bisect_start_dialog"); + bisect_start_revision_radio = glade_xml_get_widget (gxml, + "bisect_start_revision_radio"); + data = git_ui_data_new (plugin, gxml); + + g_signal_connect (G_OBJECT (dialog), "response", + G_CALLBACK (on_bisect_start_dialog_response), + data); + + g_signal_connect (G_OBJECT (bisect_start_revision_radio), "toggled", + G_CALLBACK (on_bisect_start_revision_radio_toggled), + data); + + gtk_widget_show_all (dialog); +} + +static void +bisect_reset (Git *plugin) +{ + GitBisectResetCommand *bisect_command; + + bisect_command = git_bisect_reset_command_new (plugin->project_root_directory); + + create_message_view (plugin); + + g_signal_connect (G_OBJECT (bisect_command), "command-finished", + G_CALLBACK (on_command_finished), + plugin); + + g_signal_connect (G_OBJECT (bisect_command), "data-arrived", + G_CALLBACK (on_command_info_arrived), + plugin); + + anjuta_command_start (ANJUTA_COMMAND (bisect_command)); +} + +static void +bisect_state (Git *plugin, GitBisectState state, const gchar *revision) +{ + GitBisectStateCommand *bisect_command; + + bisect_command = git_bisect_state_command_new (plugin->project_root_directory, + state, revision); + + create_message_view (plugin); + + g_signal_connect (G_OBJECT (bisect_command), "command-finished", + G_CALLBACK (on_command_finished), + plugin); + + g_signal_connect (G_OBJECT (bisect_command), "data-arrived", + G_CALLBACK (on_command_info_arrived), + plugin); + + anjuta_command_start (ANJUTA_COMMAND (bisect_command)); +} + +static void +update_bisect_menus (AnjutaUI *ui, gboolean in_bisect) +{ + GtkAction *bisect_start_action; + GtkAction *bisect_reset_action; + GtkAction *bisect_good_action; + GtkAction *bisect_bad_action; + GtkAction *bisect_log_menu_action; + + bisect_start_action = anjuta_ui_get_action (ui, "ActionGroupGit", + "ActionGitBisectStart"); + bisect_reset_action = anjuta_ui_get_action (ui, "ActionGroupGit", + "ActionGitBisectReset"); + bisect_good_action = anjuta_ui_get_action (ui, "ActionGroupGit", + "ActionGitBisectGood"); + bisect_bad_action = anjuta_ui_get_action (ui, "ActionGroupGit", + "ActionGitBisectBad"); + bisect_log_menu_action = anjuta_ui_get_action (ui, "ActionGroupGitLog", + "ActionMenuGitLogBisect"); + + if (in_bisect) + { + gtk_action_set_sensitive (bisect_start_action, FALSE); + gtk_action_set_sensitive (bisect_reset_action, TRUE); + gtk_action_set_sensitive (bisect_good_action, TRUE); + gtk_action_set_sensitive (bisect_bad_action, TRUE); + gtk_action_set_sensitive (bisect_log_menu_action, TRUE); + } + else + { + gtk_action_set_sensitive (bisect_start_action, TRUE); + gtk_action_set_sensitive (bisect_reset_action, FALSE); + gtk_action_set_sensitive (bisect_good_action, FALSE); + gtk_action_set_sensitive (bisect_bad_action, FALSE); + gtk_action_set_sensitive (bisect_log_menu_action, FALSE); + } +} + +static void +on_bisect_file_monitor_changed (GFileMonitor *file_monitor, GFile *file, + GFile *other_file, GFileMonitorEvent event_type, + AnjutaUI *ui) +{ + switch (event_type) + { + case G_FILE_MONITOR_EVENT_CREATED: + /* This indicates that a bisect has started */ + update_bisect_menus (ui, TRUE); + break; + case G_FILE_MONITOR_EVENT_DELETED: + /* This indicates that a bisect has started */ + update_bisect_menus (ui, FALSE); + break; + default: + break; + } + +} + +void +on_menu_git_bisect_start (GtkAction *action, Git *plugin) +{ + bisect_start_dialog (plugin); +} + +void +on_menu_git_bisect_reset (GtkAction *action, Git *plugin) +{ + bisect_reset (plugin); +} + +void +on_menu_git_bisect_good (GtkAction *action, Git *plugin) +{ + bisect_state (plugin, GIT_BISECT_STATE_GOOD, NULL); +} + +void +on_menu_git_bisect_bad (GtkAction *action, Git *plugin) +{ + bisect_state (plugin, GIT_BISECT_STATE_BAD, NULL); +} + +void +on_log_menu_git_bisect_good (GtkAction *action, Git *plugin) +{ + GitRevision *revision; + gchar *sha; + + revision = git_log_get_selected_revision (plugin); + + if (revision) + { + sha = git_revision_get_sha (revision); + + bisect_state (plugin, GIT_BISECT_STATE_GOOD, sha); + g_free (sha); + } +} + +void +on_log_menu_git_bisect_bad (GtkAction *action, Git *plugin) +{ + GitRevision *revision; + gchar *sha; + + revision = git_log_get_selected_revision (plugin); + + if (revision) + { + sha = git_revision_get_sha (revision); + + bisect_state (plugin, GIT_BISECT_STATE_BAD, sha); + g_free (sha); + } +} + +GFileMonitor * +bisect_menus_init (Git *plugin) +{ + AnjutaUI *ui; + gchar *bisect_log_path; + GFile *bisect_log_file; + GFileMonitor *bisect_file_monitor; + + ui = anjuta_shell_get_ui (ANJUTA_PLUGIN (plugin)->shell, NULL); + + /* Git keeps a bisect log file in a project's top-level .git directory. + * The presence of this file indicates that a bisect is in progress. + * We'll monitor the creation/deletion of this file to detect the + * occurrence of new bisect operations and the conclusions of existing ones + * and update the UI accordingly. */ + bisect_log_path = g_strjoin (G_DIR_SEPARATOR_S, + plugin->project_root_directory, + ".git", + "BISECT_LOG", + NULL); + + update_bisect_menus (ui, g_file_test (bisect_log_path, G_FILE_TEST_EXISTS)); + + bisect_log_file = g_file_new_for_path (bisect_log_path); + bisect_file_monitor = g_file_monitor_file (bisect_log_file, 0, NULL, NULL); + + g_signal_connect (G_OBJECT (bisect_file_monitor), "changed", + G_CALLBACK (on_bisect_file_monitor_changed), + ui); + + g_object_unref (bisect_log_file); + g_free (bisect_log_path); + + return bisect_file_monitor; +} diff --git a/plugins/git/git-bisect-dialog.h b/plugins/git/git-bisect-dialog.h new file mode 100644 index 00000000..9dddbb27 --- /dev/null +++ b/plugins/git/git-bisect-dialog.h @@ -0,0 +1,43 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */ +/* + * anjuta + * Copyright (C) James Liggett 2008 + * + * anjuta is free software. + * + * You may redistribute it and/or modify it under the terms of the + * GNU General Public License, as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * anjuta is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with anjuta. If not, write to: + * The Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor + * Boston, MA 02110-1301, USA. + */ + +#ifndef _GIT_BISECT_DIALOG_H +#define _GIT_BISECT_DIALOG_H + +#include "git-bisect-start-command.h" +#include "git-bisect-reset-command.h" +#include "git-bisect-state-command.h" +#include "git-log-dialog.h" +#include "git-ui-utils.h" + +void on_menu_git_bisect_start (GtkAction *action, Git *plugin); +void on_menu_git_bisect_reset (GtkAction *action, Git *plguin); +void on_menu_git_bisect_good (GtkAction *action, Git *plugin); +void on_menu_git_bisect_bad (GtkAction *action, Git *plugin); +void on_log_menu_git_bisect_good (GtkAction *action, Git *plugin); +void on_log_menu_git_bisect_bad (GtkAction *action, Git *plugin); + +GFileMonitor *bisect_menus_init (Git *plugin); + +#endif diff --git a/plugins/git/git-bisect-reset-command.c b/plugins/git/git-bisect-reset-command.c new file mode 100644 index 00000000..715af75e --- /dev/null +++ b/plugins/git/git-bisect-reset-command.c @@ -0,0 +1,75 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */ +/* + * anjuta + * Copyright (C) James Liggett 2008 + * + * anjuta is free software. + * + * You may redistribute it and/or modify it under the terms of the + * GNU General Public License, as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * anjuta is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with anjuta. If not, write to: + * The Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor + * Boston, MA 02110-1301, USA. + */ + +#include "git-bisect-reset-command.h" + +G_DEFINE_TYPE (GitBisectResetCommand, git_bisect_reset_command, + GIT_TYPE_COMMAND); + +static void +git_bisect_reset_command_init (GitBisectResetCommand *self) +{ + +} + +static void +git_bisect_reset_command_finalize (GObject *object) +{ + G_OBJECT_CLASS (git_bisect_reset_command_parent_class)->finalize (object); +} + +static guint +git_bisect_reset_command_run (AnjutaCommand *command) +{ + GitBisectResetCommand *self; + + self = GIT_BISECT_RESET_COMMAND (command); + + git_command_add_arg (GIT_COMMAND (command), "bisect"); + git_command_add_arg (GIT_COMMAND (command), "reset"); + + return 0; +} + +static void +git_bisect_reset_command_class_init (GitBisectResetCommandClass *klass) +{ + GObjectClass* object_class = G_OBJECT_CLASS (klass); + GitCommandClass* parent_class = GIT_COMMAND_CLASS (klass); + AnjutaCommandClass* command_class = ANJUTA_COMMAND_CLASS (klass); + + object_class->finalize = git_bisect_reset_command_finalize; + parent_class->output_handler = git_command_send_output_to_info; + command_class->run = git_bisect_reset_command_run; +} + + +GitBisectResetCommand * +git_bisect_reset_command_new (const gchar *working_directory) +{ + return g_object_new (GIT_TYPE_BISECT_RESET_COMMAND, + "working-directory", working_directory, + "single-line-output", TRUE, + NULL); +} diff --git a/plugins/git/git-bisect-reset-command.h b/plugins/git/git-bisect-reset-command.h new file mode 100644 index 00000000..f35fbe55 --- /dev/null +++ b/plugins/git/git-bisect-reset-command.h @@ -0,0 +1,58 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */ +/* + * anjuta + * Copyright (C) James Liggett 2008 + * + * anjuta is free software. + * + * You may redistribute it and/or modify it under the terms of the + * GNU General Public License, as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * anjuta is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with anjuta. If not, write to: + * The Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor + * Boston, MA 02110-1301, USA. + */ + +#ifndef _GIT_BISECT_RESET_COMMAND_H_ +#define _GIT_BISECT_RESET_COMMAND_H_ + +#include +#include "git-command.h" + +G_BEGIN_DECLS + +#define GIT_TYPE_BISECT_RESET_COMMAND (git_bisect_reset_command_get_type ()) +#define GIT_BISECT_RESET_COMMAND(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIT_TYPE_BISECT_RESET_COMMAND, GitBisectResetCommand)) +#define GIT_BISECT_RESET_COMMAND_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIT_TYPE_BISECT_RESET_COMMAND, GitBisectResetCommandClass)) +#define GIT_IS_BISECT_RESET_COMMAND(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIT_TYPE_BISECT_RESET_COMMAND)) +#define GIT_IS_BISECT_RESET_COMMAND_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIT_TYPE_BISECT_RESET_COMMAND)) +#define GIT_BISECT_RESET_COMMAND_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIT_TYPE_BISECT_RESET_COMMAND, GitBisectResetCommandClass)) + +typedef struct _GitBisectResetCommandClass GitBisectResetCommandClass; +typedef struct _GitBisectResetCommand GitBisectResetCommand; + +struct _GitBisectResetCommandClass +{ + GitCommandClass parent_class; +}; + +struct _GitBisectResetCommand +{ + GitCommand parent_instance; +}; + +GType git_bisect_reset_command_get_type (void) G_GNUC_CONST; +GitBisectResetCommand *git_bisect_reset_command_new (const gchar *working_directory); + +G_END_DECLS + +#endif /* _GIT_BISECT_RESET_COMMAND_H_ */ diff --git a/plugins/git/git-bisect-start-command.c b/plugins/git/git-bisect-start-command.c new file mode 100644 index 00000000..09a774bf --- /dev/null +++ b/plugins/git/git-bisect-start-command.c @@ -0,0 +1,112 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */ +/* + * anjuta + * Copyright (C) James Liggett 2008 + * + * anjuta is free software. + * + * You may redistribute it and/or modify it under the terms of the + * GNU General Public License, as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * anjuta is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with anjuta. If not, write to: + * The Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor + * Boston, MA 02110-1301, USA. + */ + +#include "git-bisect-start-command.h" + +struct _GitBisectStartCommandPriv +{ + gchar *bad_revision; + gchar *good_revision; +}; + +G_DEFINE_TYPE (GitBisectStartCommand, git_bisect_start_command, + GIT_TYPE_COMMAND); + +static void +git_bisect_start_command_init (GitBisectStartCommand *self) +{ + self->priv = g_new0 (GitBisectStartCommandPriv, 1); +} + +static void +git_bisect_start_command_finalize (GObject *object) +{ + GitBisectStartCommand *self; + + self = GIT_BISECT_START_COMMAND (object); + + g_free (self->priv->bad_revision); + g_free (self->priv->good_revision); + g_free (self->priv); + + G_OBJECT_CLASS (git_bisect_start_command_parent_class)->finalize (object); +} + +static guint +git_bisect_start_command_run (AnjutaCommand *command) +{ + GitBisectStartCommand *self; + + self = GIT_BISECT_START_COMMAND (command); + + git_command_add_arg (GIT_COMMAND (command), "bisect"); + git_command_add_arg (GIT_COMMAND (command), "start"); + + if (self->priv->bad_revision) + git_command_add_arg (GIT_COMMAND (command), self->priv->bad_revision); + + /* If a good revision was given with no bad revision, put head in for the + * bad revision, because git expects both revisions in this case, so don't + * confuse it. */ + if (self->priv->good_revision) + { + if (!self->priv->bad_revision) + git_command_add_arg (GIT_COMMAND (command), "HEAD"); + + git_command_add_arg (GIT_COMMAND (command), self->priv->good_revision); + } + + return 0; +} + +static void +git_bisect_start_command_class_init (GitBisectStartCommandClass *klass) +{ + GObjectClass* object_class = G_OBJECT_CLASS (klass); + GitCommandClass* parent_class = GIT_COMMAND_CLASS (klass); + AnjutaCommandClass* command_class = ANJUTA_COMMAND_CLASS (klass); + + object_class->finalize = git_bisect_start_command_finalize; + parent_class->output_handler = git_command_send_output_to_info; + command_class->run = git_bisect_start_command_run; +} + + +GitBisectStartCommand * +git_bisect_start_command_new (const gchar *working_directory, + const gchar *bad_revision, + const gchar *good_revision) +{ + GitBisectStartCommand *self; + + self = g_object_new (GIT_TYPE_BISECT_START_COMMAND, + "working-directory", working_directory, + "single-line-output", TRUE, + NULL); + + self->priv->bad_revision = g_strdup (bad_revision); + self->priv->good_revision = g_strdup (good_revision); + + return self; +} diff --git a/plugins/git/git-bisect-start-command.h b/plugins/git/git-bisect-start-command.h new file mode 100644 index 00000000..b5a54555 --- /dev/null +++ b/plugins/git/git-bisect-start-command.h @@ -0,0 +1,63 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */ +/* + * anjuta + * Copyright (C) James Liggett 2008 + * + * anjuta is free software. + * + * You may redistribute it and/or modify it under the terms of the + * GNU General Public License, as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * anjuta is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with anjuta. If not, write to: + * The Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor + * Boston, MA 02110-1301, USA. + */ + +#ifndef _GIT_BISECT_START_COMMAND_H_ +#define _GIT_BISECT_START_COMMAND_H_ + +#include +#include "git-command.h" + +G_BEGIN_DECLS + +#define GIT_TYPE_BISECT_START_COMMAND (git_bisect_start_command_get_type ()) +#define GIT_BISECT_START_COMMAND(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIT_TYPE_BISECT_START_COMMAND, GitBisectStartCommand)) +#define GIT_BISECT_START_COMMAND_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIT_TYPE_BISECT_START_COMMAND, GitBisectStartCommandClass)) +#define GIT_IS_BISECT_START_COMMAND(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIT_TYPE_BISECT_START_COMMAND)) +#define GIT_IS_BISECT_START_COMMAND_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIT_TYPE_BISECT_START_COMMAND)) +#define GIT_BISECT_START_COMMAND_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIT_TYPE_BISECT_START_COMMAND, GitBisectStartCommandClass)) + +typedef struct _GitBisectStartCommandClass GitBisectStartCommandClass; +typedef struct _GitBisectStartCommand GitBisectStartCommand; +typedef struct _GitBisectStartCommandPriv GitBisectStartCommandPriv; + +struct _GitBisectStartCommandClass +{ + GitCommandClass parent_class; +}; + +struct _GitBisectStartCommand +{ + GitCommand parent_instance; + + GitBisectStartCommandPriv *priv; +}; + +GType git_bisect_start_command_get_type (void) G_GNUC_CONST; +GitBisectStartCommand *git_bisect_start_command_new (const gchar *working_directory, + const gchar *bad_revision, + const gchar *good_revision); + +G_END_DECLS + +#endif /* _GIT_BISECT_START_COMMAND_H_ */ diff --git a/plugins/git/git-bisect-state-command.c b/plugins/git/git-bisect-state-command.c new file mode 100644 index 00000000..93be5c37 --- /dev/null +++ b/plugins/git/git-bisect-state-command.c @@ -0,0 +1,110 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */ +/* + * anjuta + * Copyright (C) James Liggett 2008 + * + * anjuta is free software. + * + * You may redistribute it and/or modify it under the terms of the + * GNU General Public License, as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * anjuta is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with anjuta. If not, write to: + * The Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor + * Boston, MA 02110-1301, USA. + */ + +#include "git-bisect-state-command.h" + +struct _GitBisectStateCommandPriv +{ + GitBisectState state; + gchar *revision; +}; + +G_DEFINE_TYPE (GitBisectStateCommand, git_bisect_state_command, + GIT_TYPE_COMMAND); + +static void +git_bisect_state_command_init (GitBisectStateCommand *self) +{ + self->priv = g_new0 (GitBisectStateCommandPriv, 1); +} + +static void +git_bisect_state_command_finalize (GObject *object) +{ + GitBisectStateCommand *self; + + self = GIT_BISECT_STATE_COMMAND (object); + + g_free (self->priv->revision); + g_free (self->priv); + + G_OBJECT_CLASS (git_bisect_state_command_parent_class)->finalize (object); +} + +static guint +git_bisect_state_command_run (AnjutaCommand *command) +{ + GitBisectStateCommand *self; + + self = GIT_BISECT_STATE_COMMAND (command); + + git_command_add_arg (GIT_COMMAND (command), "bisect"); + + switch (self->priv->state) + { + case GIT_BISECT_STATE_GOOD: + git_command_add_arg (GIT_COMMAND (command), "good"); + break; + case GIT_BISECT_STATE_BAD: + git_command_add_arg (GIT_COMMAND (command), "bad"); + break; + default: + break; + } + + if (self->priv->revision) + git_command_add_arg (GIT_COMMAND (command), self->priv->revision); + + return 0; +} + +static void +git_bisect_state_command_class_init (GitBisectStateCommandClass *klass) +{ + GObjectClass* object_class = G_OBJECT_CLASS (klass); + GitCommandClass* parent_class = GIT_COMMAND_CLASS (klass); + AnjutaCommandClass* command_class = ANJUTA_COMMAND_CLASS (klass); + + object_class->finalize = git_bisect_state_command_finalize; + parent_class->output_handler = git_command_send_output_to_info; + command_class->run = git_bisect_state_command_run; +} + + +GitBisectStateCommand * +git_bisect_state_command_new (const gchar *working_directory, + GitBisectState state, const gchar *revision) +{ + GitBisectStateCommand *self; + + self = g_object_new (GIT_TYPE_BISECT_STATE_COMMAND, + "working-directory", working_directory, + "single-line-output", TRUE, + NULL); + + self->priv->state = state; + self->priv->revision = g_strdup (revision); + + return self; +} diff --git a/plugins/git/git-bisect-state-command.h b/plugins/git/git-bisect-state-command.h new file mode 100644 index 00000000..01339b71 --- /dev/null +++ b/plugins/git/git-bisect-state-command.h @@ -0,0 +1,69 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */ +/* + * anjuta + * Copyright (C) James Liggett 2008 + * + * anjuta is free software. + * + * You may redistribute it and/or modify it under the terms of the + * GNU General Public License, as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * anjuta is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with anjuta. If not, write to: + * The Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor + * Boston, MA 02110-1301, USA. + */ + +#ifndef _GIT_BISECT_STATE_COMMAND_H_ +#define _GIT_BISECT_STATE_COMMAND_H_ + +#include +#include "git-command.h" + +G_BEGIN_DECLS + +#define GIT_TYPE_BISECT_STATE_COMMAND (git_bisect_state_command_get_type ()) +#define GIT_BISECT_STATE_COMMAND(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIT_TYPE_BISECT_STATE_COMMAND, GitBisectStateCommand)) +#define GIT_BISECT_STATE_COMMAND_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIT_TYPE_BISECT_STATE_COMMAND, GitBisectStateCommandClass)) +#define GIT_IS_BISECT_STATE_COMMAND(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIT_TYPE_BISECT_STATE_COMMAND)) +#define GIT_IS_BISECT_STATE_COMMAND_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIT_TYPE_BISECT_STATE_COMMAND)) +#define GIT_BISECT_STATE_COMMAND_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIT_TYPE_BISECT_STATE_COMMAND, GitBisectStateCommandClass)) + +typedef struct _GitBisectStateCommandClass GitBisectStateCommandClass; +typedef struct _GitBisectStateCommand GitBisectStateCommand; +typedef struct _GitBisectStateCommandPriv GitBisectStateCommandPriv; + +typedef enum +{ + GIT_BISECT_STATE_GOOD, + GIT_BISECT_STATE_BAD +} GitBisectState; + +struct _GitBisectStateCommandClass +{ + GitCommandClass parent_class; +}; + +struct _GitBisectStateCommand +{ + GitCommand parent_instance; + + GitBisectStateCommandPriv *priv; +}; + +GType git_bisect_state_command_get_type (void) G_GNUC_CONST; +GitBisectStateCommand *git_bisect_state_command_new (const gchar *working_directory, + GitBisectState state, + const gchar *revision); + +G_END_DECLS + +#endif /* _GIT_BISECT_STATE_COMMAND_H_ */ diff --git a/plugins/git/plugin.c b/plugins/git/plugin.c index 05ef436e..4d85148d 100644 --- a/plugins/git/plugin.c +++ b/plugins/git/plugin.c @@ -37,6 +37,7 @@ #include "git-revert-dialog.h" #include "git-fetch-dialog.h" #include "git-rebase-dialog.h" +#include "git-bisect-dialog.h" #define UI_FILE PACKAGE_DATA_DIR"/ui/anjuta-git.ui" @@ -149,6 +150,46 @@ static GtkActionEntry actions_git[] = G_CALLBACK (on_menu_git_revert) /* action callback */ }, { + "ActionMenuGitBisect", /* Action name */ + NULL, /* Stock icon, if any */ + N_("_Bisect"), /* Display label */ + NULL, /* short-cut */ + NULL, /* Tooltip */ + NULL /* action callback */ + }, + { + "ActionGitBisectStart", /* Action name */ + GTK_STOCK_MEDIA_PLAY, /* Stock icon, if any */ + N_("_Start..."), /* Display label */ + NULL, /* short-cut */ + NULL, /* Tooltip */ + G_CALLBACK (on_menu_git_bisect_start) /* action callback */ + }, + { + "ActionGitBisectReset", /* Action name */ + GTK_STOCK_REFRESH, /* Stock icon, if any */ + N_("_Reset"), /* Display label */ + NULL, /* short-cut */ + NULL, /* Tooltip */ + G_CALLBACK (on_menu_git_bisect_reset) /* action callback */ + }, + { + "ActionGitBisectGood", /* Action name */ + GTK_STOCK_YES, /* Stock icon, if any */ + N_("_Good"), /* Display label */ + NULL, /* short-cut */ + NULL, /* Tooltip */ + G_CALLBACK (on_menu_git_bisect_good) /* action callback */ + }, + { + "ActionGitBisectBad", /* Action name */ + GTK_STOCK_NO, /* Stock icon, if any */ + N_("_Bad"), /* Display label */ + NULL, /* short-cut */ + NULL, /* Tooltip */ + G_CALLBACK (on_menu_git_bisect_bad) /* action callback */ + }, + { "ActionGitLog", /* Action name */ GTK_STOCK_ZOOM_100, /* Stock icon, if any */ N_("_View log..."), /* Display label */ @@ -263,6 +304,30 @@ static GtkActionEntry actions_log[] = NULL, /* short-cut */ NULL, /* Tooltip */ G_CALLBACK (on_log_menu_git_revert) /* action callback */ + }, + { + "ActionMenuGitLogBisect", /* Action name */ + NULL, /* Stock icon, if any */ + N_("_Bisect"), /* Display label */ + NULL, /* short-cut */ + NULL, /* Tooltip */ + NULL /* action callback */ + }, + { + "ActionGitLogBisectGood", /* Action name */ + GTK_STOCK_YES, /* Stock icon, if any */ + N_("_Set good revision"), /* Display label */ + NULL, /* short-cut */ + NULL, /* Tooltip */ + G_CALLBACK (on_log_menu_git_bisect_good) /* action callback */ + }, + { + "ActionGitLogBisectBad", /* Action name */ + GTK_STOCK_NO, /* Stock icon, if any */ + N_("_Set bad revision"), /* Display label */ + NULL, /* short-cut */ + NULL, /* Tooltip */ + G_CALLBACK (on_log_menu_git_bisect_bad) /* action callback */ } }; @@ -273,6 +338,7 @@ on_project_root_added (AnjutaPlugin *plugin, const gchar *name, Git *git_plugin; gchar *project_root_uri; GFile *file; + AnjutaUI *ui; GtkAction *git_menu_action; git_plugin = ANJUTA_PLUGIN_GIT (plugin); @@ -283,8 +349,8 @@ on_project_root_added (AnjutaPlugin *plugin, const gchar *name, git_plugin->project_root_directory = g_file_get_path (file); g_object_unref (file); - git_menu_action = anjuta_ui_get_action (anjuta_shell_get_ui (plugin->shell, - NULL), + ui = anjuta_shell_get_ui (plugin->shell, NULL); + git_menu_action = anjuta_ui_get_action (ui, "ActionGroupGit", "ActionMenuGit"); @@ -292,6 +358,8 @@ on_project_root_added (AnjutaPlugin *plugin, const gchar *name, gtk_widget_set_sensitive (git_plugin->log_viewer, TRUE); g_free (project_root_uri); + + git_plugin->bisect_file_monitor = bisect_menus_init (git_plugin); } static void @@ -314,6 +382,9 @@ on_project_root_removed (AnjutaPlugin *plugin, const gchar *name, gtk_action_set_sensitive (git_menu_action, FALSE); gtk_widget_set_sensitive (git_plugin->log_viewer, FALSE); git_log_window_clear (git_plugin); + + g_file_monitor_cancel (git_plugin->bisect_file_monitor); + g_object_unref (git_plugin->bisect_file_monitor); } static void diff --git a/plugins/git/plugin.h b/plugins/git/plugin.h index 2d6e896c..339f5065 100644 --- a/plugins/git/plugin.h +++ b/plugins/git/plugin.h @@ -58,6 +58,9 @@ struct _Git GtkWidget *log_viewer; GtkWidget *log_popup_menu; + + /* File monitors */ + GFileMonitor *bisect_file_monitor; }; struct _GitClass -- 2.11.4.GIT