Update to libgit2 v0.23

This commit is contained in:
Carlos Martín Nieto 2015-06-08 12:19:01 +02:00
parent 6939b9b203
commit 81520c9c62
15 changed files with 252 additions and 255 deletions

@ -2,7 +2,7 @@
cd ~
git clone --depth=1 -b maint/v0.22 https://github.com/libgit2/libgit2.git
git clone --depth=1 -b maint/v0.23 https://github.com/libgit2/libgit2.git
cd libgit2/
mkdir build && cd build

@ -278,12 +278,12 @@ def clone_repository(
opts.bare = bare
if credentials:
opts.remote_callbacks.credentials = _credentials_cb
opts.remote_callbacks.payload = d_handle
opts.fetch_opts.callbacks.credentials = _credentials_cb
opts.fetch_opts.callbacks.payload = d_handle
if certificate:
opts.remote_callbacks.certificate_check = _certificate_cb
opts.remote_callbacks.payload = d_handle
opts.fetch_opts.callbacks.certificate_check = _certificate_cb
opts.fetch_opts.callbacks.payload = d_handle
err = C.git_clone(crepo, to_bytes(url), to_bytes(path), opts)

@ -101,19 +101,19 @@ class Config(object):
def _get(self, key):
assert_string(key, "key")
cstr = ffi.new('char **')
err = C.git_config_get_string(cstr, self._config, to_bytes(key))
entry = ffi.new('git_config_entry **')
err = C.git_config_get_entry(entry, self._config, to_bytes(key))
return err, cstr
return err, ConfigEntry._from_c(entry[0])
def _get_string(self, key):
err, cstr = self._get(key)
def _get_entry(self, key):
err, entry = self._get(key)
if err == C.GIT_ENOTFOUND:
raise KeyError(key)
check_error(err)
return cstr[0]
return entry
def __contains__(self, key):
err, cstr = self._get(key)
@ -126,9 +126,9 @@ class Config(object):
return True
def __getitem__(self, key):
val = self._get_string(key)
entry = self._get_entry(key)
return ffi.string(val).decode('utf-8')
return ffi.string(entry.value).decode('utf-8')
def __setitem__(self, key, value):
assert_string(key, "key")
@ -192,9 +192,10 @@ class Config(object):
Truthy values are: 'true', 1, 'on' or 'yes'. Falsy values are: 'false',
0, 'off' and 'no'
"""
val = self._get_string(key)
entry = self._get_entry(key)
res = ffi.new('int *')
err = C.git_config_parse_bool(res, val)
err = C.git_config_parse_bool(res, entry.value)
check_error(err)
return res[0] != 0
@ -206,9 +207,10 @@ class Config(object):
A value can have a suffix 'k', 'm' or 'g' which stand for 'kilo',
'mega' and 'giga' respectively.
"""
val = self._get_string(key)
entry = self._get_entry(key)
res = ffi.new('int64_t *')
err = C.git_config_parse_int64(res, val)
err = C.git_config_parse_int64(res, entry.value)
check_error(err)
return res[0]
@ -283,3 +285,20 @@ class Config(object):
"""Return a <Config> object representing the global configuration file.
"""
return Config._from_found_config(C.git_config_find_xdg)
class ConfigEntry(object):
"""An entry in a configuation object
"""
@classmethod
def _from_c(cls, ptr):
entry = cls.__new__(cls)
entry._entry = ptr
return entry
def __del__(self):
C.git_config_entry_free(self._entry)
@property
def value(self):
return self._entry.value

@ -1,6 +1,7 @@
typedef ... git_repository;
typedef ... git_submodule;
typedef ... git_remote;
typedef ... git_transport;
typedef ... git_refspec;
typedef ... git_cred;
typedef ... git_object;
@ -51,7 +52,7 @@ typedef enum {
GIT_EUNMERGED = -10,
GIT_ENONFASTFORWARD = -11,
GIT_EINVALIDSPEC = -12,
GIT_EMERGECONFLICT = -13,
GIT_ECONFLICT = -13,
GIT_ELOCKED = -14,
GIT_PASSTHROUGH = -30,
@ -118,6 +119,7 @@ typedef enum {
} git_credtype_t;
typedef enum git_cert_t {
GIT_CERT_NONE,
GIT_CERT_X509,
GIT_CERT_HOSTKEY_LIBSSH2,
} git_cert_t;
@ -165,6 +167,16 @@ typedef int (*git_push_transfer_progress)(
size_t bytes,
void* payload);
typedef struct {
char *src_refname;
char *dst_refname;
git_oid src;
git_oid dst;
} git_push_update;
typedef int (*git_push_negotiation)(const git_push_update **updates, size_t len, void *payload);
typedef int (*git_transport_cb)(git_transport **out, git_remote *owner, void *param);
struct git_remote_callbacks {
unsigned int version;
git_transport_message_cb sideband_progress;
@ -173,19 +185,51 @@ struct git_remote_callbacks {
git_transport_certificate_check_cb certificate_check;
git_transfer_progress_cb transfer_progress;
int (*update_tips)(const char *refname, const git_oid *a, const git_oid *b, void *data);
git_packbuilder_progress pack_progress;
git_packbuilder_progress pack_progress;
git_push_transfer_progress push_transfer_progress;
int (*push_update_reference)(const char *refname, const char *status, void *data);
git_push_negotiation push_negotiation;
git_transport_cb transport;
void *payload;
};
#define GIT_REMOTE_CALLBACKS_VERSION ...
typedef struct git_remote_callbacks git_remote_callbacks;
typedef struct {
unsigned int version;
unsigned int pb_parallelism;
git_remote_callbacks callbacks;
} git_push_options;
#define GIT_PUSH_OPTIONS_VERSION ...
int git_push_init_options(git_push_options *opts, unsigned int version);
typedef enum {
GIT_FETCH_PRUNE_UNSPECIFIED,
GIT_FETCH_PRUNE,
GIT_FETCH_NO_PRUNE,
} git_fetch_prune_t;
typedef enum {
GIT_REMOTE_DOWNLOAD_TAGS_UNSPECIFIED = 0,
GIT_REMOTE_DOWNLOAD_TAGS_AUTO,
GIT_REMOTE_DOWNLOAD_TAGS_NONE,
GIT_REMOTE_DOWNLOAD_TAGS_ALL,
} git_remote_autotag_option_t;
typedef struct {
int version;
git_remote_callbacks callbacks;
git_fetch_prune_t prune;
int update_fetchhead;
git_remote_autotag_option_t download_tags;
} git_fetch_options;
#define GIT_FETCH_OPTIONS_VERSION ...
int git_fetch_init_options(git_fetch_options *opts, unsigned int version);
int git_remote_list(git_strarray *out, git_repository *repo);
int git_remote_lookup(git_remote **out, git_repository *repo, const char *name);
int git_remote_create(
@ -201,24 +245,20 @@ const char * git_remote_name(const git_remote *remote);
int git_remote_rename(git_strarray *problems, git_repository *repo, const char *name, const char *new_name);
const char * git_remote_url(const git_remote *remote);
int git_remote_set_url(git_remote *remote, const char* url);
int git_remote_set_url(git_repository *repo, const char *remote, const char* url);
const char * git_remote_pushurl(const git_remote *remote);
int git_remote_set_pushurl(git_remote *remote, const char* url);
int git_remote_fetch(git_remote *remote, const git_strarray *refspecs, const git_signature *signature, const char *reflog_message);
int git_remote_push(git_remote *remote, git_strarray *refspecs, const git_push_options *opts, const git_signature *signature, const char *reflog_message);
int git_remote_set_pushurl(git_repository *repo, const char *remote, const char* url);
int git_remote_fetch(git_remote *remote, const git_strarray *refspecs, const git_fetch_options *opts, const char *reflog_message);
int git_remote_push(git_remote *remote, const git_strarray *refspecs, const git_push_options *opts);
const git_transfer_progress * git_remote_stats(git_remote *remote);
int git_remote_add_push(git_remote *remote, const char *refspec);
int git_remote_add_fetch(git_remote *remote, const char *refspec);
int git_remote_save(const git_remote *remote);
int git_remote_set_callbacks(git_remote *remote, const git_remote_callbacks *callbacks);
int git_remote_add_push(git_repository *repo, const char *remote, const char *refspec);
int git_remote_add_fetch(git_repository *repo, const char *remote, const char *refspec);
int git_remote_init_callbacks(git_remote_callbacks *opts, unsigned int version);
size_t git_remote_refspec_count(git_remote *remote);
const git_refspec * git_remote_get_refspec(git_remote *remote, size_t n);
int git_remote_get_fetch_refspecs(git_strarray *array, git_remote *remote);
int git_remote_set_fetch_refspecs(git_remote *remote, git_strarray *array);
int git_remote_get_push_refspecs(git_strarray *array, git_remote *remote);
int git_remote_set_push_refspecs(git_remote *remote, git_strarray *array);
void git_remote_free(git_remote *remote);
@ -253,13 +293,12 @@ int git_cred_ssh_key_from_agent(
*/
typedef enum {
GIT_SUBMODULE_IGNORE_RESET = -1,
GIT_SUBMODULE_IGNORE_UNSPECIFIED = -1,
GIT_SUBMODULE_IGNORE_NONE = 1,
GIT_SUBMODULE_IGNORE_UNTRACKED = 2,
GIT_SUBMODULE_IGNORE_DIRTY = 3,
GIT_SUBMODULE_IGNORE_ALL = 4,
GIT_SUBMODULE_IGNORE_DEFAULT = 0
} git_submodule_ignore_t;
typedef enum {
@ -348,32 +387,37 @@ typedef void (*git_checkout_progress_cb)(
size_t total_steps,
void *payload);
typedef struct {
size_t mkdir_calls;
size_t stat_calls;
size_t chmod_calls;
} git_checkout_perfdata;
typedef void (*git_checkout_perfdata_cb)(
const git_checkout_perfdata *perfdata,
void *payload);
typedef struct git_checkout_options {
unsigned int version;
unsigned int checkout_strategy;
int disable_filters;
unsigned int dir_mode;
unsigned int file_mode;
int file_open_flags;
unsigned int notify_flags;
git_checkout_notify_cb notify_cb;
void *notify_payload;
git_checkout_progress_cb progress_cb;
void *progress_payload;
git_strarray paths;
git_tree *baseline;
git_index *baseline_index;
const char *target_directory;
const char *ancestor_label;
const char *our_label;
const char *their_label;
git_checkout_perfdata_cb perfdata_cb;
void *perfdata_payload;
} git_checkout_options;
int git_checkout_init_options(git_checkout_options *opts, unsigned int version);
@ -408,11 +452,10 @@ typedef enum {
typedef struct git_clone_options {
unsigned int version;
git_checkout_options checkout_opts;
git_remote_callbacks remote_callbacks;
git_fetch_options fetch_opts;
int bare;
git_clone_local_t local;
const char* checkout_branch;
git_signature *signature;
git_repository_create_cb repository_cb;
void *repository_cb_payload;
git_remote_create_cb remote_cb;
@ -443,16 +486,21 @@ typedef enum {
GIT_CONFIG_HIGHEST_LEVEL = -1,
} git_config_level_t;
typedef struct {
typedef struct git_config_entry {
const char *name;
const char *value;
git_config_level_t level;
void (*free)(struct git_config_entry *entry);
void *payload;
} git_config_entry;
void git_config_entry_free(git_config_entry *);
int git_repository_config(git_config **out, git_repository *repo);
int git_repository_config_snapshot(git_config **out, git_repository *repo);
void git_config_free(git_config *cfg);
int git_config_get_entry(git_config_entry **out, const git_config *cfg, const char *name);
int git_config_get_string(const char **out, const git_config *cfg, const char *name);
int git_config_set_string(git_config *cfg, const char *name, const char *value);
int git_config_set_bool(git_config *cfg, const char *name, int value);
@ -535,8 +583,10 @@ int git_repository_init_ext(
const char *repo_path,
git_repository_init_options *opts);
int git_repository_set_head(git_repository *repo, const char *refname, const git_signature *signature, const char *log_message);
int git_repository_set_head_detached(git_repository *repo, const git_oid *commitish, const git_signature *signature, const char *log_message);
int git_repository_set_head(git_repository *repo, const char *refname);
int git_repository_set_head_detached(git_repository *repo, const git_oid *commitish);
int git_repository_ident(const char **name, const char **email, const git_repository *repo);
int git_repository_set_ident(git_repository *repo, const char *name, const char *email);
int git_graph_ahead_behind(size_t *ahead, size_t *behind, git_repository *repo, const git_oid *local, const git_oid *upstream);
/*
@ -557,25 +607,25 @@ const char *git_submodule_branch(git_submodule *subm);
typedef int64_t git_time_t;
typedef struct {
git_time_t seconds;
unsigned int nanoseconds;
int32_t seconds;
uint32_t nanoseconds;
} git_index_time;
typedef struct git_index_entry {
git_index_time ctime;
git_index_time mtime;
unsigned int dev;
unsigned int ino;
unsigned int mode;
unsigned int uid;
unsigned int gid;
git_off_t file_size;
uint32_t dev;
uint32_t ino;
uint32_t mode;
uint32_t uid;
uint32_t gid;
uint32_t file_size;
git_oid id;
unsigned short flags;
unsigned short flags_extended;
uint16_t flags;
uint16_t flags_extended;
const char *path;
} git_index_entry;
@ -664,13 +714,16 @@ typedef enum {
typedef struct {
unsigned int version;
git_merge_tree_flag_t flags;
git_merge_tree_flag_t tree_flags;
unsigned int rename_threshold;
unsigned int target_limit;
git_diff_similarity_metric *metric;
git_merge_file_favor_t file_favor;
unsigned int file_flags;
} git_merge_options;
#define GIT_MERGE_OPTIONS_VERSION 1
typedef struct {
unsigned int automergeable;
const char *path;

@ -153,74 +153,44 @@ class Remote(object):
return maybe_string(C.git_remote_url(self._remote))
@url.setter
def url(self, value):
err = C.git_remote_set_url(self._remote, to_bytes(value))
check_error(err)
@property
def push_url(self):
"""Push url of the remote"""
return maybe_string(C.git_remote_pushurl(self._remote))
@push_url.setter
def push_url(self, value):
err = C.git_remote_set_pushurl(self._remote, to_bytes(value))
check_error(err)
def save(self):
"""Save a remote to its repository's configuration."""
err = C.git_remote_save(self._remote)
check_error(err)
def fetch(self, signature=None, message=None):
def fetch(self, refspecs=None, message=None):
"""Perform a fetch against this remote. Returns a <TransferProgress>
object.
"""
# Get the default callbacks first
defaultcallbacks = ffi.new('git_remote_callbacks *')
err = C.git_remote_init_callbacks(defaultcallbacks, 1)
check_error(err)
fetch_opts = ffi.new('git_fetch_options *')
err = C.git_fetch_init_options(fetch_opts, C.GIT_FETCH_OPTIONS_VERSION)
# Build custom callback structure
callbacks = ffi.new('git_remote_callbacks *')
callbacks.version = 1
callbacks.sideband_progress = self._sideband_progress_cb
callbacks.transfer_progress = self._transfer_progress_cb
callbacks.update_tips = self._update_tips_cb
callbacks.credentials = self._credentials_cb
fetch_opts.callbacks.sideband_progress = self._sideband_progress_cb
fetch_opts.callbacks.transfer_progress = self._transfer_progress_cb
fetch_opts.callbacks.update_tips = self._update_tips_cb
fetch_opts.callbacks.credentials = self._credentials_cb
# We need to make sure that this handle stays alive
self._self_handle = ffi.new_handle(self)
callbacks.payload = self._self_handle
err = C.git_remote_set_callbacks(self._remote, callbacks)
try:
check_error(err)
except:
self._self_handle = None
raise
if signature:
ptr = signature._pointer[:]
else:
ptr = ffi.NULL
fetch_opts.callbacks.payload = self._self_handle
self._stored_exception = None
try:
err = C.git_remote_fetch(self._remote, ffi.NULL, ptr, to_bytes(message))
if self._stored_exception:
raise self._stored_exception
check_error(err)
with StrArray(refspecs) as arr:
err = C.git_remote_fetch(self._remote, arr, fetch_opts, to_bytes(message))
if self._stored_exception:
raise self._stored_exception
check_error(err)
finally:
# Even on error, clear stored callbacks and reset to default
self._self_handle = None
err = C.git_remote_set_callbacks(self._remote, defaultcallbacks)
check_error(err)
return TransferProgress(C.git_remote_stats(self._remote))
@ -245,12 +215,6 @@ class Remote(object):
return strarray_to_strings(specs)
@fetch_refspecs.setter
def fetch_refspecs(self, l):
with StrArray(l) as arr:
err = C.git_remote_set_fetch_refspecs(self._remote, arr)
check_error(err)
@property
def push_refspecs(self):
"""Refspecs that will be used for pushing"""
@ -261,64 +225,28 @@ class Remote(object):
return strarray_to_strings(specs)
@push_refspecs.setter
def push_refspecs(self, l):
with StrArray(l) as arr:
err = C.git_remote_set_push_refspecs(self._remote, arr)
check_error(err)
def add_fetch(self, refspec):
"""Add a fetch refspec (str) to the remote."""
err = C.git_remote_add_fetch(self._remote, to_bytes(refspec))
check_error(err)
def add_push(self, refspec):
"""Add a push refspec (str) to the remote."""
err = C.git_remote_add_push(self._remote, to_bytes(refspec))
check_error(err)
def push(self, specs, signature=None, message=None):
def push(self, specs):
"""Push the given refspec to the remote. Raises ``GitError`` on
protocol error or unpack failure.
:param [str] specs: push refspecs to use
:param Signature signature: signature to use when updating the tips (optional)
:param str message: message to use when updating the tips (optional)
"""
# Get the default callbacks first
defaultcallbacks = ffi.new('git_remote_callbacks *')
err = C.git_remote_init_callbacks(defaultcallbacks, 1)
check_error(err)
if signature:
sig_cptr = ffi.new('git_signature **')
ffi.buffer(sig_cptr)[:] = signature._pointer[:]
sig_ptr = sig_cptr[0]
else:
sig_ptr = ffi.NULL
push_opts = ffi.new('git_push_options *')
err = C.git_push_init_options(push_opts, C.GIT_PUSH_OPTIONS_VERSION)
# Build custom callback structure
callbacks = ffi.new('git_remote_callbacks *')
callbacks.version = 1
callbacks.sideband_progress = self._sideband_progress_cb
callbacks.transfer_progress = self._transfer_progress_cb
callbacks.update_tips = self._update_tips_cb
callbacks.credentials = self._credentials_cb
callbacks.push_update_reference = self._push_update_reference_cb
push_opts.callbacks.sideband_progress = self._sideband_progress_cb
push_opts.callbacks.transfer_progress = self._transfer_progress_cb
push_opts.callbacks.update_tips = self._update_tips_cb
push_opts.callbacks.credentials = self._credentials_cb
push_opts.callbacks.push_update_reference = self._push_update_reference_cb
# We need to make sure that this handle stays alive
self._self_handle = ffi.new_handle(self)
callbacks.payload = self._self_handle
try:
err = C.git_remote_set_callbacks(self._remote, callbacks)
check_error(err)
except:
self._self_handle = None
raise
push_opts.callbacks.payload = self._self_handle
try:
with StrArray(specs) as refspecs:
err = C.git_remote_push(self._remote, refspecs, ffi.NULL, sig_ptr, to_bytes(message))
err = C.git_remote_push(self._remote, refspecs, ffi.NULL)
check_error(err)
finally:
self._self_handle = None
@ -551,3 +479,29 @@ class RemoteCollection(object):
"""
err = C.git_remote_delete(self._repo._repo, to_bytes(name))
check_error(err)
def set_url(self, name, url):
""" Set the URL for a remote
"""
err = C.git_remote_set_url(self._repo._repo, to_bytes(name), to_bytes(url))
check_error(err)
def set_push_url(self, name, url):
"""Set the push-URL for a remote
"""
err = C.git_remote_set_pushurl(self._repo._repo, to_bytes(name), to_bytes(url))
check_error(err)
def add_fetch(self, name, refspec):
"""Add a fetch refspec (str) to the remote
"""
err = C.git_remote_add_fetch(self._repo._repo, to_bytes(name), to_bytes(refspec))
check_error(err)
def add_push(self, name, refspec):
"""Add a push refspec (str) to the remote
"""
err = C.git_remote_add_push(self._repo._repo, to_bytes(name), to_bytes(refspec))
check_error(err)

@ -40,7 +40,7 @@ else:
# Import from pygit2
from _pygit2 import Repository as _Repository
from _pygit2 import Oid, GIT_OID_HEXSZ, GIT_OID_MINPREFIXLEN
from _pygit2 import GIT_CHECKOUT_SAFE_CREATE, GIT_DIFF_NORMAL
from _pygit2 import GIT_CHECKOUT_SAFE, GIT_CHECKOUT_RECREATE_MISSING, GIT_DIFF_NORMAL
from _pygit2 import GIT_FILEMODE_LINK
from _pygit2 import Reference, Tree, Commit, Blob
@ -190,8 +190,8 @@ class Repository(_Repository):
# References we need to keep to strings and so forth
refs = []
# pygit2's default is SAFE_CREATE
copts.checkout_strategy = GIT_CHECKOUT_SAFE_CREATE
# pygit2's default is SAFE | RECREATE_MISSING
copts.checkout_strategy = GIT_CHECKOUT_SAFE | GIT_CHECKOUT_RECREATE_MISSING
# and go through the arguments to see what the user wanted
if strategy:
copts.checkout_strategy = strategy
@ -235,7 +235,7 @@ class Repository(_Repository):
Checkout the given reference using the given strategy, and update
the HEAD.
The reference may be a reference name or a Reference object.
The default strategy is GIT_CHECKOUT_SAFE_CREATE.
The default strategy is GIT_CHECKOUT_SAFE | GIT_CHECKOUT_RECREATE_MISSING.
To checkout from the HEAD, just pass 'HEAD'::
@ -251,7 +251,7 @@ class Repository(_Repository):
the current branch will be switched to this one.
:param int strategy: A ``GIT_CHECKOUT_`` value. The default is
``GIT_CHECKOUT_SAFE_CREATE``.
``GIT_CHECKOUT_SAFE``.
:param str directory: Alternative checkout path to workdir.
@ -281,50 +281,29 @@ class Repository(_Repository):
else:
from_ = head.target.hex
try:
signature = self.default_signature
except Exception:
signature = None
reflog_text = "checkout: moving from %s to %s" % (from_, reference)
self.set_head(refname, signature, reflog_text)
self.set_head(refname)
#
# Setting HEAD
#
def set_head(self, target, signature=None, message=None):
def set_head(self, target):
"""Set HEAD to point to the given target
Arguments:
target
The new target for HEAD. Can be a string or Oid (to detach)
signature
Signature to use for the reflog. If not provided, the repository's
default will be used
message
Message to use for the reflog
"""
sig_ptr = ffi.new('git_signature **')
if signature:
ffi.buffer(sig_ptr)[:] = signature._pointer[:]
message_ptr = ffi.NULL
if message_ptr:
message_ptr = to_bytes(message)
if isinstance(target, Oid):
oid = ffi.new('git_oid *')
ffi.buffer(oid)[:] = target.raw[:]
err = C.git_repository_set_head_detached(self._repo, oid, sig_ptr[0], message_ptr)
err = C.git_repository_set_head_detached(self._repo, oid)
check_error(err)
return
# if it's a string, then it's a reference name
err = C.git_repository_set_head(self._repo, to_bytes(target), sig_ptr[0], message_ptr)
err = C.git_repository_set_head(self._repo, to_bytes(target))
check_error(err)
#
@ -802,3 +781,27 @@ class Repository(_Repository):
return ffi.string(cvalue[0]).decode('utf-8')
assert False, "the attribute value from libgit2 is invalid"
#
# Identity for reference operations
#
@property
def ident(self):
cname = ffi.new('char **')
cemail = ffi.new('char **')
err = C.git_repository_ident(cname, cemail, self._repo)
check_error(err)
return (ffi.string(cname).decode('utf-8'), ffi.string(cemail).decode('utf-8'))
def set_ident(self, name, email):
"""Set the identity to be used for reference operations
Updates to some references also append data to their
reflog. You can use this method to set what identity will be
used. If none is set, it will be read from the configuration.
"""
err = C.git_repository_set_ident(self._repo, to_bytes(name), to_bytes(email))
check_error(err)

@ -61,6 +61,11 @@ class StrArray(object):
"""
def __init__(self, l):
# Allow passing in None as lg2 typically considers them the same as empty
if l is None:
self.array = ffi.NULL
return
if not isinstance(l, list):
raise TypeError("Value must be a list")

@ -101,7 +101,7 @@ Branch_rename(Branch *self, PyObject *args)
if (!PyArg_ParseTuple(args, "s|i", &c_name, &force))
return NULL;
err = git_branch_move(&c_out, self->reference, c_name, force, NULL, NULL);
err = git_branch_move(&c_out, self->reference, c_name, force);
if (err == GIT_OK)
return wrap_branch(c_out, self->repo);
else

@ -273,10 +273,11 @@ moduleinit(PyObject* m)
ADD_CONSTANT_INT(m, GIT_STATUS_WT_MODIFIED)
ADD_CONSTANT_INT(m, GIT_STATUS_WT_DELETED)
ADD_CONSTANT_INT(m, GIT_STATUS_IGNORED) /* Flags for ignored files */
ADD_CONSTANT_INT(m, GIT_STATUS_CONFLICTED)
/* Different checkout strategies */
ADD_CONSTANT_INT(m, GIT_CHECKOUT_NONE)
ADD_CONSTANT_INT(m, GIT_CHECKOUT_SAFE)
ADD_CONSTANT_INT(m, GIT_CHECKOUT_SAFE_CREATE)
ADD_CONSTANT_INT(m, GIT_CHECKOUT_RECREATE_MISSING)
ADD_CONSTANT_INT(m, GIT_CHECKOUT_FORCE)
ADD_CONSTANT_INT(m, GIT_CHECKOUT_ALLOW_CONFLICTS)
ADD_CONSTANT_INT(m, GIT_CHECKOUT_REMOVE_UNTRACKED)

@ -163,7 +163,7 @@ Reference_rename(Reference *self, PyObject *py_name)
return NULL;
/* Rename */
err = git_reference_rename(&new_reference, self->reference, c_name, 0, NULL, NULL);
err = git_reference_rename(&new_reference, self->reference, c_name, 0, NULL);
git_reference_free(self->reference);
free(c_name);
if (err < 0)
@ -228,7 +228,7 @@ Reference_target__get__(Reference *self)
}
PyDoc_STRVAR(Reference_set_target__doc__,
"set_target(target, [signature, message])\n"
"set_target(target, [message])\n"
"\n"
"Set the target of this reference.\n"
"\n"
@ -240,9 +240,6 @@ PyDoc_STRVAR(Reference_set_target__doc__,
"\n"
"target\n"
" The new target for this reference\n"
"signature\n"
" The signature to use for the reflog. If left out, the repository's\n"
" default identity will be used.\n"
"message\n"
" Message to use for the reflog.\n");
@ -253,28 +250,23 @@ Reference_set_target(Reference *self, PyObject *args, PyObject *kwds)
char *c_name;
int err;
git_reference *new_ref;
const git_signature *sig = NULL;
PyObject *py_target = NULL;
Signature *py_signature = NULL;
const char *message = NULL;
char *keywords[] = {"target", "signature", "message", NULL};
char *keywords[] = {"target", "message", NULL};
CHECK_REFERENCE(self);
if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O!s", keywords,
&py_target, &SignatureType, &py_signature, &message))
if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|s", keywords,
&py_target, &message))
return NULL;
if (py_signature)
sig = py_signature->signature;
/* Case 1: Direct */
if (GIT_REF_OID == git_reference_type(self->reference)) {
err = py_oid_to_git_oid_expand(self->repo->repo, py_target, &oid);
if (err < 0)
goto error;
err = git_reference_set_target(&new_ref, self->reference, &oid, sig, message);
err = git_reference_set_target(&new_ref, self->reference, &oid, message);
if (err < 0)
goto error;
@ -288,7 +280,7 @@ Reference_set_target(Reference *self, PyObject *args, PyObject *kwds)
if (c_name == NULL)
return NULL;
err = git_reference_symbolic_set_target(&new_ref, self->reference, c_name, sig, message);
err = git_reference_symbolic_set_target(&new_ref, self->reference, c_name, message);
free(c_name);
if (err < 0)
goto error;

@ -637,7 +637,7 @@ Repository_merge(Repository *self, PyObject *py_oid)
if (err < 0)
return Error_set(err);
checkout_opts.checkout_strategy = GIT_CHECKOUT_SAFE_CREATE;
checkout_opts.checkout_strategy = GIT_CHECKOUT_SAFE | GIT_CHECKOUT_RECREATE_MISSING;
err = git_merge(self->repo,
(const git_annotated_commit **)&commit, 1,
&merge_opts, &checkout_opts);
@ -677,7 +677,7 @@ Repository_cherrypick(Repository *self, PyObject *py_oid)
if (err < 0)
return Error_set(err);
cherrypick_opts.checkout_opts.checkout_strategy = GIT_CHECKOUT_SAFE_CREATE;
cherrypick_opts.checkout_opts.checkout_strategy = GIT_CHECKOUT_SAFE;
err = git_cherrypick(self->repo,
commit,
(const git_cherrypick_options *)&cherrypick_opts);
@ -989,7 +989,7 @@ Repository_create_branch(Repository *self, PyObject *args)
if (!PyArg_ParseTuple(args, "sO!|i", &c_name, &CommitType, &py_commit, &force))
return NULL;
err = git_branch_create(&c_reference, self->repo, c_name, py_commit->commit, force, NULL, NULL);
err = git_branch_create(&c_reference, self->repo, c_name, py_commit->commit, force);
if (err < 0)
return Error_set(err);
@ -1194,7 +1194,7 @@ Repository_create_reference_direct(Repository *self, PyObject *args,
if (err < 0)
return NULL;
err = git_reference_create(&c_reference, self->repo, c_name, &oid, force, NULL, NULL);
err = git_reference_create(&c_reference, self->repo, c_name, &oid, force, NULL);
if (err < 0)
return Error_set(err);
@ -1228,7 +1228,7 @@ Repository_create_reference_symbolic(Repository *self, PyObject *args,
return NULL;
err = git_reference_symbolic_create(&c_reference, self->repo, c_name,
c_target, force, NULL, NULL);
c_target, force, NULL);
if (err < 0)
return Error_set(err);
@ -1513,7 +1513,7 @@ Repository_reset(Repository *self, PyObject* args)
err = git_object_lookup_prefix(&target, self->repo, &oid, len,
GIT_OBJ_ANY);
err = err < 0 ? err : git_reset(self->repo, target, reset_type, NULL, NULL, NULL);
err = err < 0 ? err : git_reset(self->repo, target, reset_type, NULL);
git_object_free(target);
if (err < 0)
return Error_set_oid(err, &oid, len);

@ -32,8 +32,8 @@
#include <Python.h>
#include <git2.h>
#if !(LIBGIT2_VER_MAJOR == 0 && LIBGIT2_VER_MINOR == 22)
#error You need a compatible libgit2 version (v0.22.x)
#if !(LIBGIT2_VER_MAJOR == 0 && LIBGIT2_VER_MINOR == 23)
#error You need a compatible libgit2 version (v0.23.x)
#endif
/*

@ -82,7 +82,7 @@ class MergeTestBasic(utils.RepoTestCaseForMerging):
self.repo.merge(branch_id)
self.assertTrue(self.repo.index.conflicts is not None)
status = pygit2.GIT_STATUS_WT_NEW | pygit2.GIT_STATUS_INDEX_DELETED
status = pygit2.GIT_STATUS_CONFLICTED
# Asking twice to assure the reference counting is correct
self.assertEqual({'.gitignore': status}, self.repo.status())
self.assertEqual({'.gitignore': status}, self.repo.status())

@ -114,8 +114,9 @@ class ReferencesTest(utils.RepoTestCase):
reference = self.repo.lookup_reference('HEAD')
self.assertEqual(reference.target, 'refs/heads/master')
sig = Signature('foo', 'bar')
self.repo.set_ident('foo', 'bar')
msg = 'Hello log'
reference.set_target('refs/heads/i18n', signature=sig, message=msg)
reference.set_target('refs/heads/i18n', message=msg)
self.assertEqual(reference.target, 'refs/heads/i18n')
self.assertEqual(list(reference.log())[0].message, msg)
self.assertEqualSignature(list(reference.log())[0].committer, sig)

@ -100,22 +100,23 @@ class RepositoryTest(utils.RepoTestCase):
def test_remote_set_url(self):
remote = self.repo.remotes[0]
remote = self.repo.remotes["origin"]
self.assertEqual(REMOTE_URL, remote.url)
new_url = 'git://github.com/cholin/pygit2.git'
remote.url = new_url
self.repo.remotes.set_url("origin", new_url)
remote = self.repo.remotes["origin"]
self.assertEqual(new_url, remote.url)
self.assertRaisesAssign(ValueError, remote, 'url', '')
self.assertRaises(ValueError, self.repo.remotes.set_url, "origin", "")
remote.push_url = new_url
self.repo.remotes.set_push_url("origin", new_url)
remote = self.repo.remotes["origin"]
self.assertEqual(new_url, remote.push_url)
self.assertRaisesAssign(ValueError, remote, 'push_url', '')
self.assertRaises(ValueError, self.repo.remotes.set_push_url, "origin", "")
def test_refspec(self):
remote = self.repo.remotes[0]
remote = self.repo.remotes["origin"]
self.assertEqual(remote.refspec_count, 1)
refspec = remote.get_refspec(0)
@ -140,34 +141,20 @@ class RepositoryTest(utils.RepoTestCase):
self.assertEqual(list, type(push_specs))
self.assertEqual(0, len(push_specs))
remote.fetch_refspecs = ['+refs/*:refs/remotes/*']
self.assertEqual('+refs/*:refs/remotes/*', remote.fetch_refspecs[0])
self.repo.remotes.add_fetch("origin", '+refs/test/*:refs/test/remotes/*')
remote = self.repo.remotes["origin"]
fetch_specs = remote.fetch_refspecs
self.assertEqual(list, type(fetch_specs))
self.assertEqual(1, len(fetch_specs))
self.assertEqual('+refs/*:refs/remotes/*', fetch_specs[0])
self.assertEqual(2, len(fetch_specs))
self.assertEqual(['+refs/heads/*:refs/remotes/origin/*', '+refs/test/*:refs/test/remotes/*'], fetch_specs)
remote.fetch_refspecs = ['+refs/*:refs/remotes/*',
'+refs/test/*:refs/test/remotes/*']
self.assertEqual('+refs/*:refs/remotes/*', remote.fetch_refspecs[0])
self.assertEqual('+refs/test/*:refs/test/remotes/*',
remote.fetch_refspecs[1])
self.repo.remotes.add_push("origin", '+refs/test/*:refs/test/remotes/*')
remote.push_refspecs = ['+refs/*:refs/remotes/*',
'+refs/test/*:refs/test/remotes/*']
self.assertRaises(TypeError, setattr, remote, 'push_refspecs',
'+refs/*:refs/*')
self.assertRaises(TypeError, setattr, remote, 'fetch_refspecs',
'+refs/*:refs/*')
self.assertRaises(TypeError, setattr, remote, 'fetch_refspecs',
['+refs/*:refs/*', 5])
self.assertEqual('+refs/*:refs/remotes/*', remote.push_refspecs[0])
self.assertEqual('+refs/test/*:refs/test/remotes/*',
remote.push_refspecs[1])
self.assertRaises(TypeError, self.repo.remotes.add_fetch, ['+refs/*:refs/*', 5])
remote = self.repo.remotes["origin"]
self.assertEqual(['+refs/test/*:refs/test/remotes/*'], remote.push_refspecs)
def test_remote_list(self):
self.assertEqual(1, len(self.repo.remotes))
@ -193,15 +180,6 @@ class RepositoryTest(utils.RepoTestCase):
remote = self.repo.remotes.create(name, url)
self.assertTrue(remote.name in [x.name for x in self.repo.remotes])
def test_remote_save(self):
remote = self.repo.remotes[0]
remote.url = 'http://example.com/test.git'
remote.save()
self.assertEqual('http://example.com/test.git',
self.repo.remotes[0].url)
@unittest.skipIf(__pypy__ is not None, "skip refcounts checks in pypy")
def test_remote_refcount(self):
start = sys.getrefcount(self.repo)
@ -210,15 +188,6 @@ class RepositoryTest(utils.RepoTestCase):
end = sys.getrefcount(self.repo)
self.assertEqual(start, end)
def test_add_refspec(self):
remote = self.repo.create_remote('test_add_refspec', REMOTE_URL)
remote.add_push('refs/heads/*:refs/heads/test_refspec/*')
self.assertEqual('refs/heads/*:refs/heads/test_refspec/*',
remote.push_refspecs[0])
remote.add_fetch('+refs/heads/*:refs/remotes/test_refspec/*')
self.assertEqual('+refs/heads/*:refs/remotes/test_refspec/*',
remote.fetch_refspecs[1])
def test_remote_callback_typecheck(self):
remote = self.repo.remotes[0]
remote.progress = 5