Merge remote-tracking branch 'carlos/ahead-behind'

This commit is contained in:
J. David Ibáñez
2015-02-07 08:27:26 +01:00
6 changed files with 79 additions and 0 deletions

View File

@@ -69,4 +69,8 @@ Below there are some general attributes and methods:
.. automethod:: pygit2.Repository.write
.. automethod:: pygit2.Repository.reset
.. automethod:: pygit2.Repository.state_cleanup
<<<<<<< HEAD
.. automethod:: pygit2.Repository.write_archive
=======
.. automethod:: pygit2.Repository.ahead_behind
>>>>>>> Add Repsitory.ahead_behind()

View File

@@ -535,6 +535,7 @@ int git_repository_init_ext(
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_graph_ahead_behind(size_t *ahead, size_t *behind, git_repository *repo, const git_oid *local, const git_oid *upstream);
/*
* git_index

View File

@@ -625,3 +625,41 @@ class Repository(_Repository):
info.mode = 0o777 # symlinks get placeholder
archive.addfile(info, StringIO(content))
#
# Ahead-behind, which mostly lives on its own namespace
#
def ahead_behind(self, local, upstream):
"""ahead_behind(local, upstream) -> (int, int)
Calculate how many different commits are in the non-common parts
of the history between the two given ids.
Ahead is how many commits are in the ancestry of the 'local'
commit which are not in the 'upstream' commit. Behind is the
opposite.
Arguments
local
The commit which is considered the local or current state
upstream
The commit which is considered the upstream
Returns a tuple with the number of commits ahead and behind respectively.
"""
if not isinstance(local, Oid):
local = self.expand_id(local)
if not isinstance(upstream, Oid):
upstream = self.expand_id(upstream)
ahead, behind = ffi.new('size_t*'), ffi.new('size_t*')
oid1, oid2 = ffi.new('git_oid *'), ffi.new('git_oid *')
ffi.buffer(oid1)[:] = local.raw[:]
ffi.buffer(oid2)[:] = upstream.raw[:]
err = C.git_graph_ahead_behind(ahead, behind, self._repo, oid1, oid2)
check_error(err)
return int(ahead[0]), int(behind[0])

View File

@@ -1433,6 +1433,24 @@ Repository_reset(Repository *self, PyObject* args)
Py_RETURN_NONE;
}
PyDoc_STRVAR(Repository_expand_id__doc__,
"expand_id(hex) -> Oid\n"
"\n"
"Expand a string into a full Oid according to the objects in this repsitory.\n");
PyObject *
Repository_expand_id(Repository *self, PyObject *py_hex)
{
git_oid oid;
int err;
err = py_oid_to_git_oid_expand(self->repo, py_hex, &oid);
if (err < 0)
return NULL;
return git_oid_to_python(&oid);
}
PyMethodDef Repository_methods[] = {
METHOD(Repository, create_blob, METH_VARARGS),
METHOD(Repository, create_blob_fromworkdir, METH_VARARGS),
@@ -1461,6 +1479,7 @@ PyMethodDef Repository_methods[] = {
METHOD(Repository, listall_branches, METH_VARARGS),
METHOD(Repository, create_branch, METH_VARARGS),
METHOD(Repository, reset, METH_VARARGS),
METHOD(Repository, expand_id, METH_O),
METHOD(Repository, _from_c, METH_VARARGS),
METHOD(Repository, _disown, METH_NOARGS),
{NULL}

1
test/data/testrepo Submodule

Submodule test/data/testrepo added at 2be5719152

View File

@@ -156,6 +156,11 @@ class RepositoryTest(utils.BareRepoTestCase):
commit.message)
self.assertRaises(ValueError, self.repo.__getitem__, too_short_prefix)
def test_expand_id(self):
commit_sha = '5fe808e8953c12735680c257f56600cb0de44b10'
expanded = self.repo.expand_id(commit_sha[:7])
self.assertEqual(commit_sha, expanded.hex)
@unittest.skipIf(__pypy__ is not None, "skip refcounts checks in pypy")
def test_lookup_commit_refcount(self):
start = sys.getrefcount(self.repo)
@@ -295,6 +300,17 @@ class RepositoryTest_II(utils.RepoTestCase):
self.assertEqual(commit.hex,
'acecd5ea2924a4b900e7e149496e1f4b57976e51')
def test_ahead_behind(self):
ahead, behind = self.repo.ahead_behind('5ebeeebb320790caf276b9fc8b24546d63316533',
'4ec4389a8068641da2d6578db0419484972284c8')
self.assertEqual(1, ahead)
self.assertEqual(2, behind)
ahead, behind = self.repo.ahead_behind('4ec4389a8068641da2d6578db0419484972284c8',
'5ebeeebb320790caf276b9fc8b24546d63316533')
self.assertEqual(2, ahead)
self.assertEqual(1, behind)
def test_reset_hard(self):
ref = "5ebeeebb320790caf276b9fc8b24546d63316533"
with open(os.path.join(self.repo.workdir, "hello.txt")) as f: