Skip to content

Commit

Permalink
filter: add API for registering Python filters
Browse files Browse the repository at this point in the history
  • Loading branch information
pmrowla committed Oct 3, 2023
1 parent 5dda191 commit 4b5a6c6
Show file tree
Hide file tree
Showing 7 changed files with 689 additions and 1 deletion.
13 changes: 13 additions & 0 deletions pygit2/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
from .credentials import *
from .errors import check_error, Passthrough
from .ffi import ffi, C
from .filter import Filter, FilterSource, filter_register, filter_unregister
from .index import Index, IndexEntry
from .remote import Remote
from .repository import Repository
Expand Down Expand Up @@ -117,6 +118,18 @@
GIT_STASH_APPLY_PROGRESS_CHECKOUT_MODIFIED : int = C.GIT_STASH_APPLY_PROGRESS_CHECKOUT_MODIFIED
GIT_STASH_APPLY_PROGRESS_DONE : int = C.GIT_STASH_APPLY_PROGRESS_DONE

# GIT_FILTER
GIT_FILTER_TO_WORKTREE : int = C.GIT_FILTER_TO_WORKTREE
GIT_FILTER_SMUDGE : int = C.GIT_FILTER_SMUDGE
GIT_FILTER_TO_ODB : int = C.GIT_FILTER_TO_ODB
GIT_FILTER_CLEAN : int = C.GIT_FILTER_CLEAN
GIT_FILTER_DRIVER_PRIORITY : int = C.GIT_FILTER_DRIVER_PRIORITY
GIT_FILTER_DEFAULT : int = C.GIT_FILTER_DEFAULT
GIT_FILTER_ALLOW_UNSAFE : int = C.GIT_FILTER_ALLOW_UNSAFE
GIT_FILTER_NO_SYSTEM_ATTRIBUTES : int = C.GIT_FILTER_NO_SYSTEM_ATTRIBUTES
GIT_FILTER_ATTRIBUTES_FROM_HEAD : int = C.GIT_FILTER_ATTRIBUTES_FROM_HEAD
GIT_FILTER_ATTRIBUTES_FROM_COMMIT : int = C.GIT_FILTER_ATTRIBUTES_FROM_COMMIT

# libgit version tuple
LIBGIT2_VER = (LIBGIT2_VER_MAJOR, LIBGIT2_VER_MINOR, LIBGIT2_VER_REVISION)

Expand Down
3 changes: 2 additions & 1 deletion pygit2/_run.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@
'revert.h',
'stash.h',
'submodule.h',
'filter.h',
'callbacks.h', # Bridge from libgit2 to Python
]
h_source = []
Expand All @@ -96,7 +97,7 @@
ffi = FFI()
ffi.set_source(
"pygit2._libgit2",
"#include <git2.h>", # preamble
"#include <git2.h>\n#include <git2/sys/filter.h>", # preamble
**libgit2_kw
)
ffi.cdef(C_HEADER_SRC)
Expand Down
28 changes: 28 additions & 0 deletions pygit2/decl/callbacks.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,3 +65,31 @@ extern "Python" void _checkout_progress_cb(
extern "Python" int _stash_apply_progress_cb(
git_stash_apply_progress_t progress,
void *payload);

extern "Python" void _filter_shutdown_cb(git_filter *self);

extern "Python" int _filter_check_cb(
git_filter *self,
void **payload,
const git_filter_source *src,
const char **attr_values);

extern "Python" int _filter_stream_cb(
git_writestream **out,
git_filter *self,
void **payload,
const git_filter_source *src,
git_writestream *next);

extern "Python" void _filter_cleanup_cb(
git_filter *self,
void *payload);

extern "Python" int _writestream_write_cb(
git_writestream *stream,
const char *buffer,
size_t len);

extern "Python" int _writestream_close_cb(git_writestream *stream);

extern "Python" void _writestream_free_cb(git_writestream *stream);
67 changes: 67 additions & 0 deletions pygit2/decl/filter.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
typedef enum {
GIT_FILTER_TO_WORKTREE = 0,
GIT_FILTER_SMUDGE = GIT_FILTER_TO_WORKTREE,
GIT_FILTER_TO_ODB = 1,
GIT_FILTER_CLEAN = GIT_FILTER_TO_ODB
} git_filter_mode_t;

typedef enum {
GIT_FILTER_DEFAULT = 0u,
GIT_FILTER_ALLOW_UNSAFE = (1u << 0),
GIT_FILTER_NO_SYSTEM_ATTRIBUTES = (1u << 1),
GIT_FILTER_ATTRIBUTES_FROM_HEAD = (1u << 2),
GIT_FILTER_ATTRIBUTES_FROM_COMMIT = (1u << 3)
} git_filter_flag_t;



#define GIT_FILTER_VERSION ...

#define GIT_FILTER_DRIVER_PRIORITY 200

typedef struct git_filter_source git_filter_source;
typedef struct git_filter git_filter;

typedef int (*git_filter_init_fn)(git_filter *self);
typedef void (*git_filter_shutdown_fn)(git_filter *self);
typedef int (*git_filter_check_fn)(
git_filter *self,
void **payload, /* NULL on entry, may be set */
const git_filter_source *src,
const char **attr_values);
typedef int (*git_filter_apply_fn)(
git_filter *self,
void **payload, /* may be read and/or set */
git_buf *to,
const git_buf *from,
const git_filter_source *src);
typedef int (*git_filter_stream_fn)(
git_writestream **out,
git_filter *self,
void **payload,
const git_filter_source *src,
git_writestream *next);
typedef void (*git_filter_cleanup_fn)(
git_filter *self,
void *payload);

struct git_filter {
unsigned int version;
const char *attributes;
git_filter_init_fn initialize;
git_filter_shutdown_fn shutdown;
git_filter_check_fn check;
git_filter_apply_fn apply; /* deprecated in favor of stream */
git_filter_stream_fn stream;
git_filter_cleanup_fn cleanup;
};

int git_filter_init(git_filter *filter, unsigned int version);
int git_filter_register(
const char *name, git_filter *filter, int priority);
int git_filter_unregister(const char *name);
const char *git_filter_source_path(const git_filter_source *src);
uint16_t git_filter_source_filemode(const git_filter_source *src);
const git_oid *git_filter_source_id(const git_filter_source *src);
git_filter_mode_t git_filter_source_mode(const git_filter_source *src);
uint32_t git_filter_source_flags(const git_filter_source *src);
7 changes: 7 additions & 0 deletions pygit2/decl/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,13 @@ typedef struct git_submodule git_submodule;
typedef struct git_transport git_transport;
typedef struct git_tree git_tree;
typedef struct git_packbuilder git_packbuilder;
typedef struct git_writestream git_writestream;

struct git_writestream {
int (*write)(git_writestream *stream, const char *buffer, size_t len);
int (*close)(git_writestream *stream);
void (*free)(git_writestream *stream);
};

typedef int64_t git_off_t;
typedef int64_t git_time_t;
Expand Down
Loading

0 comments on commit 4b5a6c6

Please sign in to comment.