/* * Copyright 2010-2026 The pygit2 contributors * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2, * as published by the Free Software Foundation. * * In addition to the permissions in the GNU General Public License, * the authors give you unlimited permission to link the compiled * version of this file into combinations with other programs, * and to distribute those combinations without any restriction * coming from the use of this file. (The General Public License * restrictions do apply in other respects; for example, they cover * modification of the file, and distribution when not linked into * a combined executable.) * * 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 * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #define PY_SSIZE_T_CLEAN #include #include #include #include "error.h" #include "types.h" #include "utils.h" #include "repository.h" #include "oid.h" #include "filter.h" PyObject *GitError; PyObject *AlreadyExistsError; PyObject *InvalidSpecError; PyObject *InvalidError; PyObject *NotFoundError; PyObject *AmbiguousError; PyObject *AuthError; PyObject *CertificateError; PyObject *DeltaStatusEnum; PyObject *DiffFlagEnum; PyObject *FileModeEnum; PyObject *FileStatusEnum; PyObject *MergeAnalysisEnum; PyObject *MergePreferenceEnum; PyObject *ObjectTypeEnum; PyObject *ReferenceTypeEnum; extern PyTypeObject RepositoryType; extern PyTypeObject OdbType; extern PyTypeObject OdbBackendType; extern PyTypeObject OdbBackendPackType; extern PyTypeObject OdbBackendLooseType; extern PyTypeObject OidType; extern PyTypeObject ObjectType; extern PyTypeObject CommitType; extern PyTypeObject DiffType; extern PyTypeObject DeltasIterType; extern PyTypeObject DiffIterType; extern PyTypeObject DiffDeltaType; extern PyTypeObject DiffFileType; extern PyTypeObject DiffHunkType; extern PyTypeObject DiffLineType; extern PyTypeObject DiffStatsType; extern PyTypeObject PatchType; extern PyTypeObject TreeType; extern PyTypeObject TreeBuilderType; extern PyTypeObject TreeIterType; extern PyTypeObject BlobType; extern PyTypeObject TagType; extern PyTypeObject WalkerType; extern PyTypeObject RefdbType; extern PyTypeObject RefdbBackendType; extern PyTypeObject RefdbFsBackendType; extern PyTypeObject ReferenceType; extern PyTypeObject RevSpecType; extern PyTypeObject RefLogIterType; extern PyTypeObject RefLogEntryType; extern PyTypeObject BranchType; extern PyTypeObject SignatureType; extern PyTypeObject RemoteType; extern PyTypeObject RefspecType; extern PyTypeObject NoteType; extern PyTypeObject NoteIterType; extern PyTypeObject WorktreeType; extern PyTypeObject MailmapType; extern PyTypeObject StashType; extern PyTypeObject RefsIteratorType; extern PyTypeObject FilterSourceType; PyDoc_STRVAR(discover_repository__doc__, "discover_repository(path: str, across_fs: bool = False[, ceiling_dirs: str]) -> str\n" "\n" "Look for a git repository and return its path. If not found returns None."); PyObject * discover_repository(PyObject *self, PyObject *args) { git_buf repo_path = {NULL}; const char *path = NULL; PyBytesObject *py_path = NULL; int across_fs = 0; PyBytesObject *py_ceiling_dirs = NULL; const char *ceiling_dirs = NULL; PyObject *py_repo_path = NULL; int err; PyObject *result = NULL; if (!PyArg_ParseTuple(args, "O&|IO&", PyUnicode_FSConverter, &py_path, &across_fs, PyUnicode_FSConverter, &py_ceiling_dirs)) return NULL; if (py_path != NULL) path = PyBytes_AS_STRING(py_path); if (py_ceiling_dirs != NULL) ceiling_dirs = PyBytes_AS_STRING(py_ceiling_dirs); memset(&repo_path, 0, sizeof(git_buf)); err = git_repository_discover(&repo_path, path, across_fs, ceiling_dirs); if (err == GIT_OK) { py_repo_path = PyUnicode_DecodeFSDefault(repo_path.ptr); git_buf_dispose(&repo_path); result = py_repo_path; } else if (err == GIT_ENOTFOUND) { result = Py_None; } else { result = Error_set_str(err, path); } Py_XDECREF(py_ceiling_dirs); Py_XDECREF(py_path); return result; }; PyDoc_STRVAR(hashfile__doc__, "hashfile(path: str) -> Oid\n" "\n" "Returns the oid of a new blob from a file path without actually writing\n" "to the odb."); PyObject * hashfile(PyObject *self, PyObject *args) { git_oid oid; PyBytesObject *py_path = NULL; const char* path = NULL; int err; if (!PyArg_ParseTuple(args, "O&", PyUnicode_FSConverter, &py_path)) return NULL; if (py_path != NULL) path = PyBytes_AS_STRING(py_path); err = git_odb_hashfile(&oid, path, GIT_OBJECT_BLOB); Py_XDECREF(py_path); if (err < 0) return Error_set(err); return git_oid_to_python(&oid); } PyDoc_STRVAR(hash__doc__, "hash(data: bytes) -> Oid\n" "\n" "Returns the oid of a new blob from a string without actually writing to\n" "the odb."); PyObject * hash(PyObject *self, PyObject *args) { git_oid oid; const char *data; Py_ssize_t size; int err; if (!PyArg_ParseTuple(args, "s#", &data, &size)) return NULL; err = git_odb_hash(&oid, data, size, GIT_OBJECT_BLOB); if (err < 0) { return Error_set(err); } return git_oid_to_python(&oid); } PyDoc_STRVAR(init_file_backend__doc__, "init_file_backend(path: str, flags: int = 0) -> object\n" "\n" "Open repo backend given path."); PyObject * init_file_backend(PyObject *self, PyObject *args) { PyBytesObject *py_path = NULL; const char* path = NULL; unsigned int flags = 0; int err = GIT_OK; git_repository *repository = NULL; PyObject *result = NULL; if (!PyArg_ParseTuple(args, "O&|I", PyUnicode_FSConverter, &py_path, &flags)) return NULL; if (py_path != NULL) path = PyBytes_AS_STRING(py_path); err = git_repository_open_ext(&repository, path, flags, NULL); if (err == GIT_OK) { result = PyCapsule_New(repository, "backend", NULL); } else { result = NULL; Error_set_str(err, path); if (repository) { git_repository_free(repository); } if (err == GIT_ENOTFOUND) { PyErr_Format(GitError, "Repository not found at %s", path); } } Py_XDECREF(py_path); return result; } PyDoc_STRVAR(reference_is_valid_name__doc__, "reference_is_valid_name(refname: str) -> bool\n" "\n" "Check if the passed string is a valid reference name."); PyObject * reference_is_valid_name(PyObject *self, PyObject *py_refname) { const char *refname = pgit_borrow(py_refname); if (refname == NULL) return NULL; int result = git_reference_is_valid_name(refname); return PyBool_FromLong(result); } PyDoc_STRVAR(tree_entry_cmp__doc__, "tree_entry_cmp(a: Object, b: Object) -> int\n" "\n" "Rich comparison for objects, only available when the objects have been\n" "obtained through a tree. The sort criteria is the one Git uses to sort\n" "tree entries in a tree object. This function wraps git_tree_entry_cmp.\n" "\n" "Returns < 0 if a is before b, > 0 if a is after b, and 0 if a and b are\n" "the same."); PyObject * tree_entry_cmp(PyObject *self, PyObject *args) { Object *a, *b; int cmp; if (!PyArg_ParseTuple(args, "O!O!", &ObjectType, &a, &ObjectType, &b)) return NULL; if (a->entry == NULL || b->entry == NULL) { PyErr_SetString(PyExc_ValueError, "objects lack entry information"); return NULL; } cmp = git_tree_entry_cmp(a->entry, b->entry); return PyLong_FromLong(cmp); } PyDoc_STRVAR(filter_register__doc__, "filter_register(name: str, filter_cls: Type[Filter], [priority: int = C.GIT_FILTER_DRIVER_PRIORITY]) -> None\n" "\n" "Register a filter under the given name.\n" "\n" "Filters will be run in order of `priority` on smudge (to workdir) and in\n" "reverse order of priority on clean (to odb).\n" "\n" "Two filters are preregistered with libgit2:\n" " - GIT_FILTER_CRLF with priority 0\n" " - GIT_FILTER_IDENT with priority 100\n" "\n" "`priority` defaults to GIT_FILTER_DRIVER_PRIORITY which imitates a core\n" "Git filter driver that will be run last on checkout (smudge) and first \n" "on check-in (clean).\n" "\n" "Note that the filter registry is not thread safe. Any registering or\n" "deregistering of filters should be done outside of any possible usage\n" "of the filters.\n"); PyObject * filter_register(PyObject *self, PyObject *args, PyObject *kwds) { const char *name; Py_ssize_t size; PyObject *py_filter_cls; int priority = GIT_FILTER_DRIVER_PRIORITY; char *keywords[] = {"name", "filter_cls", "priority", NULL}; pygit2_filter *filter; int err; if (!PyArg_ParseTupleAndKeywords(args, kwds, "s#O|i", keywords, &name, &size, &py_filter_cls, &priority)) return NULL; /* py_attrs = py_filter_cls.attributes */ PyObject* py_attrs = PyObject_GetAttrString(py_filter_cls, "attributes"); if (py_attrs == NULL) { return NULL; } char* attrs = pgit_strdup(py_attrs); Py_DECREF(py_attrs); if (attrs == NULL) { return NULL; } /* allocate memory */ filter = malloc(sizeof(pygit2_filter)); if (filter == NULL) { free(attrs); return PyErr_NoMemory(); } memset(filter, 0, sizeof(pygit2_filter)); /* initialize git_filter */ git_filter_init(&filter->filter, GIT_FILTER_VERSION); filter->filter.attributes = attrs; filter->filter.shutdown = pygit2_filter_shutdown; filter->filter.check = pygit2_filter_check; filter->filter.stream = pygit2_filter_stream; filter->filter.cleanup = pygit2_filter_cleanup; /* keep reference to Python filter */ filter->py_filter_cls = py_filter_cls; /* git register filter */ if ((err = git_filter_register(name, &filter->filter, priority)) < 0) { free(attrs); free(filter); return Error_set(err); } Py_INCREF(py_filter_cls); /* libgit2 now owns this reference, will decref in shutdown */ Py_RETURN_NONE; } static void forget_enums(void) { Py_CLEAR(DeltaStatusEnum); Py_CLEAR(DiffFlagEnum); Py_CLEAR(FileModeEnum); Py_CLEAR(FileStatusEnum); Py_CLEAR(MergeAnalysisEnum); Py_CLEAR(MergePreferenceEnum); Py_CLEAR(ObjectTypeEnum); Py_CLEAR(ReferenceTypeEnum); } PyDoc_STRVAR(_cache_enums__doc__, "_cache_enums()\n" "\n" "For internal use only. Do not call this from user code.\n" "\n" "Let the _pygit2 C module cache references to Python enums\n" "defined in pygit2.enums.\n"); PyObject * _cache_enums(PyObject *self, PyObject *args) { (void) args; /* In case this is somehow being called several times, let go of old references */ forget_enums(); PyObject *enums = PyImport_ImportModule("pygit2.enums"); if (enums == NULL) { return NULL; } #define CACHE_PYGIT2_ENUM(name) do { \ name##Enum = PyObject_GetAttrString(enums, #name); \ if (name##Enum == NULL) { goto fail; } \ } while (0) CACHE_PYGIT2_ENUM(DeltaStatus); CACHE_PYGIT2_ENUM(DiffFlag); CACHE_PYGIT2_ENUM(FileMode); CACHE_PYGIT2_ENUM(FileStatus); CACHE_PYGIT2_ENUM(MergeAnalysis); CACHE_PYGIT2_ENUM(MergePreference); CACHE_PYGIT2_ENUM(ObjectType); CACHE_PYGIT2_ENUM(ReferenceType); #undef CACHE_PYGIT2_ENUM Py_DECREF(enums); Py_RETURN_NONE; fail: Py_DECREF(enums); forget_enums(); return NULL; } void free_module(void *self) { forget_enums(); } static PyMethodDef module_methods[] = { {"discover_repository", discover_repository, METH_VARARGS, discover_repository__doc__}, {"hash", hash, METH_VARARGS, hash__doc__}, {"hashfile", hashfile, METH_VARARGS, hashfile__doc__}, {"init_file_backend", init_file_backend, METH_VARARGS, init_file_backend__doc__}, {"reference_is_valid_name", reference_is_valid_name, METH_O, reference_is_valid_name__doc__}, {"tree_entry_cmp", tree_entry_cmp, METH_VARARGS, tree_entry_cmp__doc__}, {"filter_register", (PyCFunction)filter_register, METH_VARARGS | METH_KEYWORDS, filter_register__doc__}, {"_cache_enums", _cache_enums, METH_NOARGS, _cache_enums__doc__}, {NULL} }; struct PyModuleDef moduledef = { PyModuleDef_HEAD_INIT, "_pygit2", /* m_name */ "Python bindings for libgit2.", /* m_doc */ -1, /* m_size */ module_methods, /* m_methods */ NULL, /* m_reload */ NULL, /* m_traverse */ NULL, /* m_clear */ free_module, /* m_free */ }; PyMODINIT_FUNC PyInit__pygit2(void) { PyObject *m = PyModule_Create(&moduledef); if (m == NULL) return NULL; #ifdef Py_GIL_DISABLED PyUnstable_Module_SetGIL(m, Py_MOD_GIL_NOT_USED); #endif /* libgit2 version info */ ADD_CONSTANT_INT(m, LIBGIT2_VER_MAJOR) ADD_CONSTANT_INT(m, LIBGIT2_VER_MINOR) ADD_CONSTANT_INT(m, LIBGIT2_VER_REVISION) ADD_CONSTANT_STR(m, LIBGIT2_VERSION) /* Exceptions */ ADD_EXC(m, GitError, NULL); ADD_EXC2(m, AlreadyExistsError, GitError, PyExc_ValueError); ADD_EXC2(m, InvalidSpecError, GitError, PyExc_ValueError); ADD_EXC2(m, InvalidError, GitError, PyExc_ValueError); ADD_EXC2(m, NotFoundError, GitError, PyExc_KeyError); ADD_EXC2(m, AmbiguousError, GitError, PyExc_ValueError); ADD_EXC(m, AuthError, GitError); ADD_EXC(m, CertificateError, GitError); /* Repository */ INIT_TYPE(RepositoryType, NULL, PyType_GenericNew) ADD_TYPE(m, Repository) /* Odb */ INIT_TYPE(OdbType, NULL, PyType_GenericNew) ADD_TYPE(m, Odb) INIT_TYPE(OdbBackendType, NULL, PyType_GenericNew) ADD_TYPE(m, OdbBackend) INIT_TYPE(OdbBackendPackType, &OdbBackendType, PyType_GenericNew) ADD_TYPE(m, OdbBackendPack) INIT_TYPE(OdbBackendLooseType, &OdbBackendType, PyType_GenericNew) ADD_TYPE(m, OdbBackendLoose) /* Oid */ INIT_TYPE(OidType, NULL, PyType_GenericNew) ADD_TYPE(m, Oid) ADD_CONSTANT_INT(m, GIT_OID_RAWSZ) ADD_CONSTANT_INT(m, GIT_OID_HEXSZ) ADD_CONSTANT_STR(m, GIT_OID_HEX_ZERO) ADD_CONSTANT_INT(m, GIT_OID_MINPREFIXLEN) /* * Objects */ INIT_TYPE(ObjectType, NULL, NULL) INIT_TYPE(CommitType, &ObjectType, NULL) INIT_TYPE(SignatureType, NULL, PyType_GenericNew) INIT_TYPE(TreeType, &ObjectType, NULL) INIT_TYPE(TreeIterType, NULL, NULL) INIT_TYPE(TreeBuilderType, NULL, NULL) INIT_TYPE(BlobType, &ObjectType, NULL) INIT_TYPE(TagType, &ObjectType, NULL) INIT_TYPE(RefsIteratorType, NULL, NULL) ADD_TYPE(m, Object) ADD_TYPE(m, Commit) ADD_TYPE(m, Signature) ADD_TYPE(m, Tree) ADD_TYPE(m, TreeBuilder) ADD_TYPE(m, Blob) ADD_TYPE(m, Tag) ADD_CONSTANT_INT(m, GIT_OBJECT_ANY) ADD_CONSTANT_INT(m, GIT_OBJECT_INVALID) ADD_CONSTANT_INT(m, GIT_OBJECT_COMMIT) ADD_CONSTANT_INT(m, GIT_OBJECT_TREE) ADD_CONSTANT_INT(m, GIT_OBJECT_BLOB) ADD_CONSTANT_INT(m, GIT_OBJECT_TAG) ADD_CONSTANT_INT(m, GIT_OBJECT_OFS_DELTA) ADD_CONSTANT_INT(m, GIT_OBJECT_REF_DELTA) /* Valid modes for index and tree entries. */ ADD_CONSTANT_INT(m, GIT_FILEMODE_UNREADABLE) ADD_CONSTANT_INT(m, GIT_FILEMODE_TREE) ADD_CONSTANT_INT(m, GIT_FILEMODE_BLOB) ADD_CONSTANT_INT(m, GIT_FILEMODE_BLOB_EXECUTABLE) ADD_CONSTANT_INT(m, GIT_FILEMODE_LINK) ADD_CONSTANT_INT(m, GIT_FILEMODE_COMMIT) /* * Log */ INIT_TYPE(WalkerType, NULL, NULL) ADD_TYPE(m, Walker); ADD_CONSTANT_INT(m, GIT_SORT_NONE) ADD_CONSTANT_INT(m, GIT_SORT_TOPOLOGICAL) ADD_CONSTANT_INT(m, GIT_SORT_TIME) ADD_CONSTANT_INT(m, GIT_SORT_REVERSE) /* * Reset */ ADD_CONSTANT_INT(m, GIT_RESET_SOFT) ADD_CONSTANT_INT(m, GIT_RESET_MIXED) ADD_CONSTANT_INT(m, GIT_RESET_HARD) /* Refdb */ INIT_TYPE(RefdbType, NULL, PyType_GenericNew) ADD_TYPE(m, Refdb) INIT_TYPE(RefdbBackendType, NULL, PyType_GenericNew) ADD_TYPE(m, RefdbBackend) INIT_TYPE(RefdbFsBackendType, &RefdbBackendType, PyType_GenericNew) ADD_TYPE(m, RefdbFsBackend) /* * References */ INIT_TYPE(ReferenceType, NULL, PyType_GenericNew) INIT_TYPE(RefLogEntryType, NULL, NULL) INIT_TYPE(RefLogIterType, NULL, NULL) INIT_TYPE(NoteType, NULL, NULL) INIT_TYPE(NoteIterType, NULL, NULL) ADD_TYPE(m, Reference) ADD_TYPE(m, RefLogEntry) ADD_TYPE(m, Note) ADD_CONSTANT_INT(m, GIT_REFERENCES_ALL) ADD_CONSTANT_INT(m, GIT_REFERENCES_BRANCHES) ADD_CONSTANT_INT(m, GIT_REFERENCES_TAGS) /* * RevSpec */ INIT_TYPE(RevSpecType, NULL, NULL) ADD_TYPE(m, RevSpec) ADD_CONSTANT_INT(m, GIT_REVSPEC_SINGLE) ADD_CONSTANT_INT(m, GIT_REVSPEC_RANGE) ADD_CONSTANT_INT(m, GIT_REVSPEC_MERGE_BASE) /* * Worktree */ INIT_TYPE(WorktreeType, NULL, NULL) ADD_TYPE(m, Worktree) /* * Branches */ INIT_TYPE(BranchType, &ReferenceType, NULL); ADD_TYPE(m, Branch) ADD_CONSTANT_INT(m, GIT_BRANCH_LOCAL) ADD_CONSTANT_INT(m, GIT_BRANCH_REMOTE) ADD_CONSTANT_INT(m, GIT_BRANCH_ALL) /* * Index & Working copy */ /* Status */ ADD_CONSTANT_INT(m, GIT_STATUS_CURRENT) ADD_CONSTANT_INT(m, GIT_STATUS_INDEX_NEW) ADD_CONSTANT_INT(m, GIT_STATUS_INDEX_MODIFIED) ADD_CONSTANT_INT(m, GIT_STATUS_INDEX_DELETED) ADD_CONSTANT_INT(m, GIT_STATUS_INDEX_RENAMED) ADD_CONSTANT_INT(m, GIT_STATUS_INDEX_TYPECHANGE) ADD_CONSTANT_INT(m, GIT_STATUS_WT_NEW) ADD_CONSTANT_INT(m, GIT_STATUS_WT_MODIFIED) ADD_CONSTANT_INT(m, GIT_STATUS_WT_DELETED) ADD_CONSTANT_INT(m, GIT_STATUS_WT_TYPECHANGE) ADD_CONSTANT_INT(m, GIT_STATUS_WT_RENAMED) ADD_CONSTANT_INT(m, GIT_STATUS_WT_UNREADABLE) 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_FORCE) ADD_CONSTANT_INT(m, GIT_CHECKOUT_RECREATE_MISSING) ADD_CONSTANT_INT(m, GIT_CHECKOUT_ALLOW_CONFLICTS) ADD_CONSTANT_INT(m, GIT_CHECKOUT_REMOVE_UNTRACKED) ADD_CONSTANT_INT(m, GIT_CHECKOUT_REMOVE_IGNORED) ADD_CONSTANT_INT(m, GIT_CHECKOUT_UPDATE_ONLY) ADD_CONSTANT_INT(m, GIT_CHECKOUT_DONT_UPDATE_INDEX) ADD_CONSTANT_INT(m, GIT_CHECKOUT_NO_REFRESH) ADD_CONSTANT_INT(m, GIT_CHECKOUT_SKIP_UNMERGED) ADD_CONSTANT_INT(m, GIT_CHECKOUT_USE_OURS) ADD_CONSTANT_INT(m, GIT_CHECKOUT_USE_THEIRS) ADD_CONSTANT_INT(m, GIT_CHECKOUT_DISABLE_PATHSPEC_MATCH) ADD_CONSTANT_INT(m, GIT_CHECKOUT_SKIP_LOCKED_DIRECTORIES) ADD_CONSTANT_INT(m, GIT_CHECKOUT_DONT_OVERWRITE_IGNORED) ADD_CONSTANT_INT(m, GIT_CHECKOUT_CONFLICT_STYLE_MERGE) ADD_CONSTANT_INT(m, GIT_CHECKOUT_CONFLICT_STYLE_DIFF3) ADD_CONSTANT_INT(m, GIT_CHECKOUT_DONT_REMOVE_EXISTING) ADD_CONSTANT_INT(m, GIT_CHECKOUT_DONT_WRITE_INDEX) ADD_CONSTANT_INT(m, GIT_CHECKOUT_DRY_RUN) ADD_CONSTANT_INT(m, GIT_CHECKOUT_CONFLICT_STYLE_ZDIFF3) /* * Diff */ INIT_TYPE(DiffType, NULL, NULL) INIT_TYPE(DeltasIterType, NULL, NULL) INIT_TYPE(DiffIterType, NULL, NULL) INIT_TYPE(DiffDeltaType, NULL, NULL) INIT_TYPE(DiffFileType, NULL, NULL) INIT_TYPE(DiffHunkType, NULL, NULL) INIT_TYPE(DiffLineType, NULL, NULL) INIT_TYPE(DiffStatsType, NULL, NULL) INIT_TYPE(PatchType, NULL, NULL) ADD_TYPE(m, Diff) ADD_TYPE(m, DiffDelta) ADD_TYPE(m, DiffFile) ADD_TYPE(m, DiffHunk) ADD_TYPE(m, DiffLine) ADD_TYPE(m, DiffStats) ADD_TYPE(m, Patch) /* (git_diff_options in libgit2) */ ADD_CONSTANT_INT(m, GIT_DIFF_NORMAL) ADD_CONSTANT_INT(m, GIT_DIFF_REVERSE) ADD_CONSTANT_INT(m, GIT_DIFF_INCLUDE_IGNORED) ADD_CONSTANT_INT(m, GIT_DIFF_RECURSE_IGNORED_DIRS) ADD_CONSTANT_INT(m, GIT_DIFF_INCLUDE_UNTRACKED) ADD_CONSTANT_INT(m, GIT_DIFF_RECURSE_UNTRACKED_DIRS) ADD_CONSTANT_INT(m, GIT_DIFF_INCLUDE_UNMODIFIED) ADD_CONSTANT_INT(m, GIT_DIFF_INCLUDE_TYPECHANGE) ADD_CONSTANT_INT(m, GIT_DIFF_INCLUDE_TYPECHANGE_TREES) ADD_CONSTANT_INT(m, GIT_DIFF_IGNORE_FILEMODE) ADD_CONSTANT_INT(m, GIT_DIFF_IGNORE_SUBMODULES) ADD_CONSTANT_INT(m, GIT_DIFF_IGNORE_CASE) ADD_CONSTANT_INT(m, GIT_DIFF_INCLUDE_CASECHANGE) ADD_CONSTANT_INT(m, GIT_DIFF_DISABLE_PATHSPEC_MATCH) ADD_CONSTANT_INT(m, GIT_DIFF_SKIP_BINARY_CHECK) ADD_CONSTANT_INT(m, GIT_DIFF_ENABLE_FAST_UNTRACKED_DIRS) ADD_CONSTANT_INT(m, GIT_DIFF_UPDATE_INDEX) ADD_CONSTANT_INT(m, GIT_DIFF_INCLUDE_UNREADABLE) ADD_CONSTANT_INT(m, GIT_DIFF_INCLUDE_UNREADABLE_AS_UNTRACKED) ADD_CONSTANT_INT(m, GIT_DIFF_INDENT_HEURISTIC) ADD_CONSTANT_INT(m, GIT_DIFF_IGNORE_BLANK_LINES) ADD_CONSTANT_INT(m, GIT_DIFF_FORCE_TEXT) ADD_CONSTANT_INT(m, GIT_DIFF_FORCE_BINARY) ADD_CONSTANT_INT(m, GIT_DIFF_IGNORE_WHITESPACE) ADD_CONSTANT_INT(m, GIT_DIFF_IGNORE_WHITESPACE_CHANGE) ADD_CONSTANT_INT(m, GIT_DIFF_IGNORE_WHITESPACE_EOL) ADD_CONSTANT_INT(m, GIT_DIFF_SHOW_UNTRACKED_CONTENT) ADD_CONSTANT_INT(m, GIT_DIFF_SHOW_UNMODIFIED) ADD_CONSTANT_INT(m, GIT_DIFF_PATIENCE) ADD_CONSTANT_INT(m, GIT_DIFF_MINIMAL) ADD_CONSTANT_INT(m, GIT_DIFF_SHOW_BINARY) /* Formatting options for diff stats (git_diff_stats_format_t in libgit2) */ ADD_CONSTANT_INT(m, GIT_DIFF_STATS_NONE) ADD_CONSTANT_INT(m, GIT_DIFF_STATS_FULL) ADD_CONSTANT_INT(m, GIT_DIFF_STATS_SHORT) ADD_CONSTANT_INT(m, GIT_DIFF_STATS_NUMBER) ADD_CONSTANT_INT(m, GIT_DIFF_STATS_INCLUDE_SUMMARY) /* Flags for Diff.find_similar (git_diff_find_t in libgit2) */ ADD_CONSTANT_INT(m, GIT_DIFF_FIND_BY_CONFIG) /** Obey diff.renames */ ADD_CONSTANT_INT(m, GIT_DIFF_FIND_RENAMES) /* --find-renames */ ADD_CONSTANT_INT(m, GIT_DIFF_FIND_RENAMES_FROM_REWRITES) /* --break-rewrites=N */ ADD_CONSTANT_INT(m, GIT_DIFF_FIND_COPIES) /* --find-copies */ ADD_CONSTANT_INT(m, GIT_DIFF_FIND_COPIES_FROM_UNMODIFIED) /* --find-copies-harder */ ADD_CONSTANT_INT(m, GIT_DIFF_FIND_REWRITES) /* --break-rewrites=/M */ ADD_CONSTANT_INT(m, GIT_DIFF_BREAK_REWRITES) ADD_CONSTANT_INT(m, GIT_DIFF_FIND_AND_BREAK_REWRITES) ADD_CONSTANT_INT(m, GIT_DIFF_FIND_FOR_UNTRACKED) ADD_CONSTANT_INT(m, GIT_DIFF_FIND_ALL) /* Turn on all finding features. */ ADD_CONSTANT_INT(m, GIT_DIFF_FIND_IGNORE_LEADING_WHITESPACE) ADD_CONSTANT_INT(m, GIT_DIFF_FIND_IGNORE_WHITESPACE) ADD_CONSTANT_INT(m, GIT_DIFF_FIND_DONT_IGNORE_WHITESPACE) ADD_CONSTANT_INT(m, GIT_DIFF_FIND_EXACT_MATCH_ONLY) ADD_CONSTANT_INT(m, GIT_DIFF_BREAK_REWRITES_FOR_RENAMES_ONLY) ADD_CONSTANT_INT(m, GIT_DIFF_FIND_REMOVE_UNMODIFIED) /* DiffDelta and DiffFile flags (git_diff_flag_t in libgit2) */ ADD_CONSTANT_INT(m, GIT_DIFF_FLAG_BINARY) ADD_CONSTANT_INT(m, GIT_DIFF_FLAG_NOT_BINARY) ADD_CONSTANT_INT(m, GIT_DIFF_FLAG_VALID_ID) ADD_CONSTANT_INT(m, GIT_DIFF_FLAG_EXISTS) ADD_CONSTANT_INT(m, GIT_DIFF_FLAG_VALID_SIZE) /* DiffDelta.status (git_delta_t in libgit2) */ ADD_CONSTANT_INT(m, GIT_DELTA_UNMODIFIED) ADD_CONSTANT_INT(m, GIT_DELTA_ADDED) ADD_CONSTANT_INT(m, GIT_DELTA_DELETED) ADD_CONSTANT_INT(m, GIT_DELTA_MODIFIED) ADD_CONSTANT_INT(m, GIT_DELTA_RENAMED) ADD_CONSTANT_INT(m, GIT_DELTA_COPIED) ADD_CONSTANT_INT(m, GIT_DELTA_IGNORED) ADD_CONSTANT_INT(m, GIT_DELTA_UNTRACKED) ADD_CONSTANT_INT(m, GIT_DELTA_TYPECHANGE) ADD_CONSTANT_INT(m, GIT_DELTA_UNREADABLE) ADD_CONSTANT_INT(m, GIT_DELTA_CONFLICTED) /* Config */ ADD_CONSTANT_INT(m, GIT_CONFIG_LEVEL_PROGRAMDATA); ADD_CONSTANT_INT(m, GIT_CONFIG_LEVEL_SYSTEM); ADD_CONSTANT_INT(m, GIT_CONFIG_LEVEL_XDG); ADD_CONSTANT_INT(m, GIT_CONFIG_LEVEL_GLOBAL); ADD_CONSTANT_INT(m, GIT_CONFIG_LEVEL_LOCAL); ADD_CONSTANT_INT(m, GIT_CONFIG_LEVEL_WORKTREE); ADD_CONSTANT_INT(m, GIT_CONFIG_LEVEL_APP); ADD_CONSTANT_INT(m, GIT_CONFIG_HIGHEST_LEVEL); /* Blame */ ADD_CONSTANT_INT(m, GIT_BLAME_NORMAL) ADD_CONSTANT_INT(m, GIT_BLAME_TRACK_COPIES_SAME_FILE) ADD_CONSTANT_INT(m, GIT_BLAME_TRACK_COPIES_SAME_COMMIT_MOVES) ADD_CONSTANT_INT(m, GIT_BLAME_TRACK_COPIES_SAME_COMMIT_COPIES) ADD_CONSTANT_INT(m, GIT_BLAME_TRACK_COPIES_ANY_COMMIT_COPIES) ADD_CONSTANT_INT(m, GIT_BLAME_FIRST_PARENT) ADD_CONSTANT_INT(m, GIT_BLAME_USE_MAILMAP) ADD_CONSTANT_INT(m, GIT_BLAME_IGNORE_WHITESPACE) /* Merge */ ADD_CONSTANT_INT(m, GIT_MERGE_ANALYSIS_NONE) ADD_CONSTANT_INT(m, GIT_MERGE_ANALYSIS_NORMAL) ADD_CONSTANT_INT(m, GIT_MERGE_ANALYSIS_UP_TO_DATE) ADD_CONSTANT_INT(m, GIT_MERGE_ANALYSIS_FASTFORWARD) ADD_CONSTANT_INT(m, GIT_MERGE_ANALYSIS_UNBORN) ADD_CONSTANT_INT(m, GIT_MERGE_PREFERENCE_NONE) ADD_CONSTANT_INT(m, GIT_MERGE_PREFERENCE_NO_FASTFORWARD) ADD_CONSTANT_INT(m, GIT_MERGE_PREFERENCE_FASTFORWARD_ONLY) /* Describe */ ADD_CONSTANT_INT(m, GIT_DESCRIBE_DEFAULT); ADD_CONSTANT_INT(m, GIT_DESCRIBE_TAGS); ADD_CONSTANT_INT(m, GIT_DESCRIBE_ALL); /* Stash */ ADD_CONSTANT_INT(m, GIT_STASH_DEFAULT); ADD_CONSTANT_INT(m, GIT_STASH_KEEP_INDEX); ADD_CONSTANT_INT(m, GIT_STASH_INCLUDE_UNTRACKED); ADD_CONSTANT_INT(m, GIT_STASH_INCLUDE_IGNORED); ADD_CONSTANT_INT(m, GIT_STASH_KEEP_ALL); ADD_CONSTANT_INT(m, GIT_STASH_APPLY_DEFAULT); ADD_CONSTANT_INT(m, GIT_STASH_APPLY_REINSTATE_INDEX); /* Apply location */ ADD_CONSTANT_INT(m, GIT_APPLY_LOCATION_WORKDIR); ADD_CONSTANT_INT(m, GIT_APPLY_LOCATION_INDEX); ADD_CONSTANT_INT(m, GIT_APPLY_LOCATION_BOTH); /* Submodule */ ADD_CONSTANT_INT(m, GIT_SUBMODULE_IGNORE_UNSPECIFIED); ADD_CONSTANT_INT(m, GIT_SUBMODULE_IGNORE_NONE); ADD_CONSTANT_INT(m, GIT_SUBMODULE_IGNORE_UNTRACKED); ADD_CONSTANT_INT(m, GIT_SUBMODULE_IGNORE_DIRTY); ADD_CONSTANT_INT(m, GIT_SUBMODULE_IGNORE_ALL); ADD_CONSTANT_INT(m, GIT_SUBMODULE_STATUS_IN_HEAD); ADD_CONSTANT_INT(m, GIT_SUBMODULE_STATUS_IN_INDEX); ADD_CONSTANT_INT(m, GIT_SUBMODULE_STATUS_IN_CONFIG); ADD_CONSTANT_INT(m, GIT_SUBMODULE_STATUS_IN_WD); ADD_CONSTANT_INT(m, GIT_SUBMODULE_STATUS_INDEX_ADDED); ADD_CONSTANT_INT(m, GIT_SUBMODULE_STATUS_INDEX_DELETED); ADD_CONSTANT_INT(m, GIT_SUBMODULE_STATUS_INDEX_MODIFIED); ADD_CONSTANT_INT(m, GIT_SUBMODULE_STATUS_WD_UNINITIALIZED); ADD_CONSTANT_INT(m, GIT_SUBMODULE_STATUS_WD_ADDED); ADD_CONSTANT_INT(m, GIT_SUBMODULE_STATUS_WD_DELETED); ADD_CONSTANT_INT(m, GIT_SUBMODULE_STATUS_WD_MODIFIED); ADD_CONSTANT_INT(m, GIT_SUBMODULE_STATUS_WD_INDEX_MODIFIED); ADD_CONSTANT_INT(m, GIT_SUBMODULE_STATUS_WD_WD_MODIFIED); ADD_CONSTANT_INT(m, GIT_SUBMODULE_STATUS_WD_UNTRACKED); /* Mailmap */ INIT_TYPE(MailmapType, NULL, PyType_GenericNew) ADD_TYPE(m, Mailmap) /* Stash */ INIT_TYPE(StashType, NULL, NULL) ADD_TYPE(m, Stash) /* Blob filter */ ADD_CONSTANT_INT(m, GIT_BLOB_FILTER_CHECK_FOR_BINARY); ADD_CONSTANT_INT(m, GIT_BLOB_FILTER_NO_SYSTEM_ATTRIBUTES); ADD_CONSTANT_INT(m, GIT_BLOB_FILTER_ATTRIBUTES_FROM_HEAD); ADD_CONSTANT_INT(m, GIT_BLOB_FILTER_ATTRIBUTES_FROM_COMMIT); ADD_CONSTANT_INT(m, GIT_FILTER_DRIVER_PRIORITY); ADD_CONSTANT_INT(m, GIT_FILTER_TO_WORKTREE); ADD_CONSTANT_INT(m, GIT_FILTER_SMUDGE); ADD_CONSTANT_INT(m, GIT_FILTER_TO_ODB); ADD_CONSTANT_INT(m, GIT_FILTER_CLEAN); ADD_CONSTANT_INT(m, GIT_FILTER_DEFAULT); ADD_CONSTANT_INT(m, GIT_FILTER_ALLOW_UNSAFE); ADD_CONSTANT_INT(m, GIT_FILTER_NO_SYSTEM_ATTRIBUTES); ADD_CONSTANT_INT(m, GIT_FILTER_ATTRIBUTES_FROM_HEAD); ADD_CONSTANT_INT(m, GIT_FILTER_ATTRIBUTES_FROM_COMMIT); INIT_TYPE(FilterSourceType, NULL, NULL); ADD_TYPE(m, FilterSource); /* Global initialization of libgit2 */ git_libgit2_init(); return m; fail: Py_DECREF(m); return NULL; }