Skip to content

Commit

Permalink
Add Repository.listall_mergeheads()
Browse files Browse the repository at this point in the history
  • Loading branch information
jorio committed Dec 30, 2023
1 parent 611a3b3 commit eedf2ce
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 0 deletions.
1 change: 1 addition & 0 deletions pygit2/_pygit2.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -328,6 +328,7 @@ class Repository:
def git_object_lookup_prefix(self, oid: _OidArg) -> Object: ...
def list_worktrees(self) -> list[str]: ...
def listall_branches(self, flag: BranchType = BranchType.LOCAL) -> list[str]: ...
def listall_mergeheads(self) -> list[Oid]: ...
def listall_stashes(self) -> list[Stash]: ...
def listall_submodules(self) -> list[str]: ...
def lookup_branch(self, branch_name: str, branch_type: BranchType = BranchType.LOCAL) -> Branch: ...
Expand Down
47 changes: 47 additions & 0 deletions src/repository.c
Original file line number Diff line number Diff line change
Expand Up @@ -2336,6 +2336,52 @@ Repository_listall_stashes(Repository *self, PyObject *args)
}
}

static int foreach_mergehead_cb(const git_oid *oid, void *payload)
{
PyObject* py_oid = git_oid_to_python(oid);
if (py_oid == NULL)
return GIT_EUSER;

PyObject* list = (PyObject*) payload;
int err = PyList_Append(list, (PyObject*) py_oid);
Py_DECREF(py_oid);
if (err < 0)
return GIT_EUSER;

return 0;
}

PyDoc_STRVAR(Repository_listall_mergeheads__doc__,
"listall_mergeheads() -> list[Oid]\n"
"\n"
"If a merge is in progress, return a list of all commit oids in the MERGE_HEAD file.\n"
"Return an empty list if there is no MERGE_HEAD file (no merge in progress).");

PyObject *
Repository_listall_mergeheads(Repository *self, PyObject *args)
{
int err;

PyObject *list = PyList_New(0);
if (list == NULL)
return NULL;

err = git_repository_mergehead_foreach(self->repo, foreach_mergehead_cb, (void*)list);

if (err == 0) {
return list;
} else if (err == GIT_ENOTFOUND) {
/* MERGE_HEAD not found - return empty list */
return list;
}
else {
Py_CLEAR(list);
if (PyErr_Occurred())
return NULL;
return Error_set(err);
}
}

PyMethodDef Repository_methods[] = {
METHOD(Repository, create_blob, METH_VARARGS),
METHOD(Repository, create_blob_fromworkdir, METH_O),
Expand Down Expand Up @@ -2389,6 +2435,7 @@ PyMethodDef Repository_methods[] = {
METHOD(Repository, set_odb, METH_O),
METHOD(Repository, set_refdb, METH_O),
METHOD(Repository, listall_stashes, METH_NOARGS),
METHOD(Repository, listall_mergeheads, METH_NOARGS),
{NULL}
};

Expand Down
12 changes: 12 additions & 0 deletions test/test_merge.py
Original file line number Diff line number Diff line change
Expand Up @@ -274,3 +274,15 @@ def test_merge_octopus(mergerepo):
merge_tree = index.write_tree()

assert merge_tree == merge_commits_tree


def test_merge_mergeheads(mergerepo):
assert mergerepo.listall_mergeheads() == []

branch_head_hex = '1b2bae55ac95a4be3f8983b86cd579226d0eb247'
mergerepo.merge(branch_head_hex)

assert mergerepo.listall_mergeheads() == [pygit2.Oid(hex=branch_head_hex)]

mergerepo.state_cleanup()
assert mergerepo.listall_mergeheads() == [], "state_cleanup() should wipe the mergeheads"

0 comments on commit eedf2ce

Please sign in to comment.