[gnome-builder] plugins/git: port to GTK 4
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-builder] plugins/git: port to GTK 4
- Date: Tue, 12 Jul 2022 06:39:16 +0000 (UTC)
commit 646dfd77b71c2cffa9c116885a6191b20d43356b
Author: Christian Hergert <chergert redhat com>
Date: Mon Jul 11 22:47:46 2022 -0700
plugins/git: port to GTK 4
- Remove libdazzle usage
- Prefer "main" for new repositories over "master"
- Add support for listing branches from uncloned remote
- Fix typo in xml dbus description
- Add preferences addin for git config
- Improve cloner implementation
- Update .plugin
.../git/daemon/ipc-git-change-monitor-impl.c | 2 +-
src/plugins/git/daemon/ipc-git-remote-callbacks.c | 2 -
src/plugins/git/daemon/ipc-git-repository-impl.c | 23 +-
src/plugins/git/daemon/ipc-git-service-impl.c | 161 +++++++++++++-
.../daemon/org.gnome.Builder.Git.Repository.xml | 2 +-
.../git/daemon/org.gnome.Builder.Git.Service.xml | 5 +
src/plugins/git/gbp-git-branch.c | 105 ++++++---
src/plugins/git/gbp-git-branch.h | 2 +-
src/plugins/git/gbp-git-buffer-change-monitor.c | 27 ++-
src/plugins/git/gbp-git-preferences-addin.c | 247 +++++++++++++++++++++
src/plugins/git/gbp-git-preferences-addin.h | 31 +++
src/plugins/git/gbp-git-tag.c | 44 +++-
src/plugins/git/gbp-git-vcs-cloner.c | 245 +++++++++++++++++++-
src/plugins/git/gbp-git-vcs-config.c | 42 +++-
src/plugins/git/gbp-git-vcs.c | 13 +-
src/plugins/git/gbp-git-workbench-addin.c | 6 +-
src/plugins/git/git-plugin.c | 6 +-
src/plugins/git/git.plugin | 2 +
src/plugins/git/meson.build | 1 +
19 files changed, 892 insertions(+), 74 deletions(-)
---
diff --git a/src/plugins/git/daemon/ipc-git-change-monitor-impl.c
b/src/plugins/git/daemon/ipc-git-change-monitor-impl.c
index c9df257d6..de84f41c4 100644
--- a/src/plugins/git/daemon/ipc-git-change-monitor-impl.c
+++ b/src/plugins/git/daemon/ipc-git-change-monitor-impl.c
@@ -298,7 +298,7 @@ git_change_monitor_iface_init (IpcGitChangeMonitorIface *iface)
}
G_DEFINE_FINAL_TYPE_WITH_CODE (IpcGitChangeMonitorImpl, ipc_git_change_monitor_impl,
IPC_TYPE_GIT_CHANGE_MONITOR_SKELETON,
- G_IMPLEMENT_INTERFACE (IPC_TYPE_GIT_CHANGE_MONITOR, git_change_monitor_iface_init))
+ G_IMPLEMENT_INTERFACE (IPC_TYPE_GIT_CHANGE_MONITOR,
git_change_monitor_iface_init))
static void
ipc_git_change_monitor_impl_finalize (GObject *object)
diff --git a/src/plugins/git/daemon/ipc-git-remote-callbacks.c
b/src/plugins/git/daemon/ipc-git-remote-callbacks.c
index 1ad6d50cd..28774ff76 100644
--- a/src/plugins/git/daemon/ipc-git-remote-callbacks.c
+++ b/src/plugins/git/daemon/ipc-git-remote-callbacks.c
@@ -227,8 +227,6 @@ ipc_git_remote_callbacks_init (IpcGitRemoteCallbacks *self)
*
* This function should be called when a clone was canceled so that we can
* avoid dispatching more events.
- *
- * Since: 3.32
*/
void
ipc_git_remote_callbacks_cancel (IpcGitRemoteCallbacks *self)
diff --git a/src/plugins/git/daemon/ipc-git-repository-impl.c
b/src/plugins/git/daemon/ipc-git-repository-impl.c
index 50f5d9c2b..8fe7b60cc 100644
--- a/src/plugins/git/daemon/ipc-git-repository-impl.c
+++ b/src/plugins/git/daemon/ipc-git-repository-impl.c
@@ -64,9 +64,10 @@ static void
ipc_git_repository_impl_monitor_changed_cb (IpcGitRepositoryImpl *self,
IpcGitIndexMonitor *monitor)
{
+ g_autoptr(GgitRef) head_ref = NULL;
+ const char *shortname = NULL;
GHashTableIter iter;
gpointer key;
- g_autoptr(GgitRef) head_ref = NULL;
g_assert (IPC_IS_GIT_REPOSITORY_IMPL (self));
g_assert (IPC_IS_GIT_INDEX_MONITOR (monitor));
@@ -79,9 +80,16 @@ ipc_git_repository_impl_monitor_changed_cb (IpcGitRepositoryImpl *self,
ipc_git_change_monitor_impl_reset (change_monitor);
}
- head_ref = ggit_repository_get_head (self->repository, NULL);
- g_assert (GGIT_IS_REF (head_ref));
- ipc_git_repository_set_branch ((IpcGitRepository *)self, ggit_ref_get_shorthand (head_ref));
+ if ((head_ref = ggit_repository_get_head (self->repository, NULL)))
+ {
+ g_assert (GGIT_IS_REF (head_ref));
+ shortname = ggit_ref_get_shorthand (head_ref);
+ }
+
+ if (shortname == NULL)
+ shortname = "main";
+
+ ipc_git_repository_set_branch ((IpcGitRepository *)self, shortname);
ipc_git_repository_emit_changed (IPC_GIT_REPOSITORY (self));
}
@@ -124,6 +132,7 @@ translate_status (GgitStatusFlags flags)
case GGIT_STATUS_INDEX_TYPECHANGE:
case GGIT_STATUS_WORKING_TREE_MODIFIED:
case GGIT_STATUS_WORKING_TREE_TYPECHANGE:
+ case GGIT_STATUS_CONFLICTED:
return FILE_STATUS_CHANGED;
case GGIT_STATUS_IGNORED:
@@ -132,6 +141,8 @@ translate_status (GgitStatusFlags flags)
case GGIT_STATUS_CURRENT:
return FILE_STATUS_UNCHANGED;
+ case GGIT_STATUS_WORKING_TREE_RENAMED:
+ case GGIT_STATUS_WORKING_TREE_UNREADABLE:
default:
return FILE_STATUS_UNTRACKED;
}
@@ -223,7 +234,7 @@ ipc_git_repository_impl_handle_switch_branch (IpcGitRepository *repository,
return complete_wrapped_error (invocation, error);
if (!(shortname = ggit_ref_get_shorthand (ref)))
- shortname = "master";
+ shortname = "main";
workdir = ggit_repository_get_workdir (self->repository);
@@ -1172,7 +1183,7 @@ ipc_git_repository_impl_open (GFile *location,
branch = g_strdup (ggit_ref_get_shorthand (ref));
if (branch == NULL)
- branch = g_strdup ("master");
+ branch = g_strdup ("main");
}
workdir = ggit_repository_get_workdir (repository);
diff --git a/src/plugins/git/daemon/ipc-git-service-impl.c b/src/plugins/git/daemon/ipc-git-service-impl.c
index be2b6d876..b991dfd8c 100644
--- a/src/plugins/git/daemon/ipc-git-service-impl.c
+++ b/src/plugins/git/daemon/ipc-git-service-impl.c
@@ -27,6 +27,7 @@
#include "ipc-git-remote-callbacks.h"
#include "ipc-git-repository-impl.h"
#include "ipc-git-service-impl.h"
+#include "ipc-git-types.h"
#include "ipc-git-util.h"
struct _IpcGitServiceImpl
@@ -320,6 +321,163 @@ ipc_git_service_impl_handle_load_config (IpcGitService *service,
return TRUE;
}
+static void
+rm_rf (const char *dir)
+{
+ g_spawn_sync (NULL,
+ (char **)(const char * const[]) { "rm", "-rf", dir, NULL },
+ NULL,
+ G_SPAWN_SEARCH_PATH,
+ NULL, NULL,
+ NULL, NULL, NULL, NULL);
+}
+
+typedef GgitRemoteHead **RemoteHeadList;
+
+static void
+remote_head_list_free (RemoteHeadList list)
+{
+ for (guint i = 0; list[i]; i++)
+ ggit_remote_head_unref (list[i]);
+ g_free (list);
+}
+
+G_DEFINE_AUTO_CLEANUP_FREE_FUNC (RemoteHeadList, remote_head_list_free, NULL)
+
+typedef struct
+{
+ GgitRemoteCallbacks *callbacks;
+ char *uri;
+ IpcGitRefKind kind;
+} ListRemoteRefsByKind;
+
+static void
+list_remote_refs_by_kind_free (gpointer data)
+{
+ ListRemoteRefsByKind *state = data;
+
+ g_clear_pointer (&state->uri, g_free);
+ g_clear_object (&state->callbacks);
+ g_slice_free (ListRemoteRefsByKind, state);
+}
+
+static void
+list_remote_refs_by_kind_worker (GTask *task,
+ gpointer source_object,
+ gpointer task_data,
+ GCancellable *cancellable)
+{
+ ListRemoteRefsByKind *state = task_data;
+ g_autoptr(GgitRepository) repo = NULL;
+ g_autoptr(GgitRemote) remote = NULL;
+ g_autoptr(GError) error = NULL;
+ g_autoptr(GFile) repodir = NULL;
+ g_autofree char *tmpdir = NULL;
+ g_auto(RemoteHeadList) refs = NULL;
+ GPtrArray *ar;
+
+ g_assert (G_IS_TASK (task));
+ g_assert (IPC_IS_GIT_SERVICE_IMPL (source_object));
+ g_assert (task_data != NULL);
+ g_assert (!cancellable || G_IS_CANCELLABLE (cancellable));
+
+ /* Only branches are currently supported, tags are ignored */
+
+ if (!(tmpdir = g_dir_make_tmp (".libgit2-glib-remote-ls-XXXXXX", &error)))
+ goto handle_gerror;
+
+ repodir = g_file_new_for_path (tmpdir);
+
+ if (!(repo = ggit_repository_init_repository (repodir, TRUE, &error)))
+ goto handle_gerror;
+
+ if (!(remote = ggit_remote_new_anonymous (repo, state->uri, &error)))
+ goto handle_gerror;
+
+ ggit_remote_connect (remote,
+ GGIT_DIRECTION_FETCH,
+ state->callbacks,
+ NULL, NULL, &error);
+ if (error != NULL)
+ goto handle_gerror;
+
+ if (!(refs = ggit_remote_list (remote, &error)))
+ goto handle_gerror;
+
+ ar = g_ptr_array_new ();
+ for (guint i = 0; refs[i]; i++)
+ g_ptr_array_add (ar, g_strdup (ggit_remote_head_get_name (refs[i])));
+ g_ptr_array_add (ar, NULL);
+
+ g_task_return_pointer (task,
+ g_ptr_array_free (ar, FALSE),
+ (GDestroyNotify) g_strfreev);
+
+ goto cleanup_tmpdir;
+
+handle_gerror:
+ g_task_return_error (task, g_steal_pointer (&error));
+
+cleanup_tmpdir:
+ if (tmpdir != NULL)
+ rm_rf (tmpdir);
+}
+
+static void
+list_remote_refs_cb (GObject *object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ IpcGitServiceImpl *self = (IpcGitServiceImpl *)object;
+ g_autoptr(GDBusMethodInvocation) invocation = user_data;
+ g_autoptr(GError) error = NULL;
+ g_auto(GStrv) refs = NULL;
+
+ g_assert (IPC_IS_GIT_SERVICE_IMPL (self));
+ g_assert (G_IS_TASK (result));
+ g_assert (G_IS_DBUS_METHOD_INVOCATION (invocation));
+
+ if (!(refs = g_task_propagate_pointer (G_TASK (result), &error)))
+ complete_wrapped_error (g_steal_pointer (&invocation), error);
+ else
+ ipc_git_service_complete_list_remote_refs_by_kind (IPC_GIT_SERVICE (self),
+ g_steal_pointer (&invocation),
+ (const char * const *)refs);
+}
+
+static gboolean
+ipc_git_service_impl_list_remote_refs_by_kind (IpcGitService *service,
+ GDBusMethodInvocation *invocation,
+ const char *uri,
+ guint kind)
+{
+ IpcGitServiceImpl *self = (IpcGitServiceImpl *)service;
+ g_autoptr(GTask) task = NULL;
+ ListRemoteRefsByKind *state;
+
+ g_assert (IPC_IS_GIT_SERVICE_IMPL (self));
+ g_assert (G_IS_DBUS_METHOD_INVOCATION (invocation));
+
+ if (kind != IPC_GIT_REF_BRANCH)
+ {
+ g_dbus_method_invocation_return_dbus_error (invocation,
+ "org.freedesktop.DBus.Error.InvalidArgs",
+ "kind must be a branch, tags are unsupported");
+ return TRUE;
+ }
+
+ state = g_slice_new0 (ListRemoteRefsByKind);
+ state->callbacks = ipc_git_remote_callbacks_new (NULL);
+ state->uri = g_strdup (uri);
+ state->kind = kind;
+
+ task = g_task_new (service, NULL, list_remote_refs_cb, g_steal_pointer (&invocation));
+ g_task_set_task_data (task, state, list_remote_refs_by_kind_free);
+ g_task_run_in_thread (task, list_remote_refs_by_kind_worker);
+
+ return TRUE;
+}
+
static void
git_service_iface_init (IpcGitServiceIface *iface)
{
@@ -328,10 +486,11 @@ git_service_iface_init (IpcGitServiceIface *iface)
iface->handle_create = ipc_git_service_impl_handle_create;
iface->handle_clone = ipc_git_service_impl_handle_clone;
iface->handle_load_config = ipc_git_service_impl_handle_load_config;
+ iface->handle_list_remote_refs_by_kind = ipc_git_service_impl_list_remote_refs_by_kind;
}
G_DEFINE_FINAL_TYPE_WITH_CODE (IpcGitServiceImpl, ipc_git_service_impl, IPC_TYPE_GIT_SERVICE_SKELETON,
- G_IMPLEMENT_INTERFACE (IPC_TYPE_GIT_SERVICE, git_service_iface_init))
+ G_IMPLEMENT_INTERFACE (IPC_TYPE_GIT_SERVICE, git_service_iface_init))
static void
ipc_git_service_impl_finalize (GObject *object)
diff --git a/src/plugins/git/daemon/org.gnome.Builder.Git.Repository.xml
b/src/plugins/git/daemon/org.gnome.Builder.Git.Repository.xml
index 2d1c4956a..0512c21dd 100644
--- a/src/plugins/git/daemon/org.gnome.Builder.Git.Repository.xml
+++ b/src/plugins/git/daemon/org.gnome.Builder.Git.Repository.xml
@@ -27,7 +27,7 @@
This signal is emitted when the repository is updated.
Clients may want to refresh their cached information.
-->
- <signal name="Changed"/>>
+ <signal name="Changed"/>
<!--
Closed:
diff --git a/src/plugins/git/daemon/org.gnome.Builder.Git.Service.xml
b/src/plugins/git/daemon/org.gnome.Builder.Git.Service.xml
index e14f2b594..b00a4915e 100644
--- a/src/plugins/git/daemon/org.gnome.Builder.Git.Service.xml
+++ b/src/plugins/git/daemon/org.gnome.Builder.Git.Service.xml
@@ -70,5 +70,10 @@
<method name="LoadConfig">
<arg name="config_path" direction="out" type="o"/>
</method>
+ <method name="ListRemoteRefsByKind">
+ <arg name="url" direction="in" type="s"/>
+ <arg name="kind" direction="in" type="u"/>
+ <arg name="refs" direction="out" type="as"/>
+ </method>
</interface>
</node>
diff --git a/src/plugins/git/gbp-git-branch.c b/src/plugins/git/gbp-git-branch.c
index 1e62d17aa..bb7358b2d 100644
--- a/src/plugins/git/gbp-git-branch.c
+++ b/src/plugins/git/gbp-git-branch.c
@@ -30,44 +30,84 @@
struct _GbpGitBranch
{
GObject parent_instance;
- gchar *id;
+ char *id;
};
-static gchar *
-gbp_git_branch_get_id (IdeVcsBranch *branch)
-{
- return g_strdup (GBP_GIT_BRANCH (branch)->id);
-}
+G_DEFINE_FINAL_TYPE_WITH_CODE (GbpGitBranch, gbp_git_branch, G_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE (IDE_TYPE_VCS_BRANCH, NULL))
+
+enum {
+ PROP_0,
+ PROP_ID,
+ PROP_NAME,
+ N_PROPS
+};
+
+static GParamSpec *properties [N_PROPS];
-static gchar *
-gbp_git_branch_get_name (IdeVcsBranch *branch)
+static const char *
+gbp_git_branch_get_name (GbpGitBranch *self)
{
- const gchar *id = GBP_GIT_BRANCH (branch)->id;
+ const char *id;
- if (id && g_str_has_prefix (id, "refs/heads/"))
+ g_assert (GBP_IS_GIT_BRANCH (self));
+
+ if ((id = self->id) && g_str_has_prefix (id, "refs/heads/"))
id += strlen ("refs/heads/");
- return g_strdup (id);
+ return id;
}
static void
-vcs_branch_iface_init (IdeVcsBranchInterface *iface)
+gbp_git_branch_dispose (GObject *object)
{
- iface->get_name = gbp_git_branch_get_name;
- iface->get_id = gbp_git_branch_get_id;
+ GbpGitBranch *self = (GbpGitBranch *)object;
+
+ ide_clear_string (&self->id);
+
+ G_OBJECT_CLASS (gbp_git_branch_parent_class)->dispose (object);
}
-G_DEFINE_FINAL_TYPE_WITH_CODE (GbpGitBranch, gbp_git_branch, G_TYPE_OBJECT,
- G_IMPLEMENT_INTERFACE (IDE_TYPE_VCS_BRANCH, vcs_branch_iface_init))
+static void
+gbp_git_branch_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GbpGitBranch *self = GBP_GIT_BRANCH (object);
+
+ switch (prop_id)
+ {
+ case PROP_ID:
+ g_value_set_string (value, self->id);
+ break;
+
+ case PROP_NAME:
+ g_value_set_string (value, gbp_git_branch_get_name (self));
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
static void
-gbp_git_branch_finalize (GObject *object)
+gbp_git_branch_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
{
- GbpGitBranch *self = (GbpGitBranch *)object;
+ GbpGitBranch *self = GBP_GIT_BRANCH (object);
- g_clear_pointer (&self->id, g_free);
+ switch (prop_id)
+ {
+ case PROP_ID:
+ self->id = g_value_dup_string (value);
+ break;
- G_OBJECT_CLASS (gbp_git_branch_parent_class)->finalize (object);
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
}
static void
@@ -75,7 +115,19 @@ gbp_git_branch_class_init (GbpGitBranchClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
- object_class->finalize = gbp_git_branch_finalize;
+ object_class->dispose = gbp_git_branch_dispose;
+ object_class->get_property = gbp_git_branch_get_property;
+ object_class->set_property = gbp_git_branch_set_property;
+
+ properties [PROP_ID] =
+ g_param_spec_string ("id", NULL, NULL, NULL,
+ (G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
+
+ properties [PROP_NAME] =
+ g_param_spec_string ("name", NULL, NULL, NULL,
+ (G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_properties (object_class, N_PROPS, properties);
}
static void
@@ -84,12 +136,9 @@ gbp_git_branch_init (GbpGitBranch *self)
}
GbpGitBranch *
-gbp_git_branch_new (const gchar *id)
+gbp_git_branch_new (const char *id)
{
- GbpGitBranch *self;
-
- self = g_object_new (GBP_TYPE_GIT_BRANCH, NULL);
- self->id = g_strdup (id);
-
- return g_steal_pointer (&self);
+ return g_object_new (GBP_TYPE_GIT_BRANCH,
+ "id", id,
+ NULL);
}
diff --git a/src/plugins/git/gbp-git-branch.h b/src/plugins/git/gbp-git-branch.h
index b7518d611..7f6ce2a36 100644
--- a/src/plugins/git/gbp-git-branch.h
+++ b/src/plugins/git/gbp-git-branch.h
@@ -28,6 +28,6 @@ G_BEGIN_DECLS
G_DECLARE_FINAL_TYPE (GbpGitBranch, gbp_git_branch, GBP, GIT_BRANCH, GObject)
-GbpGitBranch *gbp_git_branch_new (const gchar *id);
+GbpGitBranch *gbp_git_branch_new (const char *id);
G_END_DECLS
diff --git a/src/plugins/git/gbp-git-buffer-change-monitor.c b/src/plugins/git/gbp-git-buffer-change-monitor.c
index b606d121f..e12606e03 100644
--- a/src/plugins/git/gbp-git-buffer-change-monitor.c
+++ b/src/plugins/git/gbp-git-buffer-change-monitor.c
@@ -22,7 +22,6 @@
#include "config.h"
-#include <dazzle.h>
#include <glib/gi18n.h>
#include <string.h>
@@ -35,7 +34,7 @@ struct _GbpGitBufferChangeMonitor
{
IdeBufferChangeMonitor parent;
IpcGitChangeMonitor *proxy;
- DzlSignalGroup *buffer_signals;
+ IdeSignalGroup *buffer_signals;
LineCache *cache;
guint last_change_count;
guint queued_source;
@@ -80,11 +79,11 @@ gbp_git_buffer_change_monitor_queue_update (GbpGitBufferChangeMonitor *self,
g_clear_handle_id (&self->queued_source, g_source_remove);
self->queued_source =
- gdk_threads_add_timeout_full (G_PRIORITY_HIGH,
- delay,
- (GSourceFunc) queued_update_source_cb,
- g_object_ref (self),
- g_object_unref);
+ g_timeout_add_full (G_PRIORITY_HIGH,
+ delay,
+ (GSourceFunc) queued_update_source_cb,
+ g_object_ref (self),
+ g_object_unref);
}
static void
@@ -94,7 +93,7 @@ gbp_git_buffer_change_monitor_destroy (IdeObject *object)
if (self->buffer_signals)
{
- dzl_signal_group_set_target (self->buffer_signals, NULL);
+ ide_signal_group_set_target (self->buffer_signals, NULL);
g_clear_object (&self->buffer_signals);
}
@@ -120,7 +119,7 @@ gbp_git_buffer_change_monitor_load (IdeBufferChangeMonitor *monitor,
g_assert (GBP_IS_GIT_BUFFER_CHANGE_MONITOR (self));
g_assert (IDE_IS_BUFFER (buffer));
- dzl_signal_group_set_target (self->buffer_signals, buffer);
+ ide_signal_group_set_target (self->buffer_signals, buffer);
gbp_git_buffer_change_monitor_queue_update (self, FAST);
}
@@ -348,24 +347,24 @@ gbp_git_buffer_change_monitor_class_init (GbpGitBufferChangeMonitorClass *klass)
static void
gbp_git_buffer_change_monitor_init (GbpGitBufferChangeMonitor *self)
{
- self->buffer_signals = dzl_signal_group_new (IDE_TYPE_BUFFER);
+ self->buffer_signals = ide_signal_group_new (IDE_TYPE_BUFFER);
- dzl_signal_group_connect_object (self->buffer_signals,
+ ide_signal_group_connect_object (self->buffer_signals,
"insert-text",
G_CALLBACK (buffer_insert_text_after_cb),
self,
G_CONNECT_SWAPPED | G_CONNECT_AFTER);
- dzl_signal_group_connect_object (self->buffer_signals,
+ ide_signal_group_connect_object (self->buffer_signals,
"delete-range",
G_CALLBACK (buffer_delete_range_cb),
self,
G_CONNECT_SWAPPED);
- dzl_signal_group_connect_object (self->buffer_signals,
+ ide_signal_group_connect_object (self->buffer_signals,
"delete-range",
G_CALLBACK (buffer_delete_range_after_cb),
self,
G_CONNECT_SWAPPED | G_CONNECT_AFTER);
- dzl_signal_group_connect_object (self->buffer_signals,
+ ide_signal_group_connect_object (self->buffer_signals,
"changed",
G_CALLBACK (buffer_changed_after_cb),
self,
diff --git a/src/plugins/git/gbp-git-preferences-addin.c b/src/plugins/git/gbp-git-preferences-addin.c
new file mode 100644
index 000000000..f8f23c640
--- /dev/null
+++ b/src/plugins/git/gbp-git-preferences-addin.c
@@ -0,0 +1,247 @@
+/* gbp-git-preferences-addin.c
+ *
+ * Copyright 2022 Christian Hergert <chergert redhat com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#define G_LOG_DOMAIN "gbp-git-preferences-addin"
+
+#include "config.h"
+
+#include <glib/gi18n.h>
+
+#include <libide-gui.h>
+
+#include "gbp-git-preferences-addin.h"
+#include "gbp-git-vcs.h"
+#include "gbp-git-vcs-config.h"
+
+struct _GbpGitPreferencesAddin
+{
+ GObject parent_instance;
+};
+
+typedef struct
+{
+ IdeVcsConfig *config;
+ IdeVcsConfigType key;
+} ConfigKeyState;
+
+static void
+config_key_state_free (gpointer data)
+{
+ ConfigKeyState *state = data;
+
+ ide_clear_and_destroy_object (&state->config);
+ g_slice_free (ConfigKeyState, state);
+}
+
+static void
+entry_config_changed (GtkEditable *editable,
+ ConfigKeyState *state)
+{
+ g_auto(GValue) value = G_VALUE_INIT;
+ const char *text;
+
+ g_assert (GTK_IS_EDITABLE (editable));
+ g_assert (state != NULL);
+ g_assert (IDE_IS_VCS_CONFIG (state->config));
+
+ text = gtk_editable_get_text (editable);
+
+ g_value_init (&value, G_TYPE_STRING);
+ g_value_set_string (&value, text);
+
+ ide_vcs_config_set_config (state->config, state->key, &value);
+}
+
+static GtkWidget *
+create_entry (IdeVcsConfig *config,
+ const char *title,
+ IdeVcsConfigType type)
+{
+ g_auto(GValue) value = G_VALUE_INIT;
+ AdwEntryRow *entry;
+ const char *text = NULL;
+ ConfigKeyState *state;
+
+ g_assert (GBP_IS_GIT_VCS_CONFIG (config));
+
+ g_value_init (&value, G_TYPE_STRING);
+ ide_vcs_config_get_config (config, type, &value);
+ text = g_value_get_string (&value);
+
+ entry = g_object_new (ADW_TYPE_ENTRY_ROW,
+ "title", title,
+ "text", text,
+ NULL);
+
+ state = g_slice_new (ConfigKeyState);
+ state->config = g_object_ref (config);
+ state->key = type;
+
+ g_signal_connect_data (entry,
+ "changed",
+ G_CALLBACK (entry_config_changed),
+ state,
+ (GClosureNotify)config_key_state_free,
+ G_CONNECT_AFTER);
+
+ return GTK_WIDGET (entry);
+}
+
+static void
+create_entry_row (const char *page_name,
+ const IdePreferenceItemEntry *entry,
+ AdwPreferencesGroup *group,
+ gpointer user_data)
+{
+ g_autoptr(IdeVcsConfig) config = NULL;
+ IdePreferencesWindow *window = user_data;
+ IdePreferencesMode mode;
+ IdeContext *context;
+
+ g_assert (IDE_IS_PREFERENCES_WINDOW (window));
+
+ /* We should always have a context, even if we're showing
+ * global preferences.
+ */
+ mode = ide_preferences_window_get_mode (window);
+ context = ide_preferences_window_get_context (window);
+
+ g_assert (IDE_IS_CONTEXT (context));
+
+ if (mode == IDE_PREFERENCES_MODE_PROJECT)
+ {
+ IdeVcs *vcs = ide_vcs_from_context (context);
+
+ if (!GBP_IS_GIT_VCS (vcs))
+ return;
+
+ if (!(config = ide_vcs_get_config (vcs)))
+ return;
+
+ gbp_git_vcs_config_set_global (GBP_GIT_VCS_CONFIG (config), FALSE);
+ }
+ else
+ {
+ config = g_object_new (GBP_TYPE_GIT_VCS_CONFIG,
+ "parent", context,
+ NULL);
+ }
+
+ g_assert (GBP_IS_GIT_VCS_CONFIG (config));
+
+ if (g_strcmp0 (entry->name, "name") == 0)
+ {
+ adw_preferences_group_add (group, create_entry (config, _("Author"), IDE_VCS_CONFIG_FULL_NAME));
+ return;
+ }
+
+ if (g_strcmp0 (entry->name, "email") == 0)
+ {
+ const char *title;
+ GtkWidget *label;
+
+ adw_preferences_group_add (group, create_entry (config, _("Email"), IDE_VCS_CONFIG_EMAIL));
+
+ /* After the email row, we want to add a blurb about whether this
+ * will affect the global or per-project settings.
+ */
+ if (mode == IDE_PREFERENCES_MODE_PROJECT)
+ title = _("The Git configuration options above effect current project only.");
+ else
+ title = _("The Git configuration options above effect global defaults.");
+
+ label = g_object_new (GTK_TYPE_LABEL,
+ "css-classes", IDE_STRV_INIT ("caption", "dim-label"),
+ "xalign", .0f,
+ "margin-top", 15,
+ "single-line-mode", TRUE,
+ "label", title,
+ NULL);
+ adw_preferences_group_add (group, label);
+
+ return;
+ }
+}
+
+static const IdePreferencePageEntry pages[] = {
+ { NULL, "projects", "git", "builder-vcs-git-symbolic", 210, N_("Version Control") },
+};
+
+static const IdePreferenceGroupEntry groups[] = {
+ { "git", "author", 0, N_("Authorship") },
+};
+
+static const IdePreferenceItemEntry items[] = {
+ { "git", "author", "name", 0, create_entry_row, N_("Full Name") },
+ { "git", "author", "email", 10, create_entry_row, N_("Email Address") },
+};
+
+static void
+gbp_git_preferences_addin_load (IdePreferencesAddin *addin,
+ IdePreferencesWindow *window,
+ IdeContext *context)
+{
+ g_assert (GBP_IS_GIT_PREFERENCES_ADDIN (addin));
+ g_assert (IDE_IS_PREFERENCES_WINDOW (window));
+ g_assert (!context || IDE_IS_CONTEXT (context));
+
+ /* We can only show Git information if we have a project open as we need
+ * access to a gnome-builder-git daemon. If no context is available, then
+ * that means we got here by showing preferences with --preferences or
+ * soemthing like that. In that (unlikely) case, we have to bail.
+ */
+ if (context == NULL)
+ return;
+
+ ide_preferences_window_add_pages (window, pages, G_N_ELEMENTS (pages), NULL);
+ ide_preferences_window_add_groups (window, groups, G_N_ELEMENTS (groups), NULL);
+ ide_preferences_window_add_items (window, items, G_N_ELEMENTS (items), window, NULL);
+}
+
+static void
+gbp_git_preferences_addin_unload (IdePreferencesAddin *addin,
+ IdePreferencesWindow *window,
+ IdeContext *context)
+{
+ g_assert (GBP_IS_GIT_PREFERENCES_ADDIN (addin));
+ g_assert (IDE_IS_PREFERENCES_WINDOW (window));
+ g_assert (!context || IDE_IS_CONTEXT (context));
+
+}
+
+static void
+preferences_addin_iface_init (IdePreferencesAddinInterface *iface)
+{
+ iface->load = gbp_git_preferences_addin_load;
+ iface->unload = gbp_git_preferences_addin_unload;
+}
+
+G_DEFINE_FINAL_TYPE_WITH_CODE (GbpGitPreferencesAddin, gbp_git_preferences_addin, G_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE (IDE_TYPE_PREFERENCES_ADDIN,
preferences_addin_iface_init))
+
+static void
+gbp_git_preferences_addin_class_init (GbpGitPreferencesAddinClass *klass)
+{
+}
+
+static void
+gbp_git_preferences_addin_init (GbpGitPreferencesAddin *self)
+{
+}
diff --git a/src/plugins/git/gbp-git-preferences-addin.h b/src/plugins/git/gbp-git-preferences-addin.h
new file mode 100644
index 000000000..1d30f4aee
--- /dev/null
+++ b/src/plugins/git/gbp-git-preferences-addin.h
@@ -0,0 +1,31 @@
+/* gbp-git-preferences-addin.h
+ *
+ * Copyright 2022 Christian Hergert <chergert redhat com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#pragma once
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define GBP_TYPE_GIT_PREFERENCES_ADDIN (gbp_git_preferences_addin_get_type())
+
+G_DECLARE_FINAL_TYPE (GbpGitPreferencesAddin, gbp_git_preferences_addin, GBP, GIT_PREFERENCES_ADDIN, GObject)
+
+G_END_DECLS
diff --git a/src/plugins/git/gbp-git-tag.c b/src/plugins/git/gbp-git-tag.c
index 9746fefa2..1ca85fa54 100644
--- a/src/plugins/git/gbp-git-tag.c
+++ b/src/plugins/git/gbp-git-tag.c
@@ -29,11 +29,11 @@
struct _GbpGitTag
{
GObject parent_instance;
- gchar *name;
+ char *name;
};
-static gchar *
-gbp_git_tag_get_name (IdeVcsTag *tag)
+static char *
+gbp_git_tag_dup_name (IdeVcsTag *tag)
{
return g_strdup (GBP_GIT_TAG (tag)->name);
}
@@ -41,11 +41,19 @@ gbp_git_tag_get_name (IdeVcsTag *tag)
static void
vcs_tag_iface_init (IdeVcsTagInterface *iface)
{
- iface->get_name = gbp_git_tag_get_name;
+ iface->dup_name = gbp_git_tag_dup_name;
}
G_DEFINE_FINAL_TYPE_WITH_CODE (GbpGitTag, gbp_git_tag, G_TYPE_OBJECT,
- G_IMPLEMENT_INTERFACE (IDE_TYPE_VCS_TAG, vcs_tag_iface_init))
+ G_IMPLEMENT_INTERFACE (IDE_TYPE_VCS_TAG, vcs_tag_iface_init))
+
+enum {
+ PROP_0,
+ PROP_NAME,
+ N_PROPS
+};
+
+static GParamSpec *properties[N_PROPS];
static void
gbp_git_tag_finalize (GObject *object)
@@ -57,12 +65,38 @@ gbp_git_tag_finalize (GObject *object)
G_OBJECT_CLASS (gbp_git_tag_parent_class)->finalize (object);
}
+static void
+gbp_git_tag_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GbpGitTag *self = GBP_GIT_TAG (object);
+
+ switch (prop_id)
+ {
+ case PROP_NAME:
+ g_value_set_string (value, self->name);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
static void
gbp_git_tag_class_init (GbpGitTagClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->finalize = gbp_git_tag_finalize;
+ object_class->get_property = gbp_git_tag_get_property;
+
+ properties [PROP_NAME] =
+ g_param_spec_string ("name", NULL, NULL, NULL,
+ (G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_properties (object_class, N_PROPS, properties);
}
static void
diff --git a/src/plugins/git/gbp-git-vcs-cloner.c b/src/plugins/git/gbp-git-vcs-cloner.c
index 9b850aaa9..4ff950773 100644
--- a/src/plugins/git/gbp-git-vcs-cloner.c
+++ b/src/plugins/git/gbp-git-vcs-cloner.c
@@ -26,7 +26,9 @@
#include <libide-threading.h>
#include "daemon/ipc-git-service.h"
+#include "daemon/ipc-git-types.h"
+#include "gbp-git-branch.h"
#include "gbp-git-client.h"
#include "gbp-git-progress.h"
#include "gbp-git-vcs-cloner.h"
@@ -49,7 +51,21 @@ typedef struct
static void vcs_cloner_iface_init (IdeVcsClonerInterface *iface);
G_DEFINE_FINAL_TYPE_WITH_CODE (GbpGitVcsCloner, gbp_git_vcs_cloner, IDE_TYPE_OBJECT,
- G_IMPLEMENT_INTERFACE (IDE_TYPE_VCS_CLONER, vcs_cloner_iface_init))
+ G_IMPLEMENT_INTERFACE (IDE_TYPE_VCS_CLONER, vcs_cloner_iface_init))
+
+static const char *
+guess_ssh_user_from_host (const char *host)
+{
+ if (host != NULL)
+ {
+ /* TODO: check .ssh/config for User mappings */
+ if (strstr (host, "gitlab.") != NULL ||
+ strstr (host, "github.") != NULL)
+ return "git";
+ }
+
+ return g_get_user_name ();
+}
static void
clone_request_free (gpointer data)
@@ -287,6 +303,230 @@ gbp_git_vcs_cloner_clone_finish (IdeVcsCloner *cloner,
return ide_task_propagate_boolean (IDE_TASK (result), error);
}
+static gboolean
+should_ignore (const char *name)
+{
+ if (name == NULL)
+ return TRUE;
+
+ if (g_str_has_prefix (name, "refs/merge-requests/") ||
+ g_str_has_prefix (name, "refs/tags/"))
+ return TRUE;
+
+ return FALSE;
+}
+
+enum {
+ CLASS_HEAD,
+ CLASS_MAIN,
+ CLASS_MASTER,
+ CLASS_FEATURE,
+ CLASS_GNOME,
+ CLASS_OTHER,
+ CLASS_WIP,
+};
+
+static int
+classify_branch_name (const char *branch)
+{
+ switch (branch[0])
+ {
+ case 'H':
+ if (strcmp (branch, "HEAD") == 0)
+ return CLASS_HEAD;
+ break;
+
+ case 'm':
+ if (strcmp (branch, "main") == 0)
+ return CLASS_MAIN;
+ else if (strcmp (branch, "master") == 0)
+ return CLASS_MASTER;
+ break;
+
+ case 'w':
+ if (g_str_has_prefix (branch, "wip/"))
+ return CLASS_WIP;
+ break;
+
+ case 'f':
+ if (g_str_has_prefix (branch, "feature/"))
+ return CLASS_FEATURE;
+ break;
+
+ case 'g':
+ if (g_str_has_prefix (branch, "gnome-"))
+ return CLASS_GNOME;
+ break;
+
+ default:
+ break;
+ }
+
+ return CLASS_OTHER;
+}
+
+static inline const char *
+get_name (const char *ref)
+{
+ if (ref[0] == 'r' && g_str_has_prefix (ref, "refs/heads/"))
+ return ref + strlen ("refs/heads/");
+ return ref;
+}
+
+static int
+strptrcmp (const char * const *ptra,
+ const char * const *ptrb)
+{
+ const char *name_a = get_name (*ptra);
+ const char *name_b = get_name (*ptrb);
+ int class_a = classify_branch_name (name_a);
+ int class_b = classify_branch_name (name_b);
+
+ if (class_a < class_b)
+ return -1;
+ else if (class_a > class_b)
+ return 1;
+ else
+ return strcmp (name_a, name_b);
+}
+
+static void
+gbp_git_vcs_cloner_list_remote_refs_by_kind_cb (GObject *object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ IpcGitService *service = (IpcGitService *)object;
+ g_autoptr(IdeTask) task = user_data;
+ g_autoptr(GError) error = NULL;
+ g_autoptr(GListStore) store = NULL;
+ g_auto(GStrv) refs = NULL;
+
+ IDE_ENTRY;
+
+ g_assert (IPC_IS_GIT_SERVICE (service));
+ g_assert (G_IS_ASYNC_RESULT (result));
+ g_assert (IDE_IS_TASK (task));
+
+ if (!ipc_git_service_call_list_remote_refs_by_kind_finish (service, &refs, result, &error))
+ {
+ ide_task_return_error (task, g_steal_pointer (&error));
+ IDE_EXIT;
+ }
+
+ g_qsort_with_data (refs, g_strv_length (refs), sizeof (char *),
+ (GCompareDataFunc)strptrcmp, NULL);
+ store = g_list_store_new (GBP_TYPE_GIT_BRANCH);
+
+ for (guint i = 0; refs[i]; i++)
+ {
+ g_autoptr(GbpGitBranch) branch = NULL;
+
+ if (should_ignore (refs[i]))
+ continue;
+
+ branch = gbp_git_branch_new (refs[i]);
+ g_list_store_append (store, branch);
+ }
+
+ ide_task_return_pointer (task, g_steal_pointer (&store), g_object_unref);
+
+ IDE_EXIT;
+}
+
+static void
+gbp_git_vcs_cloner_list_branches_async (IdeVcsCloner *cloner,
+ IdeVcsUri *uri,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GbpGitVcsCloner *self = (GbpGitVcsCloner *)cloner;
+ g_autoptr(IpcGitService) service = NULL;
+ g_autoptr(IdeTask) task = NULL;
+ g_autoptr(GError) error = NULL;
+ g_autofree char *uri_str = NULL;
+ GbpGitClient *client;
+ IdeContext *context;
+
+ IDE_ENTRY;
+
+ g_assert (GBP_IS_GIT_VCS_CLONER (cloner));
+ g_assert (uri != NULL);
+ g_assert (!cancellable || G_IS_CANCELLABLE (cancellable));
+
+ task = ide_task_new (self, cancellable, callback, user_data);
+ ide_task_set_source_tag (task, gbp_git_vcs_cloner_list_branches_async);
+
+ if (!(context = ide_object_get_context (IDE_OBJECT (self))) ||
+ !(client = gbp_git_client_from_context (context)))
+ {
+ ide_task_return_new_error (task,
+ G_IO_ERROR,
+ G_IO_ERROR_FAILED,
+ "Failed to locate git client object within context");
+ IDE_EXIT;
+ }
+
+ /* We can make this async if/when necessary. It just spawns the process and
+ * sets up a GDBusProxy to the subprocess. Not ideal, but we do it elsewhere
+ * too when accessing the service.
+ */
+ if (!(service = gbp_git_client_get_service (client, cancellable, &error)))
+ {
+ ide_task_return_error (task, g_steal_pointer (&error));
+ IDE_EXIT;
+ }
+
+ /* Always set a username if the transport is SSH */
+ if (g_strcmp0 ("ssh", ide_vcs_uri_get_scheme (uri)) == 0)
+ {
+ if (ide_vcs_uri_get_user (uri) == NULL)
+ {
+ const char *host = ide_vcs_uri_get_host (uri);
+ ide_vcs_uri_set_user (uri, guess_ssh_user_from_host (host));
+ }
+ }
+
+ uri_str = ide_vcs_uri_to_string (uri);
+
+ ipc_git_service_call_list_remote_refs_by_kind (service,
+ uri_str,
+ IPC_GIT_REF_BRANCH,
+ cancellable,
+ gbp_git_vcs_cloner_list_remote_refs_by_kind_cb,
+ g_steal_pointer (&task));
+
+ IDE_EXIT;
+}
+
+static GListModel *
+gbp_git_vcs_cloner_list_branches_finish (IdeVcsCloner *cloner,
+ GAsyncResult *result,
+ GError **error)
+{
+ GListModel *ret;
+
+ IDE_ENTRY;
+
+ g_assert (GBP_IS_GIT_VCS_CLONER (cloner));
+ g_assert (IDE_IS_TASK (result));
+
+ ret = ide_task_propagate_pointer (IDE_TASK (result), error);
+ g_assert (!ret || G_IS_LIST_MODEL (ret));
+
+ IDE_RETURN (ret);
+}
+
+static char *
+gbp_git_vcs_cloner_get_directory_name (IdeVcsCloner *cloner,
+ IdeVcsUri *uri)
+{
+ g_assert (GBP_IS_GIT_VCS_CLONER (cloner));
+ g_assert (uri != NULL);
+
+ return ide_vcs_uri_get_clone_name (uri);
+}
+
static void
vcs_cloner_iface_init (IdeVcsClonerInterface *iface)
{
@@ -294,4 +534,7 @@ vcs_cloner_iface_init (IdeVcsClonerInterface *iface)
iface->validate_uri = gbp_git_vcs_cloner_validate_uri;
iface->clone_async = gbp_git_vcs_cloner_clone_async;
iface->clone_finish = gbp_git_vcs_cloner_clone_finish;
+ iface->list_branches_async = gbp_git_vcs_cloner_list_branches_async;
+ iface->list_branches_finish = gbp_git_vcs_cloner_list_branches_finish;
+ iface->get_directory_name = gbp_git_vcs_cloner_get_directory_name;
}
diff --git a/src/plugins/git/gbp-git-vcs-config.c b/src/plugins/git/gbp-git-vcs-config.c
index f110696d5..859d325a2 100644
--- a/src/plugins/git/gbp-git-vcs-config.c
+++ b/src/plugins/git/gbp-git-vcs-config.c
@@ -29,6 +29,7 @@
#include "daemon/ipc-git-config.h"
#include "gbp-git-client.h"
+#include "gbp-git-vcs.h"
#include "gbp-git-vcs-config.h"
struct _GbpGitVcsConfig
@@ -73,18 +74,46 @@ get_config (GbpGitVcsConfig *self,
context = ide_object_get_context (IDE_OBJECT (self));
client = gbp_git_client_from_context (context);
- if (!self->is_global)
- {
- /* TODO: get config from repository */
- }
+ g_assert (IDE_IS_CONTEXT (context));
+ g_assert (GBP_IS_GIT_CLIENT (client));
if (!(service = gbp_git_client_get_service (client, cancellable, error)))
return NULL;
- if (!ipc_git_service_call_load_config_sync (service, &obj_path, cancellable, error))
- return NULL;
+ if (!self->is_global)
+ {
+ IdeVcs *vcs;
+ IpcGitRepository *repository;
+
+ vcs = ide_vcs_from_context (context);
+ g_assert (GBP_IS_GIT_VCS (vcs));
+
+ repository = gbp_git_vcs_get_repository (GBP_GIT_VCS (vcs));
+ g_assert (!repository || IPC_IS_GIT_REPOSITORY (repository));
+
+ if (repository == NULL)
+ {
+ g_set_error (error,
+ G_IO_ERROR,
+ G_IO_ERROR_NOT_SUPPORTED,
+ "Failed to load git repository");
+ return NULL;
+ }
+
+ if (!ipc_git_repository_call_load_config_sync (repository, &obj_path, cancellable, error))
+ return NULL;
+ }
+ else
+ {
+ if (!ipc_git_service_call_load_config_sync (service, &obj_path, cancellable, error))
+ return NULL;
+ }
+
+ g_assert (obj_path != NULL);
+ g_assert (g_variant_is_object_path (obj_path));
connection = g_dbus_proxy_get_connection (G_DBUS_PROXY (service));
+ g_assert (G_IS_DBUS_CONNECTION (connection));
return ipc_git_config_proxy_new_sync (connection,
G_DBUS_PROXY_FLAGS_NONE,
@@ -92,7 +121,6 @@ get_config (GbpGitVcsConfig *self,
obj_path,
cancellable,
error);
-
}
static void
diff --git a/src/plugins/git/gbp-git-vcs.c b/src/plugins/git/gbp-git-vcs.c
index 36d89733d..81d0162e2 100644
--- a/src/plugins/git/gbp-git-vcs.c
+++ b/src/plugins/git/gbp-git-vcs.c
@@ -160,7 +160,7 @@ gbp_git_vcs_switch_branch_async (IdeVcs *vcs,
task = ide_task_new (self, cancellable, callback, user_data);
ide_task_set_source_tag (task, gbp_git_vcs_switch_branch_async);
- branch_id = ide_vcs_branch_get_id (branch);
+ branch_id = ide_vcs_branch_dup_id (branch);
ipc_git_repository_call_switch_branch (self->repository,
branch_id,
@@ -233,8 +233,8 @@ gbp_git_vcs_push_branch_async (IdeVcs *vcs,
task = ide_task_new (self, cancellable, callback, user_data);
ide_task_set_source_tag (task, gbp_git_vcs_push_branch_async);
- branch_id = ide_vcs_branch_get_id (branch);
- name = ide_vcs_branch_get_name (branch);
+ branch_id = ide_vcs_branch_dup_id (branch);
+ name = ide_vcs_branch_dup_name (branch);
ref_specs = g_ptr_array_new_with_free_func (g_free);
g_ptr_array_add (ref_specs, g_strdup_printf ("%s:%s", branch_id, branch_id));
@@ -530,9 +530,16 @@ gbp_git_vcs_list_status_finish (IdeVcs *vcs,
return ide_task_propagate_object (IDE_TASK (result), error);
}
+static char *
+gbp_git_vcs_get_display_name (IdeVcs *vcs)
+{
+ return g_strdup (_("Git"));
+}
+
static void
vcs_iface_init (IdeVcsInterface *iface)
{
+ iface->get_display_name = gbp_git_vcs_get_display_name;
iface->get_workdir = gbp_git_vcs_get_workdir;
iface->is_ignored = gbp_git_vcs_is_ignored;
iface->get_config = gbp_git_vcs_get_config;
diff --git a/src/plugins/git/gbp-git-workbench-addin.c b/src/plugins/git/gbp-git-workbench-addin.c
index 0dbca9731..a64177895 100644
--- a/src/plugins/git/gbp-git-workbench-addin.c
+++ b/src/plugins/git/gbp-git-workbench-addin.c
@@ -112,8 +112,8 @@ gbp_git_workbench_addin_load_project_discover_cb (GObject *object,
if (!ipc_git_service_call_discover_finish (service, &git_location, result, &error))
{
- g_dbus_error_strip_remote_error (error);
- ide_task_return_error (task, g_steal_pointer (&error));
+ g_debug ("Not a git repository: %s", error->message);
+ ide_task_return_unsupported_error (task);
return;
}
@@ -239,7 +239,7 @@ workbench_addin_iface_init (IdeWorkbenchAddinInterface *iface)
}
G_DEFINE_FINAL_TYPE_WITH_CODE (GbpGitWorkbenchAddin, gbp_git_workbench_addin, G_TYPE_OBJECT,
- G_IMPLEMENT_INTERFACE (IDE_TYPE_WORKBENCH_ADDIN, workbench_addin_iface_init))
+ G_IMPLEMENT_INTERFACE (IDE_TYPE_WORKBENCH_ADDIN, workbench_addin_iface_init))
static void
gbp_git_workbench_addin_class_init (GbpGitWorkbenchAddinClass *klass)
diff --git a/src/plugins/git/git-plugin.c b/src/plugins/git/git-plugin.c
index c77425f12..d0d5fec05 100644
--- a/src/plugins/git/git-plugin.c
+++ b/src/plugins/git/git-plugin.c
@@ -23,13 +23,14 @@
#include "config.h"
#include <libpeas/peas.h>
-#include <libide-editor.h>
+#include <libide-gui.h>
#include <libide-foundry.h>
#include <libide-vcs.h>
#include "gbp-git-buffer-addin.h"
#include "gbp-git-dependency-updater.h"
#include "gbp-git-pipeline-addin.h"
+#include "gbp-git-preferences-addin.h"
#include "gbp-git-vcs-cloner.h"
#include "gbp-git-vcs-config.h"
#include "gbp-git-vcs-initializer.h"
@@ -61,4 +62,7 @@ _gbp_git_register_types (PeasObjectModule *module)
peas_object_module_register_extension_type (module,
IDE_TYPE_WORKBENCH_ADDIN,
GBP_TYPE_GIT_WORKBENCH_ADDIN);
+ peas_object_module_register_extension_type (module,
+ IDE_TYPE_PREFERENCES_ADDIN,
+ GBP_TYPE_GIT_PREFERENCES_ADDIN);
}
diff --git a/src/plugins/git/git.plugin b/src/plugins/git/git.plugin
index 8592d5293..7565e9dd5 100644
--- a/src/plugins/git/git.plugin
+++ b/src/plugins/git/git.plugin
@@ -6,3 +6,5 @@ Description=Support for the Git version control system
Embedded=_gbp_git_register_types
Module=git
Name=Git
+X-Category=vcs
+X-Preferences-Kind=application;project;
diff --git a/src/plugins/git/meson.build b/src/plugins/git/meson.build
index d08ba06c5..ad9ce6450 100644
--- a/src/plugins/git/meson.build
+++ b/src/plugins/git/meson.build
@@ -10,6 +10,7 @@ plugins_sources += files([
'gbp-git-client.c',
'gbp-git-dependency-updater.c',
'gbp-git-pipeline-addin.c',
+ 'gbp-git-preferences-addin.c',
'gbp-git-progress.c',
'gbp-git-submodule-stage.c',
'gbp-git-tag.c',
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]