diff --git a/builder/Makefile.am.inc b/builder/Makefile.am.inc index b9af2058..ab700c8d 100644 --- a/builder/Makefile.am.inc +++ b/builder/Makefile.am.inc @@ -34,6 +34,8 @@ flatpak_builder_SOURCES = \ builder/builder-cache.h \ builder/builder-utils.c \ builder/builder-utils.h \ + builder/builder-git.c \ + builder/builder-git.h \ $(NULL) flatpak_builder_LDADD = $(BASE_LIBS) $(OSTREE_LIBS) $(JSON_LIBS) $(SOUP_LIBS) $(LIBELF_LIBS) \ diff --git a/builder/builder-git.c b/builder/builder-git.c new file mode 100644 index 00000000..6dedd985 --- /dev/null +++ b/builder/builder-git.c @@ -0,0 +1,425 @@ +/* builder-git.c + * + * Copyright (C) 2015 Red Hat, Inc + * + * This file is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This file 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + * + * Authors: + * Alexander Larsson + */ + +#include "config.h" + +#include +#include +#include +#include +#include + +#include "builder-utils.h" + +#include "builder-git.h" +#include "builder-utils.h" +#include "flatpak-utils.h" + +static gboolean +git (GFile *dir, + char **output, + GError **error, + ...) +{ + gboolean res; + va_list ap; + + va_start (ap, error); + res = flatpak_spawn (dir, output, error, "git", ap); + va_end (ap); + + return res; +} + +static GFile * +git_get_mirror_dir (const char *url_or_path, + BuilderContext *context) +{ + g_autoptr(GFile) git_dir = NULL; + g_autofree char *filename = NULL; + g_autofree char *git_dir_path = NULL; + + git_dir = g_file_get_child (builder_context_get_state_dir (context), + "git"); + + git_dir_path = g_file_get_path (git_dir); + g_mkdir_with_parents (git_dir_path, 0755); + + /* Technically a path isn't a uri but if it's absolute it should still be unique. */ + filename = builder_uri_to_filename (url_or_path); + return g_file_get_child (git_dir, filename); +} + +static char * +git_get_current_commit (GFile *repo_dir, + const char *branch, + BuilderContext *context, + GError **error) +{ + char *output = NULL; + + if (!git (repo_dir, &output, error, + "rev-parse", branch, NULL)) + return NULL; + + /* Trim trailing whitespace */ + g_strchomp (output); + + return output; +} + +char * +builder_git_get_current_commit (const char *repo_location, + const char *branch, + BuilderContext *context, + GError **error) +{ + g_autoptr(GFile) mirror_dir = NULL; + + mirror_dir = git_get_mirror_dir (repo_location, context); + return git_get_current_commit (mirror_dir, branch, context, error); +} + +char * +make_absolute (const char *orig_parent, const char *orig_relpath, GError **error) +{ + g_autofree char *parent = g_strdup (orig_parent); + const char *relpath = orig_relpath; + char *start; + char *parent_path; + + if (!g_str_has_prefix (relpath, "../")) + return g_strdup (orig_relpath); + + if (parent[strlen (parent) - 1] == '/') + parent[strlen (parent) - 1] = 0; + + if ((start = strstr (parent, "://"))) + start = start + 3; + else + start = parent; + + parent_path = strchr (start, '/'); + if (parent_path == NULL) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Invalid uri or path %s", orig_parent); + return NULL; + } + + while (g_str_has_prefix (relpath, "../")) + { + char *last_slash = strrchr (parent_path, '/'); + if (last_slash == NULL) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Invalid relative path %s for uri or path %s", orig_relpath, orig_parent); + return NULL; + } + relpath += 3; + *last_slash = 0; + } + + return g_strconcat (parent, "/", relpath, NULL); +} + +static gboolean +git_mirror_submodules (const char *repo_location, + gboolean update, + GFile *mirror_dir, + const char *revision, + BuilderContext *context, + GError **error) +{ + g_autoptr(GKeyFile) key_file = g_key_file_new (); + g_autofree gchar *rev_parse_output = NULL; + g_autofree gchar *submodule_data = NULL; + g_autofree gchar **submodules = NULL; + g_autofree gchar *gitmodules = g_strconcat (revision, ":.gitmodules", NULL); + gsize num_submodules; + + if (!git (mirror_dir, &rev_parse_output, NULL, "rev-parse", "--verify", "--quiet", gitmodules, NULL)) + return TRUE; + + if (git (mirror_dir, &submodule_data, NULL, "show", gitmodules, NULL)) + { + if (!g_key_file_load_from_data (key_file, submodule_data, -1, + G_KEY_FILE_NONE, error)) + return FALSE; + + submodules = g_key_file_get_groups (key_file, &num_submodules); + + int i; + for (i = 0; i < num_submodules; i++) + { + g_autofree gchar *submodule = NULL; + g_autofree gchar *path = NULL; + g_autofree gchar *relative_url = NULL; + g_autofree gchar *absolute_url = NULL; + g_autofree gchar *ls_tree = NULL; + g_auto(GStrv) lines = NULL; + g_auto(GStrv) words = NULL; + + submodule = submodules[i]; + + if (!g_str_has_prefix (submodule, "submodule \"")) + continue; + + path = g_key_file_get_string (key_file, submodule, "path", error); + if (path == NULL) + return FALSE; + + relative_url = g_key_file_get_string (key_file, submodule, "url", error); + absolute_url = make_absolute (repo_location, relative_url, error); + if (absolute_url == NULL) + return FALSE; + + if (!git (mirror_dir, &ls_tree, error, "ls-tree", revision, path, NULL)) + return FALSE; + + lines = g_strsplit (g_strstrip (ls_tree), "\n", 0); + if (g_strv_length (lines) != 1) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Not a gitlink tree: %s", path); + return FALSE; + } + + words = g_strsplit_set (lines[0], " \t", 4); + + if (g_strcmp0 (words[0], "160000") != 0) + continue; + + if (!builder_git_mirror_repo (absolute_url, update, TRUE, words[2], context, error)) + return FALSE; + } + } + + return TRUE; +} + +gboolean +builder_git_mirror_repo (const char *repo_location, + gboolean update, + gboolean mirror_submodules, + const char *ref, + BuilderContext *context, + GError **error) +{ + g_autoptr(GFile) mirror_dir = NULL; + g_autofree char *current_commit = NULL; + + mirror_dir = git_get_mirror_dir (repo_location, context); + + if (!g_file_query_exists (mirror_dir, NULL)) + { + g_autofree char *filename = g_file_get_basename (mirror_dir); + g_autoptr(GFile) parent = g_file_get_parent (mirror_dir); + g_autofree char *filename_tmp = g_strconcat (filename, ".clone_tmp", NULL); + g_autoptr(GFile) mirror_dir_tmp = g_file_get_child (parent, filename_tmp); + + g_print ("Cloning git repo %s\n", repo_location); + + if (!git (parent, NULL, error, + "clone", "--mirror", repo_location, filename_tmp, NULL) || + !g_file_move (mirror_dir_tmp, mirror_dir, 0, NULL, NULL, NULL, error)) + return FALSE; + } + else if (update) + { + g_print ("Fetching git repo %s\n", repo_location); + if (!git (mirror_dir, NULL, error, + "fetch", "-p", NULL)) + return FALSE; + } + + current_commit = git_get_current_commit (mirror_dir, ref, context, error); + if (current_commit == NULL) + return FALSE; + + if (!git_mirror_submodules (repo_location, update, mirror_dir, current_commit, context, error)) + return FALSE; + + return TRUE; +} + +static gboolean +git_extract_submodule (const char *repo_location, + GFile *checkout_dir, + const char *revision, + BuilderContext *context, + GError **error) +{ + g_autoptr(GKeyFile) key_file = g_key_file_new (); + g_autofree gchar *rev_parse_output = NULL; + g_autofree gchar *submodule_data = NULL; + g_autofree gchar **submodules = NULL; + g_autofree gchar *gitmodules = g_strconcat (revision, ":.gitmodules", NULL); + gsize num_submodules; + + if (!git (checkout_dir, &rev_parse_output, NULL, "rev-parse", "--verify", "--quiet", gitmodules, NULL)) + return TRUE; + + if (git (checkout_dir, &submodule_data, NULL, "show", gitmodules, NULL)) + { + if (!g_key_file_load_from_data (key_file, submodule_data, -1, + G_KEY_FILE_NONE, error)) + return FALSE; + + submodules = g_key_file_get_groups (key_file, &num_submodules); + + int i; + for (i = 0; i < num_submodules; i++) + { + g_autofree gchar *submodule = NULL; + g_autofree gchar *name = NULL; + g_autofree gchar *update_method = NULL; + g_autofree gchar *path = NULL; + g_autofree gchar *relative_url = NULL; + g_autofree gchar *absolute_url = NULL; + g_autofree gchar *ls_tree = NULL; + g_auto(GStrv) lines = NULL; + g_auto(GStrv) words = NULL; + g_autoptr(GFile) mirror_dir = NULL; + g_autoptr(GFile) child_dir = NULL; + g_autofree gchar *mirror_dir_as_url = NULL; + g_autofree gchar *option = NULL; + gsize len; + + submodule = submodules[i]; + len = strlen (submodule); + + if (!g_str_has_prefix (submodule, "submodule \"")) + continue; + + name = g_strndup (submodule + 11, len - 12); + + /* Skip any submodules that are disabled (have the update method set to "none") + Only check if the command succeeds. If it fails, the update method is not set. */ + update_method = g_key_file_get_string (key_file, submodule, "update", NULL); + if (g_strcmp0 (update_method, "none") == 0) + continue; + + path = g_key_file_get_string (key_file, submodule, "path", error); + if (path == NULL) + return FALSE; + + relative_url = g_key_file_get_string (key_file, submodule, "url", error); + absolute_url = make_absolute (repo_location, relative_url, error); + if (absolute_url == NULL) + return FALSE; + + if (!git (checkout_dir, &ls_tree, error, "ls-tree", revision, path, NULL)) + return FALSE; + + lines = g_strsplit (g_strstrip (ls_tree), "\n", 0); + if (g_strv_length (lines) != 1) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Not a gitlink tree: %s", path); + return FALSE; + } + + words = g_strsplit_set (lines[0], " \t", 4); + + if (g_strcmp0 (words[0], "160000") != 0) + continue; + + mirror_dir = git_get_mirror_dir (absolute_url, context); + mirror_dir_as_url = g_file_get_uri (mirror_dir); + option = g_strdup_printf ("submodule.%s.url", name); + + if (!git (checkout_dir, NULL, error, + "config", option, mirror_dir_as_url, NULL)) + return FALSE; + + if (!git (checkout_dir, NULL, error, + "submodule", "update", "--init", path, NULL)) + return FALSE; + + child_dir = g_file_resolve_relative_path (checkout_dir, path); + + if (!git_extract_submodule (absolute_url, child_dir, words[2], context, error)) + return FALSE; + } + } + + return TRUE; +} + +gboolean +builder_git_checkout_dir (const char *repo_location, + const char *branch, + const char *dir, + GFile *dest, + BuilderContext *context, + GError **error) +{ + g_autoptr(GFile) mirror_dir = NULL; + g_autofree char *mirror_dir_path = NULL; + g_autofree char *dest_path = NULL; + + mirror_dir = git_get_mirror_dir (repo_location, context); + + mirror_dir_path = g_file_get_path (mirror_dir); + dest_path = g_file_get_path (dest); + + if (!git (NULL, NULL, error, + "clone", "-n", mirror_dir_path, dest_path, NULL)) + return FALSE; + + if (!git (dest, NULL, error, + "checkout", branch, "--", dir ? dir : ".", NULL)) + return FALSE; + + return TRUE; +} + +gboolean +builder_git_checkout (const char *repo_location, + const char *branch, + GFile *dest, + BuilderContext *context, + GError **error) +{ + g_autoptr(GFile) mirror_dir = NULL; + g_autofree char *mirror_dir_path = NULL; + g_autofree char *dest_path = NULL; + + mirror_dir = git_get_mirror_dir (repo_location, context); + + mirror_dir_path = g_file_get_path (mirror_dir); + dest_path = g_file_get_path (dest); + + if (!git (NULL, NULL, error, + "clone", mirror_dir_path, dest_path, NULL)) + return FALSE; + + if (!git (dest, NULL, error, + "checkout", branch, NULL)) + return FALSE; + + if (!git_extract_submodule (repo_location, dest, branch, context, error)) + return FALSE; + + if (!git (dest, NULL, error, + "config", "--local", "remote.origin.url", + repo_location, NULL)) + return FALSE; + + return TRUE; +} diff --git a/builder/builder-git.h b/builder/builder-git.h new file mode 100644 index 00000000..fb0cf9c1 --- /dev/null +++ b/builder/builder-git.h @@ -0,0 +1,52 @@ +/* + * Copyright © 2015 Red Hat, Inc + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + * + * Authors: + * Alexander Larsson + */ + +#ifndef __BUILDER_GIT_H__ +#define __BUILDER_GIT_H__ + +#include "builder-context.h" + +G_BEGIN_DECLS + +gboolean builder_git_mirror_repo (const char *repo_location, + gboolean update, + gboolean mirror_submodules, + const char *ref, + BuilderContext *context, + GError **error); +char * builder_git_get_current_commit (const char *repo_location, + const char *branch, + BuilderContext *context, + GError **error); +gboolean builder_git_checkout (const char *repo_location, + const char *branch, + GFile *dest, + BuilderContext *context, + GError **error); +gboolean builder_git_checkout_dir (const char *repo_location, + const char *branch, + const char *dir, + GFile *dest, + BuilderContext *context, + GError **error); + +G_END_DECLS + +#endif /* __BUILDER_GIT_H__ */ diff --git a/builder/builder-source-git.c b/builder/builder-source-git.c index 81df634b..fbce468b 100644 --- a/builder/builder-source-git.c +++ b/builder/builder-source-git.c @@ -30,6 +30,7 @@ #include "builder-utils.h" #include "builder-source-git.h" +#include "builder-git.h" #include "builder-utils.h" #include "flatpak-utils.h" @@ -57,13 +58,6 @@ enum { LAST_PROP }; -static gboolean git_mirror_repo (const char *repo_url, - gboolean update, - const char *ref, - BuilderContext *context, - GError **error); - - static void builder_source_git_finalize (GObject *object) { @@ -133,41 +127,6 @@ builder_source_git_set_property (GObject *object, } } -static gboolean -git (GFile *dir, - char **output, - GError **error, - ...) -{ - gboolean res; - va_list ap; - - va_start (ap, error); - res = flatpak_spawn (dir, output, error, "git", ap); - va_end (ap); - - return res; -} - -static GFile * -git_get_mirror_dir (const char *url_or_path, - BuilderContext *context) -{ - g_autoptr(GFile) git_dir = NULL; - g_autofree char *filename = NULL; - g_autofree char *git_dir_path = NULL; - - git_dir = g_file_get_child (builder_context_get_state_dir (context), - "git"); - - git_dir_path = g_file_get_path (git_dir); - g_mkdir_with_parents (git_dir_path, 0755); - - /* Technically a path isn't a uri but if it's absolute it should still be unique. */ - filename = builder_uri_to_filename (url_or_path); - return g_file_get_child (git_dir, filename); -} - static const char * get_branch (BuilderSourceGit *self) { @@ -209,183 +168,6 @@ get_url_or_path (BuilderSourceGit *self, return g_file_get_path (repo); } -static char * -git_get_current_commit (GFile *repo_dir, - const char *branch, - BuilderContext *context, - GError **error) -{ - char *output = NULL; - - if (!git (repo_dir, &output, error, - "rev-parse", branch, NULL)) - return NULL; - - /* Trim trailing whitespace */ - g_strchomp (output); - - return output; -} - -char * -make_absolute (const char *orig_parent, const char *orig_relpath, GError **error) -{ - g_autofree char *parent = g_strdup (orig_parent); - const char *relpath = orig_relpath; - char *start; - char *parent_path; - - if (!g_str_has_prefix (relpath, "../")) - return g_strdup (orig_relpath); - - if (parent[strlen (parent) - 1] == '/') - parent[strlen (parent) - 1] = 0; - - if ((start = strstr (parent, "://"))) - start = start + 3; - else - start = parent; - - parent_path = strchr (start, '/'); - if (parent_path == NULL) - { - g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Invalid uri or path %s", orig_parent); - return NULL; - } - - while (g_str_has_prefix (relpath, "../")) - { - char *last_slash = strrchr (parent_path, '/'); - if (last_slash == NULL) - { - g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Invalid relative path %s for uri or path %s", orig_relpath, orig_parent); - return NULL; - } - relpath += 3; - *last_slash = 0; - } - - return g_strconcat (parent, "/", relpath, NULL); -} - -static gboolean -git_mirror_submodules (const char *repo_location, - gboolean update, - GFile *mirror_dir, - const char *revision, - BuilderContext *context, - GError **error) -{ - g_autoptr(GKeyFile) key_file = g_key_file_new (); - g_autofree gchar *rev_parse_output = NULL; - g_autofree gchar *submodule_data = NULL; - g_autofree gchar **submodules = NULL; - g_autofree gchar *gitmodules = g_strconcat (revision, ":.gitmodules", NULL); - gsize num_submodules; - - if (!git (mirror_dir, &rev_parse_output, NULL, "rev-parse", "--verify", "--quiet", gitmodules, NULL)) - return TRUE; - - if (git (mirror_dir, &submodule_data, NULL, "show", gitmodules, NULL)) - { - if (!g_key_file_load_from_data (key_file, submodule_data, -1, - G_KEY_FILE_NONE, error)) - return FALSE; - - submodules = g_key_file_get_groups (key_file, &num_submodules); - - int i; - for (i = 0; i < num_submodules; i++) - { - g_autofree gchar *submodule = NULL; - g_autofree gchar *path = NULL; - g_autofree gchar *relative_url = NULL; - g_autofree gchar *absolute_url = NULL; - g_autofree gchar *ls_tree = NULL; - g_auto(GStrv) lines = NULL; - g_auto(GStrv) words = NULL; - - submodule = submodules[i]; - - if (!g_str_has_prefix (submodule, "submodule \"")) - continue; - - path = g_key_file_get_string (key_file, submodule, "path", error); - if (path == NULL) - return FALSE; - - relative_url = g_key_file_get_string (key_file, submodule, "url", error); - absolute_url = make_absolute (repo_location, relative_url, error); - if (absolute_url == NULL) - return FALSE; - - if (!git (mirror_dir, &ls_tree, error, "ls-tree", revision, path, NULL)) - return FALSE; - - lines = g_strsplit (g_strstrip (ls_tree), "\n", 0); - if (g_strv_length (lines) != 1) - { - g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Not a gitlink tree: %s", path); - return FALSE; - } - - words = g_strsplit_set (lines[0], " \t", 4); - - if (g_strcmp0 (words[0], "160000") != 0) - continue; - - if (!git_mirror_repo (absolute_url, update, words[2], context, error)) - return FALSE; - } - } - - return TRUE; -} - -static gboolean -git_mirror_repo (const char *repo_location, - gboolean update, - const char *ref, - BuilderContext *context, - GError **error) -{ - g_autoptr(GFile) mirror_dir = NULL; - g_autofree char *current_commit = NULL; - - mirror_dir = git_get_mirror_dir (repo_location, context); - - if (!g_file_query_exists (mirror_dir, NULL)) - { - g_autofree char *filename = g_file_get_basename (mirror_dir); - g_autoptr(GFile) parent = g_file_get_parent (mirror_dir); - g_autofree char *filename_tmp = g_strconcat (filename, ".clone_tmp", NULL); - g_autoptr(GFile) mirror_dir_tmp = g_file_get_child (parent, filename_tmp); - - g_print ("Cloning git repo %s\n", repo_location); - - if (!git (parent, NULL, error, - "clone", "--mirror", repo_location, filename_tmp, NULL) || - !g_file_move (mirror_dir_tmp, mirror_dir, 0, NULL, NULL, NULL, error)) - return FALSE; - } - else if (update) - { - g_print ("Fetching git repo %s\n", repo_location); - if (!git (mirror_dir, NULL, error, - "fetch", "-p", NULL)) - return FALSE; - } - - current_commit = git_get_current_commit (mirror_dir, ref, context, error); - if (current_commit == NULL) - return FALSE; - - if (!git_mirror_submodules (repo_location, update, mirror_dir, current_commit, context, error)) - return FALSE; - - return TRUE; -} - static gboolean builder_source_git_download (BuilderSource *source, gboolean update_vcs, @@ -399,119 +181,16 @@ builder_source_git_download (BuilderSource *source, if (location == NULL) return FALSE; - if (!git_mirror_repo (location, - update_vcs, - get_branch (self), - context, - error)) + if (!builder_git_mirror_repo (location, + update_vcs, TRUE, + get_branch (self), + context, + error)) return FALSE; return TRUE; } -static gboolean -git_extract_submodule (const char *repo_location, - GFile *checkout_dir, - const char *revision, - BuilderContext *context, - GError **error) -{ - g_autoptr(GKeyFile) key_file = g_key_file_new (); - g_autofree gchar *rev_parse_output = NULL; - g_autofree gchar *submodule_data = NULL; - g_autofree gchar **submodules = NULL; - g_autofree gchar *gitmodules = g_strconcat (revision, ":.gitmodules", NULL); - gsize num_submodules; - - if (!git (checkout_dir, &rev_parse_output, NULL, "rev-parse", "--verify", "--quiet", gitmodules, NULL)) - return TRUE; - - if (git (checkout_dir, &submodule_data, NULL, "show", gitmodules, NULL)) - { - if (!g_key_file_load_from_data (key_file, submodule_data, -1, - G_KEY_FILE_NONE, error)) - return FALSE; - - submodules = g_key_file_get_groups (key_file, &num_submodules); - - int i; - for (i = 0; i < num_submodules; i++) - { - g_autofree gchar *submodule = NULL; - g_autofree gchar *name = NULL; - g_autofree gchar *update_method = NULL; - g_autofree gchar *path = NULL; - g_autofree gchar *relative_url = NULL; - g_autofree gchar *absolute_url = NULL; - g_autofree gchar *ls_tree = NULL; - g_auto(GStrv) lines = NULL; - g_auto(GStrv) words = NULL; - g_autoptr(GFile) mirror_dir = NULL; - g_autoptr(GFile) child_dir = NULL; - g_autofree gchar *mirror_dir_as_url = NULL; - g_autofree gchar *option = NULL; - gsize len; - - submodule = submodules[i]; - len = strlen (submodule); - - if (!g_str_has_prefix (submodule, "submodule \"")) - continue; - - name = g_strndup (submodule + 11, len - 12); - - /* Skip any submodules that are disabled (have the update method set to "none") - Only check if the command succeeds. If it fails, the update method is not set. */ - update_method = g_key_file_get_string (key_file, submodule, "update", NULL); - if (g_strcmp0 (update_method, "none") == 0) - continue; - - path = g_key_file_get_string (key_file, submodule, "path", error); - if (path == NULL) - return FALSE; - - relative_url = g_key_file_get_string (key_file, submodule, "url", error); - absolute_url = make_absolute (repo_location, relative_url, error); - if (absolute_url == NULL) - return FALSE; - - if (!git (checkout_dir, &ls_tree, error, "ls-tree", revision, path, NULL)) - return FALSE; - - lines = g_strsplit (g_strstrip (ls_tree), "\n", 0); - if (g_strv_length (lines) != 1) - { - g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Not a gitlink tree: %s", path); - return FALSE; - } - - words = g_strsplit_set (lines[0], " \t", 4); - - if (g_strcmp0 (words[0], "160000") != 0) - continue; - - mirror_dir = git_get_mirror_dir (absolute_url, context); - mirror_dir_as_url = g_file_get_uri (mirror_dir); - option = g_strdup_printf ("submodule.%s.url", name); - - if (!git (checkout_dir, NULL, error, - "config", option, mirror_dir_as_url, NULL)) - return FALSE; - - if (!git (checkout_dir, NULL, error, - "submodule", "update", "--init", path, NULL)) - return FALSE; - - child_dir = g_file_resolve_relative_path (checkout_dir, path); - - if (!git_extract_submodule (absolute_url, child_dir, words[2], context, error)) - return FALSE; - } - } - - return TRUE; -} - static gboolean builder_source_git_extract (BuilderSource *source, GFile *dest, @@ -520,35 +199,14 @@ builder_source_git_extract (BuilderSource *source, GError **error) { BuilderSourceGit *self = BUILDER_SOURCE_GIT (source); - - g_autoptr(GFile) mirror_dir = NULL; - g_autofree char *mirror_dir_path = NULL; - g_autofree char *dest_path = NULL; g_autofree char *location = NULL; location = get_url_or_path (self, context, error); if (location == NULL) return FALSE; - mirror_dir = git_get_mirror_dir (location, context); - - mirror_dir_path = g_file_get_path (mirror_dir); - dest_path = g_file_get_path (dest); - - if (!git (NULL, NULL, error, - "clone", mirror_dir_path, dest_path, NULL)) - return FALSE; - - if (!git (dest, NULL, error, - "checkout", get_branch (self), NULL)) - return FALSE; - - if (!git_extract_submodule (location, dest, get_branch (self), context, error)) - return FALSE; - - if (!git (dest, NULL, error, - "config", "--local", "remote.origin.url", - location, NULL)) + if (!builder_git_checkout (location, get_branch (self), + dest, context, error)) return FALSE; return TRUE; @@ -560,8 +218,6 @@ builder_source_git_checksum (BuilderSource *source, BuilderContext *context) { BuilderSourceGit *self = BUILDER_SOURCE_GIT (source); - - g_autoptr(GFile) mirror_dir = NULL; g_autofree char *current_commit = NULL; g_autoptr(GError) error = NULL; g_autofree char *location = NULL; @@ -573,9 +229,7 @@ builder_source_git_checksum (BuilderSource *source, location = get_url_or_path (self, context, &error); if (location != NULL) { - mirror_dir = git_get_mirror_dir (location, context); - - current_commit = git_get_current_commit (mirror_dir, get_branch (self), context, &error); + current_commit = builder_git_get_current_commit (location,get_branch (self), context, &error); if (current_commit) builder_cache_checksum_str (cache, current_commit); else if (error) @@ -593,8 +247,6 @@ builder_source_git_update (BuilderSource *source, GError **error) { BuilderSourceGit *self = BUILDER_SOURCE_GIT (source); - - g_autoptr(GFile) mirror_dir = NULL; char *current_commit; g_autofree char *location = NULL; @@ -602,9 +254,7 @@ builder_source_git_update (BuilderSource *source, if (location == NULL) return FALSE; - mirror_dir = git_get_mirror_dir (location, context); - - current_commit = git_get_current_commit (mirror_dir, get_branch (self), context, NULL); + current_commit = builder_git_get_current_commit (location, get_branch (self), context, NULL); if (current_commit) { g_free (self->branch);