[gnome-builder/wip/chergert/git-oop] use git client for discovery



commit 6ebc3704202589a15c1dff3beeef518d5eaa5135
Author: Christian Hergert <chergert redhat com>
Date:   Thu Mar 21 13:46:45 2019 -0700

    use git client for discovery

 src/plugins/git/gbp-git-client.c          |  10 +++
 src/plugins/git/gbp-git-client.h          |   1 +
 src/plugins/git/gbp-git-workbench-addin.c | 124 ++++++++----------------------
 src/plugins/git/gbp-git.c                 |   6 ++
 src/plugins/git/gbp-git.h                 |   1 +
 src/plugins/git/gnome-builder-git.c       |   6 +-
 6 files changed, 53 insertions(+), 95 deletions(-)
---
diff --git a/src/plugins/git/gbp-git-client.c b/src/plugins/git/gbp-git-client.c
index e0a4d1852..162ce57c5 100644
--- a/src/plugins/git/gbp-git-client.c
+++ b/src/plugins/git/gbp-git-client.c
@@ -1026,6 +1026,7 @@ gbp_git_client_create_repo_finish (GbpGitClient  *self,
 typedef struct
 {
   GFile *workdir;
+  GFile *dot_git;
   gchar *branch;
   guint  is_worktree : 1;
 } Discover;
@@ -1034,6 +1035,7 @@ static void
 discover_free (Discover *state)
 {
   g_clear_object (&state->workdir);
+  g_clear_object (&state->dot_git);
   g_clear_pointer (&state->branch, g_free);
   g_slice_free (Discover, state);
 }
@@ -1047,6 +1049,7 @@ gbp_git_client_discover_cb (GObject      *object,
   g_autoptr(IdeTask) task = user_data;
   g_autoptr(GVariant) reply = NULL;
   g_autoptr(GError) error = NULL;
+  const gchar *gitdir = NULL;
   const gchar *workdir = NULL;
   const gchar *branch = NULL;
   Discover *state;
@@ -1067,6 +1070,7 @@ gbp_git_client_discover_cb (GObject      *object,
 
   r = JSONRPC_MESSAGE_PARSE (reply,
     "workdir", JSONRPC_MESSAGE_GET_STRING (&workdir),
+    "gitdir", JSONRPC_MESSAGE_GET_STRING (&gitdir),
     "branch", JSONRPC_MESSAGE_GET_STRING (&branch),
     "is-worktree", JSONRPC_MESSAGE_GET_BOOLEAN (&is_worktree)
   );
@@ -1080,6 +1084,7 @@ gbp_git_client_discover_cb (GObject      *object,
       return;
     }
 
+  state->dot_git = g_file_new_for_uri (gitdir);
   state->workdir = g_file_new_for_uri (workdir);
   state->branch = g_strdup (branch);
   state->is_worktree = !!is_worktree;
@@ -1127,6 +1132,7 @@ gboolean
 gbp_git_client_discover_finish (GbpGitClient  *self,
                                 GAsyncResult  *result,
                                 GFile        **workdir,
+                                GFile        **dot_git,
                                 gchar        **branch,
                                 gboolean      *is_worktree,
                                 GError       **error)
@@ -1135,6 +1141,7 @@ gbp_git_client_discover_finish (GbpGitClient  *self,
   g_return_val_if_fail (IDE_IS_TASK (result), FALSE);
 
   ide_clear_param (workdir, NULL);
+  ide_clear_param (dot_git, NULL);
   ide_clear_param (branch, NULL);
   ide_clear_param (is_worktree, FALSE);
 
@@ -1147,6 +1154,9 @@ gbp_git_client_discover_finish (GbpGitClient  *self,
       if (workdir != NULL)
         *workdir = g_steal_pointer (&state->workdir);
 
+      if (dot_git != NULL)
+        *dot_git = g_steal_pointer (&state->dot_git);
+
       if (branch != NULL)
         *branch = g_steal_pointer (&state->branch);
 
diff --git a/src/plugins/git/gbp-git-client.h b/src/plugins/git/gbp-git-client.h
index 18d699c0f..7a2b6504f 100644
--- a/src/plugins/git/gbp-git-client.h
+++ b/src/plugins/git/gbp-git-client.h
@@ -136,6 +136,7 @@ void          gbp_git_client_discover_async           (GbpGitClient         *sel
 gboolean      gbp_git_client_discover_finish          (GbpGitClient         *self,
                                                        GAsyncResult         *result,
                                                        GFile               **workdir,
+                                                       GFile               **dot_git,
                                                        gchar               **branch,
                                                        gboolean             *is_worktree,
                                                        GError              **error);
diff --git a/src/plugins/git/gbp-git-workbench-addin.c b/src/plugins/git/gbp-git-workbench-addin.c
index e3831d98e..b73f8ebba 100644
--- a/src/plugins/git/gbp-git-workbench-addin.c
+++ b/src/plugins/git/gbp-git-workbench-addin.c
@@ -28,6 +28,7 @@
 #include <libide-threading.h>
 
 #include "gbp-git-buffer-change-monitor.h"
+#include "gbp-git-client.h"
 #include "gbp-git-index-monitor.h"
 #include "gbp-git-vcs.h"
 #include "gbp-git-workbench-addin.h"
@@ -41,110 +42,40 @@ struct _GbpGitWorkbenchAddin
 };
 
 static void
-gbp_git_workbench_addin_load_project_worker (IdeTask      *task,
-                                             gpointer      source_object,
-                                             gpointer      task_data,
-                                             GCancellable *cancellable)
+gbp_git_workbench_addin_discover_cb (GObject      *object,
+                                     GAsyncResult *result,
+                                     gpointer      user_data)
 {
-  g_autoptr(GgitRepository) repository = NULL;
-  g_autoptr(GbpGitVcs) vcs = NULL;
-  g_autoptr(GFile) location = NULL;
-  g_autoptr(GFile) workdir = NULL;
+  GbpGitClient *client = (GbpGitClient *)object;
+  g_autoptr(IdeTask) task = NULL;
   g_autoptr(GError) error = NULL;
-  g_autofree gchar *worktree_branch = NULL;
-  GFile *directory = task_data;
-
-  g_assert (IDE_IS_TASK (task));
-  g_assert (GBP_IS_GIT_WORKBENCH_ADDIN (source_object));
-  g_assert (G_IS_FILE (directory));
-
-  /* Short-circuit if we don't .git */
-  if (!(location = ggit_repository_discover_full (directory, TRUE, NULL, &error)))
-    {
-      ide_task_return_new_error (task,
-                                 G_IO_ERROR,
-                                 G_IO_ERROR_NOT_SUPPORTED,
-                                 "Failed to locate git repository location");
-      return;
-    }
-
-  g_debug ("Located .git at %s", g_file_peek_path (location));
-
-  /* If @location is a regular file, we might have a git-worktree link */
-  if (g_file_query_file_type (location, 0, NULL) == G_FILE_TYPE_REGULAR)
-    {
-      g_autofree gchar *contents = NULL;
-      gsize len;
-
-      if (g_file_load_contents (location, NULL, &contents, &len, NULL, NULL))
-        {
-          IdeLineReader reader;
-          gchar *line;
-          gsize line_len;
+  g_autoptr(IdeVcs) vcs = NULL;
+  g_autoptr(GFile) workdir = NULL;
+  g_autoptr(GFile) dot_git = NULL;
+  g_autofree gchar *branch = NULL;
+  gboolean is_worktree = FALSE;
 
-          ide_line_reader_init (&reader, contents, len);
+  IDE_ENTRY;
 
-          while ((line = ide_line_reader_next (&reader, &line_len)))
-            {
-              line[line_len] = 0;
-
-              if (g_str_has_prefix (line, "gitdir: "))
-                {
-                  g_autoptr(GFile) location_parent = g_file_get_parent (location);
-                  const gchar *path = line + strlen ("gitdir: ");
-                  const gchar *branch;
-
-                  g_clear_object (&location);
-
-                  if (g_path_is_absolute (path))
-                    location = g_file_new_for_path (path);
-                  else
-                    location = g_file_resolve_relative_path (location_parent, path);
-
-                  /*
-                   * Worktrees only have a single branch, and it is the name
-                   * of the suffix of .git/worktrees/<name>
-                   */
-                  if ((branch = strrchr (line, G_DIR_SEPARATOR)))
-                    worktree_branch = g_strdup (branch + 1);
-
-                  break;
-                }
-            }
-        }
-    }
+  g_assert (GBP_IS_GIT_CLIENT (client));
+  g_assert (G_IS_ASYNC_RESULT (result));
+  g_assert (IDE_IS_TASK (task));
 
-  if (!(repository = ggit_repository_open (location, &error)))
+  if (!gbp_git_client_discover_finish (client, result, &workdir, &dot_git, &branch, &is_worktree, &error))
     {
       ide_task_return_error (task, g_steal_pointer (&error));
       return;
     }
 
-  workdir = ggit_repository_get_workdir (repository);
-
-  g_assert (G_IS_FILE (location));
-  g_assert (G_IS_FILE (workdir));
-  g_assert (GGIT_IS_REPOSITORY (repository));
-
-  if (worktree_branch == NULL)
-    {
-      g_autoptr(GgitRef) ref = NULL;
-
-      if ((ref = ggit_repository_get_head (repository, NULL)))
-        worktree_branch = g_strdup (ggit_ref_get_shorthand (ref));
-
-      if (worktree_branch == NULL)
-        worktree_branch = g_strdup ("master");
-    }
-
   vcs = g_object_new (GBP_TYPE_GIT_VCS,
-                      "branch-name", worktree_branch,
-                      "location", location,
-                      "repository", repository,
+                      "branch-name", branch,
                       "workdir", workdir,
+                      "location", dot_git,
                       NULL);
 
   ide_task_return_pointer (task, g_steal_pointer (&vcs), g_object_unref);
+
+  IDE_EXIT;
 }
 
 static void
@@ -156,6 +87,8 @@ gbp_git_workbench_addin_load_project_async (IdeWorkbenchAddin   *addin,
 {
   GbpGitWorkbenchAddin *self = (GbpGitWorkbenchAddin *)addin;
   g_autoptr(IdeTask) task = NULL;
+  GbpGitClient *client;
+  IdeContext *context;
   GFile *directory;
 
   g_assert (IDE_IS_MAIN_THREAD ());
@@ -177,11 +110,14 @@ gbp_git_workbench_addin_load_project_async (IdeWorkbenchAddin   *addin,
       return;
     }
 
-  /* Try to discover the git repository from a worker thread. If we find
-   * it, we'll set the VCS on the workbench for various components to use.
-   */
-  ide_task_set_task_data (task, g_object_ref (directory), g_object_unref);
-  ide_task_run_in_thread (task, gbp_git_workbench_addin_load_project_worker);
+  context = ide_workbench_get_context (self->workbench);
+  client = gbp_git_client_from_context (context);
+
+  gbp_git_client_discover_async (client,
+                                 directory,
+                                 cancellable,
+                                 gbp_git_workbench_addin_discover_cb,
+                                 g_steal_pointer (&task));
 }
 
 static void
diff --git a/src/plugins/git/gbp-git.c b/src/plugins/git/gbp-git.c
index 463029015..68fae4c8e 100644
--- a/src/plugins/git/gbp-git.c
+++ b/src/plugins/git/gbp-git.c
@@ -779,6 +779,7 @@ typedef struct
 {
   GFile *directory;
   GFile *workdir;
+  GFile *dot_git;
   gchar *branch;
   guint  is_worktree : 1;
 } Discover;
@@ -788,6 +789,7 @@ discover_free (Discover *state)
 {
   g_clear_object (&state->directory);
   g_clear_object (&state->workdir);
+  g_clear_object (&state->dot_git);
   g_clear_pointer (&state->branch, g_free);
   g_slice_free (Discover, state);
 }
@@ -889,6 +891,7 @@ gbp_git_discover_worker (GTask        *task,
     }
 
   state->workdir = g_file_dup (workdir);
+  state->dot_git = g_file_dup (location);
   state->branch = g_steal_pointer (&worktree_branch);
   state->is_worktree = !!is_worktree;
 
@@ -922,6 +925,7 @@ gboolean
 gbp_git_discover_finish (GbpGit        *self,
                          GAsyncResult  *result,
                          GFile        **workdir,
+                         GFile        **dot_git,
                          gchar        **branch,
                          gboolean      *is_worktree,
                          GError       **error)
@@ -929,6 +933,7 @@ gbp_git_discover_finish (GbpGit        *self,
   g_return_val_if_fail (GBP_IS_GIT (self), FALSE);
   g_return_val_if_fail (G_IS_TASK (result), FALSE);
   g_return_val_if_fail (workdir != NULL, FALSE);
+  g_return_val_if_fail (dot_git != NULL, FALSE);
   g_return_val_if_fail (branch != NULL, FALSE);
   g_return_val_if_fail (is_worktree != NULL, FALSE);
 
@@ -937,6 +942,7 @@ gbp_git_discover_finish (GbpGit        *self,
       Discover *state = g_task_get_task_data (G_TASK (result));
 
       *workdir = g_steal_pointer (&state->workdir);
+      *dot_git = g_steal_pointer (&state->dot_git);
       *branch = g_steal_pointer (&state->branch);
       *is_worktree = state->is_worktree;
 
diff --git a/src/plugins/git/gbp-git.h b/src/plugins/git/gbp-git.h
index 04120bd8b..7023e60f5 100644
--- a/src/plugins/git/gbp-git.h
+++ b/src/plugins/git/gbp-git.h
@@ -142,6 +142,7 @@ void       gbp_git_discover_async           (GbpGit                      *self,
 gboolean   gbp_git_discover_finish          (GbpGit                      *self,
                                              GAsyncResult                *result,
                                              GFile                      **workdir,
+                                             GFile                      **dot_git,
                                              gchar                      **branch,
                                              gboolean                    *is_worktree,
                                              GError                     **error);
diff --git a/src/plugins/git/gnome-builder-git.c b/src/plugins/git/gnome-builder-git.c
index 4e1a58b43..6a7cbd3a7 100644
--- a/src/plugins/git/gnome-builder-git.c
+++ b/src/plugins/git/gnome-builder-git.c
@@ -917,24 +917,28 @@ handle_discover_cb (GObject      *object,
   g_autoptr(ClientOp) op = user_data;
   g_autoptr(GVariant) reply = NULL;
   g_autoptr(GError) error = NULL;
+  g_autoptr(GFile) dot_git = NULL;
   g_autoptr(GFile) workdir = NULL;
   g_autofree gchar *branch = NULL;
   g_autofree gchar *uri = NULL;
+  g_autofree gchar *gituri = NULL;
   gboolean is_worktree = FALSE;
 
   g_assert (GBP_IS_GIT (git));
   g_assert (G_IS_ASYNC_RESULT (result));
   g_assert (op != NULL);
 
-  if (!gbp_git_discover_finish (git, result, &workdir, &branch, &is_worktree, &error))
+  if (!gbp_git_discover_finish (git, result, &workdir, &dot_git, &branch, &is_worktree, &error))
     {
       client_op_error (op, error);
       return;
     }
 
+  gituri = g_file_get_uri (dot_git);
   uri = g_file_get_uri (workdir);
 
   reply = JSONRPC_MESSAGE_NEW (
+    "gitdir", JSONRPC_MESSAGE_PUT_STRING (gituri),
     "workdir", JSONRPC_MESSAGE_PUT_STRING (uri),
     "branch", JSONRPC_MESSAGE_PUT_STRING (branch),
     "is-worktree", JSONRPC_MESSAGE_PUT_BOOLEAN (is_worktree)


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]