[gitg] Implemented cherry-picking
- From: Jesse van den Kieboom <jessevdk src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [gitg] Implemented cherry-picking
- Date: Sat, 9 Jan 2010 23:07:24 +0000 (UTC)
commit 684f9172e90670683b12dc0c64ffb7c1e5086132
Author: Jesse van den Kieboom <jessevdk gnome org>
Date: Sat Jan 9 22:18:28 2010 +0100
Implemented cherry-picking
gitg/gitg-branch-actions.c | 182 ++++++++++++++++++++++++++++++++++++++++++++
gitg/gitg-branch-actions.h | 2 +
gitg/gitg-dnd.c | 26 +++++--
gitg/gitg-dnd.h | 8 ++-
gitg/gitg-window.c | 43 ++++++++++-
5 files changed, 253 insertions(+), 8 deletions(-)
---
diff --git a/gitg/gitg-branch-actions.c b/gitg/gitg-branch-actions.c
index 7f83bee..68f9a17 100644
--- a/gitg/gitg-branch-actions.c
+++ b/gitg/gitg-branch-actions.c
@@ -1594,3 +1594,185 @@ gitg_branch_actions_tag (GitgWindow *window, gchar const *sha1, gchar const *nam
return TRUE;
}
}
+
+typedef struct
+{
+ GitgRevision *revision;
+ GitgRef *dest;
+
+ gchar *stashcommit;
+ GitgRef *head;
+} CherryPickInfo;
+
+static CherryPickInfo *
+cherry_pick_info_new (GitgRevision *revision, GitgRef *dest)
+{
+ CherryPickInfo *ret = g_slice_new0 (CherryPickInfo);
+
+ ret->revision = gitg_revision_ref (revision);
+ ret->dest = gitg_ref_copy (dest);
+
+ return ret;
+}
+
+static void
+cherry_pick_info_free (CherryPickInfo *info)
+{
+ gitg_revision_unref (info->revision);
+ gitg_ref_free (info->dest);
+
+ g_free (info->stashcommit);
+ gitg_ref_free (info->head);
+
+ g_slice_free (CherryPickInfo, info);
+}
+
+static void
+on_cherry_pick_result (GitgWindow *window,
+ GitgProgress progress,
+ gpointer data)
+{
+ CherryPickInfo *info = (CherryPickInfo *)data;
+
+ if (progress == GITG_PROGRESS_ERROR)
+ {
+ gchar const *message;
+
+ message_dialog (window,
+ GTK_MESSAGE_ERROR,
+ _("Failed to cherry-pick on <%s>"),
+ NULL,
+ NULL,
+ gitg_ref_get_shortname (info->dest));
+ }
+ else if (progress == GITG_PROGRESS_SUCCESS)
+ {
+ GitgRepository *repository = gitg_window_get_repository (window);
+
+ // Checkout head
+ if (!checkout_local_branch_real (window, info->head))
+ {
+ gchar const *message = NULL;
+
+ if (info->stashcommit)
+ {
+ gitg_repository_commandv (repository, NULL,
+ "update-ref", "-m", "gitg autosave stash",
+ "refs/stash", info->stashcommit, NULL);
+
+ message = _("The stashed changes have been stored to be reapplied manually");
+ }
+
+ message_dialog (window,
+ GTK_MESSAGE_ERROR,
+ _("Failed to checkout previously checked out branch"),
+ message,
+ NULL);
+ }
+ else if (info->stashcommit)
+ {
+ // Reapply stash
+ if (!gitg_repository_commandv (gitg_window_get_repository (window),
+ NULL,
+ "stash",
+ "apply",
+ "--index",
+ info->stashcommit,
+ NULL))
+ {
+ gitg_repository_commandv (repository, NULL,
+ "update-ref", "-m", "gitg autosave stash",
+ "refs/stash", info->stashcommit, NULL);
+
+ message_dialog (window,
+ GTK_MESSAGE_ERROR,
+ _("Failed to reapply stash correctly"),
+ _("There might be unresolved conflicts in the working tree or index which you need to resolve manually"),
+ NULL);
+ }
+ }
+
+ gitg_repository_reload (gitg_window_get_repository (window));
+ }
+
+ cherry_pick_info_free (info);
+}
+
+GitgRunner *
+gitg_branch_actions_cherry_pick (GitgWindow *window,
+ GitgRevision *revision,
+ GitgRef *dest)
+{
+ g_return_val_if_fail (GITG_IS_WINDOW (window), NULL);
+ g_return_val_if_fail (revision != NULL, NULL);
+ g_return_val_if_fail (dest != NULL, NULL);
+
+ gchar *message = g_strdup_printf (_("Are you sure you want to cherry-pick that revision on <%s>?"),
+ gitg_ref_get_shortname (dest));
+
+ if (message_dialog (window,
+ GTK_MESSAGE_QUESTION,
+ _("Cherry-pick"),
+ message,
+ _("Cherry-pick")) != GTK_RESPONSE_ACCEPT)
+ {
+ g_free (message);
+ return NULL;
+ }
+
+ gchar *stashcommit;
+
+ if (!stash_changes (window, &stashcommit, FALSE))
+ {
+ return NULL;
+ }
+
+ GitgRepository *repository = gitg_window_get_repository (window);
+ GitgRef *head = gitg_repository_get_current_working_ref (repository);
+
+ // First checkout the correct branch on which to cherry-pick
+ if (!gitg_repository_commandv (repository,
+ NULL,
+ "checkout",
+ gitg_ref_get_shortname (dest),
+ NULL))
+ {
+ g_free (stashcommit);
+
+ message_dialog (window,
+ GTK_MESSAGE_ERROR,
+ _("Failed to checkout local branch <%s>"),
+ _("The branch on which to cherry-pick could not be checked out"),
+ NULL,
+ gitg_ref_get_shortname (dest));
+
+ return NULL;
+ }
+
+ message = g_strdup_printf (_("Cherry-picking on <%s>"),
+ gitg_ref_get_shortname (dest));
+
+ GitgRunner *ret;
+
+ CherryPickInfo *info = cherry_pick_info_new (revision, dest);
+
+ info->stashcommit = stashcommit;
+ info->head = gitg_ref_copy (head);
+
+ gchar *sha1 = gitg_revision_get_sha1 (revision);
+
+ ret = run_progress (window,
+ _("Cherry-pick"),
+ message,
+ on_cherry_pick_result,
+ info,
+ "cherry-pick",
+ sha1,
+ NULL);
+
+ g_free (message);
+ gitg_ref_free (head);
+ g_free (sha1);
+
+ return ret;
+}
diff --git a/gitg/gitg-branch-actions.h b/gitg/gitg-branch-actions.h
index 80ab57d..b7b5859 100644
--- a/gitg/gitg-branch-actions.h
+++ b/gitg/gitg-branch-actions.h
@@ -42,6 +42,8 @@ gboolean gitg_branch_actions_apply_stash (GitgWindow *window, GitgRef *stash, Gi
gboolean gitg_branch_actions_tag (GitgWindow *window, gchar const *sha1, gchar const *name, gchar const *message, gboolean sign);
+GitgRunner *gitg_branch_actions_cherry_pick (GitgWindow *window, GitgRevision *revision, GitgRef *dest);
+
G_END_DECLS
#endif /* __GITG_BRANCH_ACTIONS_H__ */
diff --git a/gitg/gitg-dnd.c b/gitg/gitg-dnd.c
index 72152a1..949f096 100644
--- a/gitg/gitg-dnd.c
+++ b/gitg/gitg-dnd.c
@@ -29,6 +29,7 @@ typedef struct
GitgRef *cursor_ref;
GitgDndCallback callback;
+ GitgDndRevisionCallback revision_callback;
gpointer callback_data;
gdouble x;
@@ -554,7 +555,7 @@ gitg_drag_source_motion_cb (GtkWidget *widget,
guint time,
GitgDndData *data)
{
- if (!data->ref)
+ if (!data->ref && !data->revision)
{
return FALSE;
}
@@ -587,13 +588,18 @@ gitg_drag_source_motion_cb (GtkWidget *widget,
gtk_widget_queue_draw (widget);
}
- if (data->callback)
+ if (data->ref && data->callback)
{
data->callback (data->ref, ref, FALSE, data->callback_data);
}
+ else if (data->revision && data->revision_callback)
+ {
+ data->revision_callback (data->revision, ref, FALSE, data->callback_data);
+ }
}
- if (ref && can_drop (data->ref, ref))
+ if ((data->ref && ref && can_drop (data->ref, ref)) ||
+ (data->revision && ref && gitg_ref_get_ref_type (ref) == GITG_REF_TYPE_BRANCH))
{
if (ref != data->target)
{
@@ -627,17 +633,21 @@ gitg_drag_source_drop_cb (GtkWidget *widget,
guint time,
GitgDndData *data)
{
- if (!data->ref || !data->target)
+ if (!(data->ref || data->revision) || !data->target)
{
return FALSE;
}
gboolean ret = FALSE;
- if (data->callback)
+ if (data->ref && data->callback)
{
ret = data->callback (data->ref, data->target, TRUE, data->callback_data);
}
+ else if (data->revision && data->revision_callback)
+ {
+ ret = data->revision_callback (data->revision, data->target, TRUE, data->callback_data);
+ }
gtk_drag_finish (context, ret, FALSE, time);
return ret;
@@ -784,7 +794,10 @@ gitg_drag_source_data_get_cb (GtkWidget *widget,
}
void
-gitg_dnd_enable (GtkTreeView *tree_view, GitgDndCallback callback, gpointer callback_data)
+gitg_dnd_enable (GtkTreeView *tree_view,
+ GitgDndCallback callback,
+ GitgDndRevisionCallback revision_callback,
+ gpointer callback_data)
{
if (GITG_DND_GET_DATA (tree_view))
{
@@ -795,6 +808,7 @@ gitg_dnd_enable (GtkTreeView *tree_view, GitgDndCallback callback, gpointer call
data->tree_view = tree_view;
data->callback = callback;
+ data->revision_callback = revision_callback;
data->callback_data = callback_data;
g_object_set_data_full (G_OBJECT (tree_view),
diff --git a/gitg/gitg-dnd.h b/gitg/gitg-dnd.h
index 37a211b..cfce9f7 100644
--- a/gitg/gitg-dnd.h
+++ b/gitg/gitg-dnd.h
@@ -3,12 +3,18 @@
#include <gtk/gtk.h>
#include "gitg-ref.h"
+#include "gitg-revision.h"
G_BEGIN_DECLS
typedef gboolean (*GitgDndCallback)(GitgRef *source, GitgRef *dest, gboolean dropped, gpointer callback_data);
+typedef gboolean (*GitgDndRevisionCallback)(GitgRevision *source, GitgRef *dest, gboolean dropped, gpointer callback_data);
+
+void gitg_dnd_enable (GtkTreeView *tree_view,
+ GitgDndCallback callback,
+ GitgDndRevisionCallback revision_callback,
+ gpointer callback_data);
-void gitg_dnd_enable (GtkTreeView *tree_view, GitgDndCallback callback, gpointer callback_data);
void gitg_dnd_disable (GtkTreeView *tree_view);
G_END_DECLS
diff --git a/gitg/gitg-window.c b/gitg/gitg-window.c
index 822ff94..6583758 100644
--- a/gitg/gitg-window.c
+++ b/gitg/gitg-window.c
@@ -581,6 +581,44 @@ on_refs_dnd (GitgRef *source, GitgRef *dest, gboolean dropped, GitgWindow *windo
}
static void
+update_revision_dnd_status (GitgWindow *window, GitgRevision *source, GitgRef *dest)
+{
+ if (!dest)
+ {
+ gtk_statusbar_push (window->priv->statusbar, 0, "");
+ }
+ else
+ {
+ gchar *message = g_strdup_printf (_("Cherry-pick revision on <%s>"),
+ gitg_ref_get_shortname (dest));
+
+ gtk_statusbar_push (window->priv->statusbar, 0, message);
+ g_free (message);
+ }
+}
+
+static gboolean
+on_revision_dnd (GitgRevision *source,
+ GitgRef *dest,
+ gboolean dropped,
+ GitgWindow *window)
+{
+ if (!dropped)
+ {
+ update_revision_dnd_status (window, source, dest);
+ return FALSE;
+ }
+
+ if (gitg_ref_get_ref_type (dest) != GITG_REF_TYPE_BRANCH)
+ {
+ return FALSE;
+ }
+
+ return add_branch_action (window,
+ gitg_branch_actions_cherry_pick (window, source, dest));
+}
+
+static void
init_tree_view (GitgWindow *window, GtkBuilder *builder)
{
GtkTreeViewColumn *col = GTK_TREE_VIEW_COLUMN(gtk_builder_get_object(builder, "rv_column_subject"));
@@ -589,7 +627,10 @@ init_tree_view (GitgWindow *window, GtkBuilder *builder)
gtk_tree_view_column_set_cell_data_func(col, GTK_CELL_RENDERER(window->priv->renderer_path), (GtkTreeCellDataFunc)on_renderer_path, window, NULL);
- gitg_dnd_enable (window->priv->tree_view, (GitgDndCallback)on_refs_dnd, window);
+ gitg_dnd_enable (window->priv->tree_view,
+ (GitgDndCallback)on_refs_dnd,
+ (GitgDndRevisionCallback)on_revision_dnd,
+ window);
}
static void
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]