[libgit2-glib] Add initial clone support.



commit dbf771c1377167424d2b16ecc13bba9a939b8c51
Author: Ignacio Casal Quinteiro <icq gnome org>
Date:   Tue Mar 19 17:18:05 2013 +0100

    Add initial clone support.
    
    Some of the members in git_clone_options are still missing.

 libgit2-glib/Makefile.am          |    2 +
 libgit2-glib/ggit-clone-options.c |  429 +++++++++++++++++++++++++++++++++++++
 libgit2-glib/ggit-clone-options.h |   91 ++++++++
 libgit2-glib/ggit-repository.c    |   75 +++++++-
 libgit2-glib/ggit-repository.h    |    5 +
 libgit2-glib/ggit-types.h         |    7 +
 6 files changed, 608 insertions(+), 1 deletions(-)
---
diff --git a/libgit2-glib/Makefile.am b/libgit2-glib/Makefile.am
index 4e610f5..5d81a2e 100644
--- a/libgit2-glib/Makefile.am
+++ b/libgit2-glib/Makefile.am
@@ -17,6 +17,7 @@ libgit2_glib_1_0_la_LIBADD = $(LIBGIT2_GLIB_LIBS)
 INST_H_FILES =                         \
        ggit-blob.h                     \
        ggit-branch.h                   \
+       ggit-clone-options.h            \
        ggit-commit.h                   \
        ggit-config.h                   \
        ggit-config-entry.h             \
@@ -60,6 +61,7 @@ NOINST_H_FILES =                      \
 C_FILES =                              \
        ggit-blob.c                     \
        ggit-branch.c                   \
+       ggit-clone-options.c            \
        ggit-commit.c                   \
        ggit-config.c                   \
        ggit-config-entry.c             \
