From 95e6593625f2a870c8729bc65537b19f0b5df8aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=2E=20David=20Ib=C3=A1=C3=B1ez?= Date: Tue, 3 Jun 2014 12:52:46 +0200 Subject: [PATCH] init_repository now wraps git_repository_init_ext Fixes #347 --- pygit2/__init__.py | 46 +++++++++++++++++- pygit2/decl.h | 113 ++++++++++++++++++++++++++++++++++++--------- pygit2/ffi.py | 9 ++-- 3 files changed, 139 insertions(+), 29 deletions(-) diff --git a/pygit2/__init__.py b/pygit2/__init__.py index a067a3b..eed50c8 100644 --- a/pygit2/__init__.py +++ b/pygit2/__init__.py @@ -41,17 +41,59 @@ from .config import Config from .errors import check_error from .ffi import ffi, C, to_str -def init_repository(path, bare=False): +def init_repository(path, bare=False, + flags=C.GIT_REPOSITORY_INIT_MKPATH, + mode=0, + workdir_path=None, + description=None, + template_path=None, + initial_head=None, + origin_url=None): """ Creates a new Git repository in the given *path*. If *bare* is True the repository will be bare, i.e. it will not have a working copy. + + The *flags* may be a combination of: + + - GIT_REPOSITORY_INIT_BARE (overriden by the *bare* parameter) + - GIT_REPOSITORY_INIT_NO_REINIT + - GIT_REPOSITORY_INIT_NO_DOTGIT_DIR + - GIT_REPOSITORY_INIT_MKDIR + - GIT_REPOSITORY_INIT_MKPATH (set by default) + - GIT_REPOSITORY_INIT_EXTERNAL_TEMPLATE + + The *mode* parameter may be any of GIT_REPOSITORY_SHARED_UMASK (default), + GIT_REPOSITORY_SHARED_GROUP or GIT_REPOSITORY_INIT_SHARED_ALL, or a custom + value. + + The *workdir_path*, *description*, *template_path*, *initial_head* and + *origin_url* are all strings. + + See libgit2's documentation on git_repository_init_ext for further details. """ + # Pre-process input parameters + if bare: + flags |= C.GIT_REPOSITORY_INIT_BARE + + # Options + options = ffi.new('git_repository_init_options *') + options.version = 1 + options.flags = flags + options.mode = mode + options.workdir_path = to_str(workdir_path) + options.description = to_str(description) + options.template_path = to_str(template_path) + options.initial_head = to_str(initial_head) + options.origin_url = to_str(origin_url) + + # Call crepository = ffi.new('git_repository **') - err = C.git_repository_init(crepository, to_str(path), bare) + err = C.git_repository_init_ext(crepository, to_str(path), options) check_error(err) + # Ok return Repository(path) diff --git a/pygit2/decl.h b/pygit2/decl.h index 1fb28e7..fd1c22e 100644 --- a/pygit2/decl.h +++ b/pygit2/decl.h @@ -5,8 +5,6 @@ typedef ... git_push; typedef ... git_cred; typedef ... git_diff_file; typedef ... git_tree; -typedef ... git_config; -typedef ... git_config_iterator; #define GIT_OID_RAWSZ ... #define GIT_PATH_MAX ... @@ -20,6 +18,7 @@ typedef struct git_strarray { size_t count; } git_strarray; + typedef enum { GIT_OK = 0, GIT_ERROR = -1, @@ -71,11 +70,13 @@ typedef enum { GIT_DIRECTION_PUSH = 1 } git_direction; + typedef enum { - GIT_CREDTYPE_USERPASS_PLAINTEXT = ..., - GIT_CREDTYPE_SSH_KEY = ..., - GIT_CREDTYPE_SSH_CUSTOM = ..., - GIT_CREDTYPE_DEFAULT = ..., + GIT_CREDTYPE_USERPASS_PLAINTEXT, + GIT_CREDTYPE_SSH_KEY, + GIT_CREDTYPE_SSH_CUSTOM, + GIT_CREDTYPE_DEFAULT, + ... } git_credtype_t; typedef struct git_remote_callbacks { @@ -90,10 +91,12 @@ typedef struct git_remote_callbacks { int git_remote_list(git_strarray *out, git_repository *repo); int git_remote_load(git_remote **out, git_repository *repo, const char *name); -int git_remote_create(git_remote **out, - git_repository *repo, - const char *name, - const char *url); +int git_remote_create( + git_remote **out, + git_repository *repo, + const char *name, + const char *url); + const char * git_remote_name(const git_remote *remote); typedef int (*git_remote_rename_problem_cb)(const char *problematic_refspec, void *payload); int git_remote_rename(git_remote *remote, @@ -125,9 +128,10 @@ int git_push_add_refspec(git_push *push, const char *refspec); int git_push_finish(git_push *push); int git_push_unpack_ok(git_push *push); -int git_push_status_foreach(git_push *push, - int (*cb)(const char *ref, const char *msg, void *data), - void *data); +int git_push_status_foreach( + git_push *push, + int (*cb)(const char *ref, const char *msg, void *data), + void *data); int git_push_update_tips(git_push *push); void git_push_free(git_push *push); @@ -155,6 +159,10 @@ int git_cred_ssh_key_new( const char *privatekey, const char *passphrase); +/* + * git_checkout + */ + typedef enum { ... } git_checkout_notify_t; typedef int (*git_checkout_notify_cb)( @@ -199,6 +207,10 @@ typedef struct git_checkout_opts { } git_checkout_opts; +/* + * git_clone + */ + typedef struct git_clone_options { unsigned int version; @@ -212,11 +224,22 @@ typedef struct git_clone_options { } git_clone_options; int git_clone(git_repository **out, - const char *url, - const char *local_path, - const git_clone_options *options); + const char *url, + const char *local_path, + const git_clone_options *options); -int git_clone_into(git_repository *repo, git_remote *remote, const git_checkout_opts *co_opts, const char *branch); +int git_clone_into( + git_repository *repo, + git_remote *remote, + const git_checkout_opts *co_opts, + const char *branch); + +/* + * git_config + */ + +typedef ... git_config; +typedef ... git_config_iterator; typedef enum { GIT_CONFIG_LEVEL_SYSTEM = 1, @@ -254,11 +277,17 @@ int git_config_iterator_new(git_config_iterator **out, const git_config *cfg); int git_config_next(git_config_entry **entry, git_config_iterator *iter); void git_config_iterator_free(git_config_iterator *iter); -int git_config_multivar_iterator_new(git_config_iterator **out, - const git_config *cfg, const char *name, - const char *regexp); +int git_config_multivar_iterator_new( + git_config_iterator **out, + const git_config *cfg, + const char *name, + const char *regexp); -int git_config_set_multivar(git_config *cfg, const char *name, const char *regexp, const char *value); +int git_config_set_multivar( + git_config *cfg, + const char *name, + const char *regexp, + const char *value); int git_config_new(git_config **out); int git_config_open_ondisk(git_config **out, const char *path); @@ -267,5 +296,43 @@ int git_config_find_global(char *out, size_t length); int git_config_find_xdg(char *out, size_t length); -int git_repository_init(git_repository **out, const char *path, - unsigned is_bare); +/* + * git_repository_init + */ +typedef enum { + GIT_REPOSITORY_INIT_BARE, + GIT_REPOSITORY_INIT_NO_REINIT, + GIT_REPOSITORY_INIT_NO_DOTGIT_DIR, + GIT_REPOSITORY_INIT_MKDIR, + GIT_REPOSITORY_INIT_MKPATH, + GIT_REPOSITORY_INIT_EXTERNAL_TEMPLATE, + ... +} git_repository_init_flag_t; + +typedef enum { + GIT_REPOSITORY_INIT_SHARED_UMASK, + GIT_REPOSITORY_INIT_SHARED_GROUP, + GIT_REPOSITORY_INIT_SHARED_ALL, + ... +} git_repository_init_mode_t; + +typedef struct { + unsigned int version; + uint32_t flags; + uint32_t mode; + const char *workdir_path; + const char *description; + const char *template_path; + const char *initial_head; + const char *origin_url; +} git_repository_init_options; + +int git_repository_init( + git_repository **out, + const char *path, + unsigned is_bare); + +int git_repository_init_ext( + git_repository **out, + const char *repo_path, + git_repository_init_options *opts); diff --git a/pygit2/ffi.py b/pygit2/ffi.py index 468b9bc..0dba2f3 100644 --- a/pygit2/ffi.py +++ b/pygit2/ffi.py @@ -38,7 +38,7 @@ import sys if major_version < 3: def to_str(s, encoding='utf-8', errors='strict'): - if s == ffi.NULL or s == None: + if s == ffi.NULL or s is None: return ffi.NULL if isinstance(s, unicode): @@ -48,7 +48,7 @@ if major_version < 3: return s else: def to_str(s, encoding='utf-8', errors='strict'): - if s == ffi.NULL or s == None: + if s == ffi.NULL or s is None: return ffi.NULL if isinstance(s, bytes): @@ -108,7 +108,7 @@ dir_path = path.dirname(path.abspath(inspect.getfile(inspect.currentframe()))) decl_path = path.join(dir_path, 'decl.h') with codecs.open(decl_path, 'r', 'utf-8') as header: - ffi.cdef(header.read()) + ffi.cdef(header.read()) # if LIBGIT2 exists, set build and link against that version libgit2_path = getenv('LIBGIT2') @@ -118,4 +118,5 @@ if libgit2_path: include_dirs = [path.join(libgit2_path, 'include')] library_dirs = [path.join(libgit2_path, 'lib')] -C = ffi.verify("#include ", libraries=["git2"], include_dirs=include_dirs, library_dirs=library_dirs) +C = ffi.verify("#include ", libraries=["git2"], + include_dirs=include_dirs, library_dirs=library_dirs)