diff --git a/libgit2-glib/ggit-clone-options.c b/libgit2-glib/ggit-clone-options.c
new file mode 100644
index 0000000..024f176
--- /dev/null
+++ b/libgit2-glib/ggit-clone-options.c
@@ -0,0 +1,429 @@
+/*
+ * ggit-clone-options.c
+ * This file is part of libgit2-glib
+ *
+ * Copyright (C) 2013 - Ignacio Casal Quinteiro
+ *
+ * libgit2-glib 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.
+ *
+ * libgit2-glib 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 libgit2-glib. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <git2/errors.h>
+
+#include "ggit-clone-options.h"
+#include "ggit-native.h"
+
+struct _GgitCloneOptions
+{
+       git_clone_options clone_options;
+       GgitCredAcquireCallback cred_callback;
+       gpointer cred_user_data;
+};
+
+G_DEFINE_BOXED_TYPE (GgitCloneOptions, ggit_clone_options,
+                     ggit_clone_options_copy, ggit_clone_options_free)
+
+const git_clone_options *
+_ggit_clone_options_get_clone_options (GgitCloneOptions *clone_options)
+{
+       /* NULL is common for clone_options as it specifies to use the default
+        * so handle a NULL clone_options here instead of in every caller.
+        */
+       if (clone_options == NULL)
+       {
+               return NULL;
+       }
+
+       return (const git_clone_options *)&clone_options->clone_options;
+}
+
+static gint
+wrap_cred_acquire (git_cred **cred,
+                   const char *url,
+                   const char *username_from_url,
+                   unsigned int allowed_types,
+                   void *payload)
+{
+       GgitCred *gcred;
+       GgitCloneOptions *options = GGIT_CLONE_OPTIONS (payload);
+       gint ret;
+
+       ret= options->cred_callback (url, username_from_url, allowed_types, &gcred,
+                                    options->cred_user_data);
+
+       *cred = NULL;
+
+       if (gcred != NULL)
+       {
+               *cred = _ggit_native_get (gcred);
+
+               // NOTE: this is to be able to unref the cred and do not
+               // free wrapped object
+               _ggit_native_set_destroy_func (gcred, NULL);
+               g_object_unref (gcred);
+       }
+
+       return ret;
+}
+
+/**
+ * ggit_clone_options_copy:
+ * @clone_options: a #GgitCloneOptions.
+ *
+ * Copies @clone_options into a newly allocated #GgitCloneOptions.
+ *
+ * Returns: (transfer full): a newly allocated #GgitCloneOptions.
+ */
+GgitCloneOptions *
+ggit_clone_options_copy (GgitCloneOptions *clone_options)
+{
+       GgitCloneOptions *new_clone_options;
+       git_clone_options *gclone_options;
+       git_clone_options gnew_clone_options = GIT_CLONE_OPTIONS_INIT;
+
+       g_return_val_if_fail (clone_options != NULL, NULL);
+
+       gclone_options = &clone_options->clone_options;
+
+       new_clone_options = g_slice_new (GgitCloneOptions);
+
+       gnew_clone_options.bare = gclone_options->bare;
+       gnew_clone_options.fetch_progress_cb = gclone_options->fetch_progress_cb;
+       gnew_clone_options.fetch_progress_payload = gclone_options->fetch_progress_payload;
+       gnew_clone_options.remote_name = g_strdup (gclone_options->remote_name);
+       gnew_clone_options.pushurl = g_strdup (gclone_options->pushurl);
+       gnew_clone_options.fetch_spec = g_strdup (gclone_options->fetch_spec);
+       gnew_clone_options.push_spec = g_strdup (gclone_options->push_spec);
+       gnew_clone_options.remote_autotag = gclone_options->remote_autotag;
+       gnew_clone_options.checkout_branch = g_strdup (gclone_options->checkout_branch);
+
+       new_clone_options->clone_options = gnew_clone_options;
+       new_clone_options->cred_callback = clone_options->cred_callback;
+       new_clone_options->cred_user_data = clone_options->cred_user_data;
+
+       return new_clone_options;
+}
+
+/**
+ * ggit_clone_options_free:
+ * @clone_options: a #GgitCloneOptions.
+ *
+ * Frees @clone_options.
+ */
+void
+ggit_clone_options_free (GgitCloneOptions *clone_options)
+{
+       git_clone_options *gclone_options;
+
+       g_return_if_fail (clone_options != NULL);
+
+       gclone_options = &clone_options->clone_options;
+       g_free ((gchar *)gclone_options->remote_name);
+       g_free ((gchar *)gclone_options->pushurl);
+       g_free ((gchar *)gclone_options->fetch_spec);
+       g_free ((gchar *)gclone_options->push_spec);
+       g_free ((gchar *)gclone_options->checkout_branch);
+
+       g_slice_free (GgitCloneOptions, clone_options);
+}
+
+/**
+ * ggit_clone_options_new:
+ *
+ * Creates a new #GgitCloneOptions.
+ *
+ * Returns: a newly allocated #GgitCloneOptions.
+ */
+GgitCloneOptions *
+ggit_clone_options_new (void)
+{
+       GgitCloneOptions *clone_options;
+       git_clone_options gclone_options = GIT_CLONE_OPTIONS_INIT;
+
+       clone_options = g_slice_new (GgitCloneOptions);
+       clone_options->clone_options = gclone_options;
+
+       return clone_options;
+}
+
+/**
+ * ggit_clone_options_get_is_bare:
+ * @options: a #GgitCloneOptions.
+ *
+ * Gets if the repository will be bare.
+ *
+ * Returns: %TRUE to clone a bare repository.
+ */
+gboolean
+ggit_clone_options_get_is_bare (GgitCloneOptions *options)
+{
+       g_return_val_if_fail (options != NULL, FALSE);
+
+       return options->clone_options.bare;
+}
+
+/**
+ * ggit_clone_options_set_is_bare:
+ * @options: a #GgitCloneOptions.
+ * @bare: %TRUE to clone a bare repository.
+ *
+ * Sets whether to clone a bare repository.
+ */
+void
+ggit_clone_options_set_is_bare (GgitCloneOptions *options,
+                                gboolean          bare)
+{
+       g_return_if_fail (options != NULL);
+
+       options->clone_options.bare = bare;
+}
+
+/**
+ * ggit_clone_options_set_fetch_progress_callback:
+ * @options: a #GgitCloneOptions.
+ * @callback: (allow-none) (scope call) (closure user_data): callback for fetch progress.
+ * @user_data: callback user data.
+ *
+ * Sets the callback for fetch progress. Be aware that this is called inline
+ * with network and indexing operations, so performance may be affected.
+ */
+void
+ggit_clone_options_set_fetch_progress_callback (GgitCloneOptions             *options,
+                                                GgitTransferProgressCallback  callback,
+                                                gpointer                      user_data)
+{
+       g_return_if_fail (options != NULL);
+
+       options->clone_options.fetch_progress_cb = (git_transfer_progress_callback)callback;
+       options->clone_options.fetch_progress_payload = user_data;
+}
+
+/**
+ * ggit_clone_options_get_remote_name:
+ * @options: a #GgitCloneOptions.
+ *
+ * Gets the name given to the "origin" remote.  The default is "origin".
+ *
+ * Returns: the name given to the "origin" remote.  The default is "origin".
+ */
+const gchar *
+ggit_clone_options_get_remote_name (GgitCloneOptions *options)
+{
+       g_return_val_if_fail (options != NULL, NULL);
+
+       return options->clone_options.remote_name;
+}
+
+/**
+ * ggit_clone_options_set_remote_name:
+ * @options: a #GgitCloneOptions.
+ * @remote_name: (allow-none): the name given to the "origin" remote.
+ *
+ * Sets the name given to the "origin" remote.
+ */
+void
+ggit_clone_options_set_remote_name (GgitCloneOptions *options,
+                                    const gchar      *remote_name)
+{
+       g_return_if_fail (options != NULL);
+
+       options->clone_options.remote_name = g_strdup (remote_name);
+}
+
+/**
+ * ggit_clone_options_get_push_url:
+ * @options: a #GgitCloneOptions.
+ *
+ * Gets the URL to be used for pushing or %NULL.
+ *
+ * Returns: the URL to be used for pushing or %NULL.
+ */
+const gchar *
+ggit_clone_options_get_push_url (GgitCloneOptions *options)
+{
+       g_return_val_if_fail (options != NULL, NULL);
+
+       return options->clone_options.pushurl;
+}
+
+/**
+ * ggit_clone_options_set_push_url:
+ * @options: a #GgitCloneOptions.
+ * @push_url: (allow-none): the URL to be used for pushing. %NULL means use the fetch url.
+ *
+ * Sets the URL to be used for pushing. %NULL means use the fetch url.
+ */
+void
+ggit_clone_options_set_push_url (GgitCloneOptions *options,
+                                 const gchar      *push_url)
+{
+       g_return_if_fail (options != NULL);
+
+       options->clone_options.pushurl = g_strdup (push_url);
+}
+
+/**
+ * ggit_clone_options_get_fetch_spec:
+ * @options: a #GgitCloneOptions.
+ *
+ * Gets the fetch specification to be used or %NULL.
+ *
+ * Returns: the fetch specification to be used for fetching or %NULL.
+ */
+const gchar *
+ggit_clone_options_get_fetch_spec (GgitCloneOptions *options)
+{
+       g_return_val_if_fail (options != NULL, NULL);
+
+       return options->clone_options.fetch_spec;
+}
+
+/**
+ * ggit_clone_options_set_fetch_spec:
+ * @options: a #GgitCloneOptions.
+ * @fetch_spec: (allow-none): the fetch specification to be used for fetching or %NULL.
+ *
+ * Sets the fetch specification to be used for fetching. %NULL
+ * results in the same behavior as %GGIT_REMOTE_DEFAULT_FETCH.
+ */
+void
+ggit_clone_options_set_fetch_spec (GgitCloneOptions *options,
+                                   const gchar      *fetch_spec)
+{
+       g_return_if_fail (options != NULL);
+
+       options->clone_options.fetch_spec = g_strdup (fetch_spec);
+}
+
+/**
+ * ggit_clone_options_get_push_spec:
+ * @options: a #GgitCloneOptions.
+ *
+ * Gets the fetch specification to be used for pushing or %NULL.
+ *
+ * Returns: the fetch specification to be used for pushing or %NULL.
+ */
+const gchar *
+ggit_clone_options_get_push_spec (GgitCloneOptions *options)
+{
+       g_return_val_if_fail (options != NULL, NULL);
+
+       return options->clone_options.push_spec;
+}
+
+/**
+ * ggit_clone_options_set_push_spec:
+ * @options: a #GgitCloneOptions.
+ * @push_spec: (allow-none): the fetch specification to be used for pushing or %NULL.
+ *
+ * Sets fetch specification to be used for pushing. %NULL means
+ * use the same spec as for fetching.
+ */
+void
+ggit_clone_options_set_push_spec (GgitCloneOptions *options,
+                                  const gchar      *push_spec)
+{
+       g_return_if_fail (options != NULL);
+
+       options->clone_options.push_spec = g_strdup (push_spec);
+}
+
+/**
+ * ggit_clone_options_set_cred_acquire_callback:
+ * @options: a #GgitCloneOptions.
+ * @callback: (allow-none) (scope call) (closure user_data): callback if credentials are required.
+ * @user_data: callback user data.
+ *
+ * Sets the callback to be used if credentials are required
+ * during the initial fetch.
+ */
+void
+ggit_clone_options_set_cred_acquire_callback (GgitCloneOptions        *options,
+                                              GgitCredAcquireCallback  callback,
+                                              gpointer                 user_data)
+{
+       g_return_if_fail (options != NULL);
+
+       options->cred_callback = callback;
+       options->cred_user_data = user_data;
+       options->clone_options.cred_acquire_cb = wrap_cred_acquire;
+       options->clone_options.cred_acquire_payload = options;
+}
+
+/**
+ * ggit_clone_options_get_remote_auto_tag:
+ * @options: a #GgitCloneOptions.
+ *
+ * Gets the auto tag setting before the initial fetch.
+ * The default is @GGIT_REMOTE_DOWNLOAD_TAGS_ALL.
+ *
+ * Returns: a #GgitRemoteDownloadTagsType
+ */
+GgitRemoteDownloadTagsType
+ggit_clone_options_get_remote_auto_tag (GgitCloneOptions *options)
+{
+       g_return_val_if_fail (options != NULL, GGIT_REMOTE_DOWNLOAD_TAGS_ALL);
+
+       return options->clone_options.remote_autotag;
+}
+
+/**
+ * ggit_clone_options_set_remote_auto_tag:
+ * @options: a #GgitCloneOptions.
+ * @remote_auto_tag: a #GgitRemoteDownloadTagsType.
+ *
+ * Specifies the auto tag setting before the initial fetch.
+ */
+void
+ggit_clone_options_set_remote_auto_tag (GgitCloneOptions           *options,
+                                        GgitRemoteDownloadTagsType  remote_auto_tag)
+{
+       g_return_if_fail (options != NULL);
+
+       options->clone_options.remote_autotag = remote_auto_tag;
+}
+
+/**
+ * ggit_clone_options_get_checkout_branch:
+ * @options: a #GgitCloneOptions.
+ *
+ * Gets the name of the branch to checkout or %NULL.
+ *
+ * Returns: the name of the branch to checkout or %NULL.
+ */
+const gchar *
+ggit_clone_options_get_checkout_branch (GgitCloneOptions *options)
+{
+       g_return_val_if_fail (options != NULL, NULL);
+
+       return options->clone_options.checkout_branch;
+}
+
+/**
+ * ggit_clone_options_set_checkout_branch:
+ * @options: a #GgitCloneOptions.
+ * @checkout_branch: (allow-none): the name of the branch to checkout or %NULL.
+ *
+ * Gives the name of the branch to checkout. %NULL means
+ * use the remote's HEAD.
+ */
+void
+ggit_clone_options_set_checkout_branch (GgitCloneOptions *options,
+                                        const gchar      *checkout_branch)
+{
+       g_return_if_fail (options != NULL);
+
+       options->clone_options.checkout_branch = g_strdup (checkout_branch);
+}
+
+/* ex:set ts=8 noet: */
diff --git a/libgit2-glib/ggit-clone-options.h b/libgit2-glib/ggit-clone-options.h
new file mode 100644
index 0000000..9710d18
--- /dev/null
+++ b/libgit2-glib/ggit-clone-options.h
@@ -0,0 +1,91 @@
+/*
+ * ggit-clone-options.h
+ * This file is part of libgit2-glib
+ *
+ * Copyright (C) 2013 - Ignacio Casal Quinteiro
+ *
+ * libgit2-glib 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.
+ *
+ * libgit2-glib 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 libgit2-glib. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef __GGIT_CLONE_OPTIONS_H__
+#define __GGIT_CLONE_OPTIONS_H__
+
+#include <glib-object.h>
+#include <git2/clone.h>
+
+#include "ggit-types.h"
+
+G_BEGIN_DECLS
+
+#define GGIT_TYPE_CLONE_OPTIONS       (ggit_clone_options_get_type ())
+#define GGIT_CLONE_OPTIONS(obj)       ((GgitCloneOptions *)obj)
+
+GType                      ggit_clone_options_get_type            (void) G_GNUC_CONST;
+
+const git_clone_options  *_ggit_clone_options_get_clone_options   (GgitCloneOptions        *clone_options);
+
+GgitCloneOptions          *ggit_clone_options_copy                (GgitCloneOptions        *clone_options);
+void                       ggit_clone_options_free                (GgitCloneOptions        *clone_options);
+
+GgitCloneOptions          *ggit_clone_options_new                 (void);
+
+gboolean                   ggit_clone_options_get_is_bare         (GgitCloneOptions        *options);
+
+void                       ggit_clone_options_set_is_bare         (GgitCloneOptions        *options,
+                                                                   gboolean                 bare);
+
+void                       ggit_clone_options_set_fetch_progress_callback (GgitCloneOptions             
*options,
+                                                                           GgitTransferProgressCallback  
callback,
+                                                                           gpointer                      
user_data);
+
+const gchar               *ggit_clone_options_get_remote_name     (GgitCloneOptions        *options);
+
+void                       ggit_clone_options_set_remote_name     (GgitCloneOptions        *options,
+                                                                   const gchar             *remote_name);
+
+const gchar               *ggit_clone_options_get_push_url        (GgitCloneOptions        *options);
+
+void                       ggit_clone_options_set_push_url        (GgitCloneOptions        *options,
+                                                                   const gchar             *push_url);
+
+const gchar               *ggit_clone_options_get_fetch_spec      (GgitCloneOptions        *options);
+
+void                       ggit_clone_options_set_fetch_spec      (GgitCloneOptions        *options,
+                                                                   const gchar             *fetch_spec);
+
+const gchar               *ggit_clone_options_get_push_spec       (GgitCloneOptions        *options);
+
+void                       ggit_clone_options_set_push_spec       (GgitCloneOptions        *options,
+                                                                   const gchar             *push_spec);
+
+void                       ggit_clone_options_set_cred_acquire_callback (GgitCloneOptions        *options,
+                                                                         GgitCredAcquireCallback  callback,
+                                                                         gpointer                 user_data);
+
+GgitRemoteDownloadTagsType ggit_clone_options_get_remote_auto_tag (GgitCloneOptions        *options);
+
+void                       ggit_clone_options_set_remote_auto_tag (GgitCloneOptions           *options,
+                                                                   GgitRemoteDownloadTagsType  
remote_auto_tag);
+
+const gchar               *ggit_clone_options_get_checkout_branch (GgitCloneOptions        *options);
+
+void                       ggit_clone_options_set_checkout_branch (GgitCloneOptions        *options,
+                                                                   const gchar             *checkout_branch);
+
+G_END_DECLS
+
+#endif /* __GGIT_CLONE_OPTIONS_H__ */
+
+/* ex:set ts=8 noet: */
diff --git a/libgit2-glib/ggit-repository.c b/libgit2-glib/ggit-repository.c
index a0f99f4..4c9c444 100644
--- a/libgit2-glib/ggit-repository.c
+++ b/libgit2-glib/ggit-repository.c
@@ -39,14 +39,18 @@
 #include "ggit-remote.h"
 #include "ggit-submodule.h"
 #include "ggit-signature.h"
+#include "ggit-clone-options.h"
 
 #define GGIT_REPOSITORY_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE((object), GGIT_TYPE_REPOSITORY, 
GgitRepositoryPrivate))
 
 struct _GgitRepositoryPrivate
 {
+       gchar *url;
        GFile *location;
        GFile *workdir;
 
+       GgitCloneOptions *clone_options;
+
        guint is_bare : 1;
        guint init : 1;
 };
@@ -54,11 +58,13 @@ struct _GgitRepositoryPrivate
 enum
 {
        PROP_0,
+       PROP_URL,
        PROP_LOCATION,
        PROP_IS_BARE,
        PROP_INIT,
        PROP_WORKDIR,
-       PROP_HEAD
+       PROP_HEAD,
+       PROP_CLONE_OPTIONS
 };
 
 static void ggit_repository_initable_iface_init (GInitableIface  *iface);
@@ -73,6 +79,7 @@ ggit_repository_finalize (GObject *object)
 {
        GgitRepositoryPrivate *priv = GGIT_REPOSITORY (object)->priv;
 
+       g_free (priv->url);
        g_clear_object (&priv->location);
        g_clear_object (&priv->workdir);
 
@@ -90,6 +97,9 @@ ggit_repository_get_property (GObject    *object,
 
        switch (prop_id)
        {
+               case PROP_URL:
+                       g_value_set_string (value, priv->url);
+                       break;
                case PROP_LOCATION:
                        g_value_take_object (value,
                                             ggit_repository_get_location (repository));
@@ -110,6 +120,9 @@ ggit_repository_get_property (GObject    *object,
                        g_value_set_object (value,
                                            ggit_repository_get_head (repository, NULL));
                        break;
+               case PROP_CLONE_OPTIONS:
+                       g_value_set_boxed (value, priv->clone_options);
+                       break;
                default:
                        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
                        break;
@@ -158,6 +171,9 @@ ggit_repository_set_property (GObject      *object,
 
        switch (prop_id)
        {
+               case PROP_URL:
+                       priv->url = g_value_dup_string (value);
+                       break;
                case PROP_LOCATION:
                {
                        GFile *f;
@@ -182,6 +198,9 @@ ggit_repository_set_property (GObject      *object,
                case PROP_INIT:
                        priv->init = g_value_get_boolean (value);
                        break;
+               case PROP_CLONE_OPTIONS:
+                       priv->clone_options = g_value_get_boxed (value);
+                       break;
                default:
                        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
                        break;
@@ -198,6 +217,16 @@ ggit_repository_class_init (GgitRepositoryClass *klass)
        object_class->set_property = ggit_repository_set_property;
 
        g_object_class_install_property (object_class,
+                                        PROP_URL,
+                                        g_param_spec_string ("url",
+                                                             "URL for cloning a repository",
+                                                             "The URL for cloning a repository",
+                                                             NULL,
+                                                             G_PARAM_READWRITE |
+                                                             G_PARAM_CONSTRUCT_ONLY |
+                                                             G_PARAM_STATIC_STRINGS));
+
+       g_object_class_install_property (object_class,
                                         PROP_LOCATION,
                                         g_param_spec_object ("location",
                                                              "Location of repository",
@@ -245,6 +274,15 @@ ggit_repository_class_init (GgitRepositoryClass *klass)
                                                              GGIT_TYPE_REF,
                                                              G_PARAM_READABLE));
 
+       g_object_class_install_property (object_class,
+                                        PROP_CLONE_OPTIONS,
+                                        g_param_spec_boxed ("clone-options",
+                                                            "Clone options",
+                                                            "Clone options",
+                                                            GGIT_TYPE_CLONE_OPTIONS,
+                                                            G_PARAM_READWRITE |
+                                                            G_PARAM_CONSTRUCT_ONLY));
+
        g_type_class_add_private (object_class, sizeof (GgitRepositoryPrivate));
 }
 
@@ -289,6 +327,13 @@ ggit_repository_initable_init (GInitable    *initable,
                                           path,
                                           priv->is_bare);
        }
+       else if (priv->url != NULL)
+       {
+               err = git_clone (&repo,
+                                priv->url,
+                                path,
+                                _ggit_clone_options_get_clone_options (priv->clone_options));
+       }
        else
        {
                err = git_repository_open (&repo,
@@ -420,6 +465,34 @@ ggit_repository_init_repository (GFile     *location,
 }
 
 /**
+ * ggit_repository_clone:
+ * @url: url to fetch the repository from.
+ * @location: the location of the repository.
+ * @options: (allow-none): a #GgitCloneOptions.
+ * @error: a #GError for error reporting, or %NULL.
+ *
+ * Clones a new git repository in the given folder.
+ *
+ * Returns: (transfer full): a newly created #GgitRepository.
+ */
+GgitRepository *
+ggit_repository_clone (const gchar       *url,
+                       GFile             *location,
+                       GgitCloneOptions  *options,
+                       GError           **error)
+{
+       g_return_val_if_fail (url != NULL, NULL);
+       g_return_val_if_fail (G_IS_FILE (location), NULL);
+       g_return_val_if_fail (error == NULL || *error == NULL, NULL);
+
+       return g_initable_new (GGIT_TYPE_REPOSITORY, NULL, error,
+                              "url", url,
+                              "location", location,
+                              "clone-options", options,
+                              NULL);
+}
+
+/**
  * ggit_repository_lookup:
  * @repository: a #GgitRepository.
  * @oid: a #GgitOId.
diff --git a/libgit2-glib/ggit-repository.h b/libgit2-glib/ggit-repository.h
index bb9ed79..a7ad460 100644
--- a/libgit2-glib/ggit-repository.h
+++ b/libgit2-glib/ggit-repository.h
@@ -77,6 +77,11 @@ GgitRepository     *ggit_repository_init_repository   (GFile                 *lo
                                                        gboolean               is_bare,
                                                        GError               **error);
 
+GgitRepository     *ggit_repository_clone             (const gchar           *url,
+                                                       GFile                 *location,
+                                                       GgitCloneOptions      *options,
+                                                       GError               **error);
+
 GgitObject         *ggit_repository_lookup            (GgitRepository        *repository,
                                                        GgitOId               *oid,
                                                        GType                  gtype,
diff --git a/libgit2-glib/ggit-types.h b/libgit2-glib/ggit-types.h
index a335771..30b60eb 100644
--- a/libgit2-glib/ggit-types.h
+++ b/libgit2-glib/ggit-types.h
@@ -33,6 +33,13 @@ G_BEGIN_DECLS
 typedef struct _GgitBlob GgitBlob;
 
 /**
+ * GgitCloneOptions:
+ *
+ * Represents the options used when cloning.
+ */
+typedef struct _GgitCloneOptions GgitCloneOptions;
+
+/**
  * GgitCommit:
  *
  * Represents a commit object.


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