From 761d23bb2d2707ab13288a35b49b69a7bab1b766 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Rodri=CC=81guez=20Troitin=CC=83o?= Date: Fri, 17 May 2013 23:00:53 +0200 Subject: [PATCH 1/4] Implement Branch.branch_name. --- src/branch.c | 19 +++++++++++++++++++ test/test_branch.py | 9 +++++++++ 2 files changed, 28 insertions(+) diff --git a/src/branch.c b/src/branch.c index a3b4c7803..48909d283 100644 --- a/src/branch.c +++ b/src/branch.c @@ -105,6 +105,24 @@ PyObject* Branch_rename(Branch *self, PyObject *args) } +PyDoc_STRVAR(Branch_branch_name__doc__, + "The name of the local or remote branch."); + +PyObject* Branch_branch_name__get__(Branch *self) +{ + int err; + const char *c_name; + + CHECK_REFERENCE(self); + + err = git_branch_name(&c_name, self->reference); + if (err == GIT_OK) + return to_unicode(c_name, NULL, NULL); + else + return Error_set(err); +} + + PyMethodDef Branch_methods[] = { METHOD(Branch, delete, METH_NOARGS), METHOD(Branch, is_head, METH_NOARGS), @@ -113,6 +131,7 @@ PyMethodDef Branch_methods[] = { }; PyGetSetDef Branch_getseters[] = { + GETTER(Branch, branch_name), {NULL} }; diff --git a/test/test_branch.py b/test/test_branch.py index eebf1e03e..a1289d7ba 100644 --- a/test/test_branch.py +++ b/test/test_branch.py @@ -110,6 +110,15 @@ def test_branch_rename_fails_with_invalid_names(self): self.assertRaises(ValueError, lambda: original_branch.rename('abc@{123')) + def test_branch_name(self): + branch = self.repo.lookup_branch('master') + self.assertEqual(branch.branch_name, 'master') + self.assertEqual(branch.name, 'refs/heads/master') + + branch = self.repo.lookup_branch('i18n') + self.assertEqual(branch.branch_name, 'i18n') + self.assertEqual(branch.name, 'refs/heads/i18n') + class BranchesEmptyRepoTestCase(utils.EmptyRepoTestCase): def setUp(self): From 8d9f59edec9c5ee400c52c88df258856dff6c1e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Rodri=CC=81guez=20Troitin=CC=83o?= Date: Fri, 17 May 2013 23:03:40 +0200 Subject: [PATCH 2/4] Implement Branch.remote_name. --- src/branch.c | 39 +++++++++++++++++++++++++++++++++++++++ test/test_branch.py | 6 ++++++ 2 files changed, 45 insertions(+) diff --git a/src/branch.c b/src/branch.c index 48909d283..a3a3126a0 100644 --- a/src/branch.c +++ b/src/branch.c @@ -123,6 +123,44 @@ PyObject* Branch_branch_name__get__(Branch *self) } +PyDoc_STRVAR(Branch_remote_name__doc__, + "The name of the remote that the remote tracking branch belongs to."); + +PyObject* Branch_remote_name__get__(Branch *self) +{ + int err; + const char *branch_name; + char *c_name = NULL; + + CHECK_REFERENCE(self); + + branch_name = git_reference_name(self->reference); + // get the length of the remote name + err = git_branch_remote_name(NULL, 0, self->repo->repo, branch_name); + if (err < GIT_OK) + return Error_set(err); + + // get the actual remote name + c_name = calloc(err, sizeof(char)); + if (c_name == NULL) + return PyErr_NoMemory(); + + err = git_branch_remote_name(c_name, + err * sizeof(char), + self->repo->repo, + branch_name); + if (err < GIT_OK) { + free(c_name); + return Error_set(err); + } + + PyObject *py_name = to_unicode(c_name, NULL, NULL); + free(c_name); + + return py_name; +} + + PyMethodDef Branch_methods[] = { METHOD(Branch, delete, METH_NOARGS), METHOD(Branch, is_head, METH_NOARGS), @@ -132,6 +170,7 @@ PyMethodDef Branch_methods[] = { PyGetSetDef Branch_getseters[] = { GETTER(Branch, branch_name), + GETTER(Branch, remote_name), {NULL} }; diff --git a/test/test_branch.py b/test/test_branch.py index a1289d7ba..dd2414153 100644 --- a/test/test_branch.py +++ b/test/test_branch.py @@ -140,6 +140,12 @@ def test_listall_branches(self): branches = sorted(self.repo.listall_branches(pygit2.GIT_BRANCH_REMOTE)) self.assertEqual(branches, ['origin/master']) + def test_branch_remote_name(self): + self.repo.remotes[0].fetch() + branch = self.repo.lookup_branch('origin/master', + pygit2.GIT_BRANCH_REMOTE) + self.assertEqual(branch.remote_name, 'origin') + if __name__ == '__main__': unittest.main() From b7490db82f9a2de675c68be8e0493cfcee3ab2e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Rodri=CC=81guez=20Troitin=CC=83o?= Date: Fri, 17 May 2013 23:10:54 +0200 Subject: [PATCH 3/4] Implement Branch.upstream getter and setter. Thanks to @cholin for the help! --- src/branch.c | 55 +++++++++++++++++++++++++++++++++++++++++++++ test/test_branch.py | 18 +++++++++++++++ 2 files changed, 73 insertions(+) diff --git a/src/branch.c b/src/branch.c index a3a3126a0..84a243838 100644 --- a/src/branch.c +++ b/src/branch.c @@ -31,7 +31,10 @@ #include "reference.h" #include "utils.h" + extern PyObject *GitError; +extern PyTypeObject ReferenceType; + PyDoc_STRVAR(Branch_delete__doc__, "delete()\n" @@ -161,6 +164,57 @@ PyObject* Branch_remote_name__get__(Branch *self) } +PyDoc_STRVAR(Branch_upstream__doc__, + "The branch supporting the remote tracking branch or None if this is not a " + "remote tracking branch. Set to None to unset."); + +PyObject* Branch_upstream__get__(Branch *self) +{ + int err; + git_reference *c_reference; + + CHECK_REFERENCE(self); + + err = git_branch_upstream(&c_reference, self->reference); + if (err == GIT_ENOTFOUND) + Py_RETURN_NONE; + else if (err < GIT_OK) + return Error_set(err); + + return wrap_branch(c_reference, self->repo); +} + +int Branch_upstream__set__(Branch *self, Reference *py_ref) +{ + int err; + const char *branch_name = NULL; + + CHECK_REFERENCE_INT(self); + + if ((PyObject *)py_ref != Py_None) { + if (!PyObject_TypeCheck(py_ref, (PyTypeObject *)&ReferenceType)) { + PyErr_SetObject(PyExc_TypeError, (PyObject *)py_ref); + return -1; + } + + CHECK_REFERENCE_INT(py_ref); + err = git_branch_name(&branch_name, py_ref->reference); + if (err < GIT_OK) { + Error_set(err); + return -1; + } + } + + err = git_branch_set_upstream(self->reference, branch_name); + if (err < GIT_OK) { + Error_set(err); + return -1; + } + + return 0; +} + + PyMethodDef Branch_methods[] = { METHOD(Branch, delete, METH_NOARGS), METHOD(Branch, is_head, METH_NOARGS), @@ -171,6 +225,7 @@ PyMethodDef Branch_methods[] = { PyGetSetDef Branch_getseters[] = { GETTER(Branch, branch_name), GETTER(Branch, remote_name), + GETSET(Branch, upstream), {NULL} }; diff --git a/test/test_branch.py b/test/test_branch.py index dd2414153..52ce9ca61 100644 --- a/test/test_branch.py +++ b/test/test_branch.py @@ -146,6 +146,24 @@ def test_branch_remote_name(self): pygit2.GIT_BRANCH_REMOTE) self.assertEqual(branch.remote_name, 'origin') + def test_branch_upstream(self): + self.repo.remotes[0].fetch() + remote_master = self.repo.lookup_branch('origin/master', + pygit2.GIT_BRANCH_REMOTE) + master = self.repo.create_branch('master', + self.repo[remote_master.target.hex]) + + self.assertTrue(master.upstream is None) + master.upstream = remote_master + self.assertEqual(master.upstream.branch_name, 'origin/master') + + def set_bad_upstream(): + master.upstream = 2.5 + self.assertRaises(TypeError, set_bad_upstream) + + master.upstream = None + self.assertTrue(master.upstream is None) + if __name__ == '__main__': unittest.main() From db5b4e90659db3ec006ffc1636a69b57df8947fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Rodri=CC=81guez=20Troitin=CC=83o?= Date: Fri, 17 May 2013 23:13:35 +0200 Subject: [PATCH 4/4] Implement Branch.upstream_name getter. --- src/branch.c | 39 +++++++++++++++++++++++++++++++++++++++ test/test_branch.py | 10 ++++++++++ 2 files changed, 49 insertions(+) diff --git a/src/branch.c b/src/branch.c index 84a243838..48f5bbaab 100644 --- a/src/branch.c +++ b/src/branch.c @@ -215,6 +215,44 @@ int Branch_upstream__set__(Branch *self, Reference *py_ref) } +PyDoc_STRVAR(Branch_upstream_name__doc__, + "The name of the reference supporting the remote tracking branch."); + +PyObject* Branch_upstream_name__get__(Branch *self) +{ + int err; + const char *branch_name; + char *c_name = NULL; + + CHECK_REFERENCE(self); + + branch_name = git_reference_name(self->reference); + // get the length of the upstream name + err = git_branch_upstream_name(NULL, 0, self->repo->repo, branch_name); + if (err < GIT_OK) + return Error_set(err); + + // get the actual upstream name + c_name = calloc(err, sizeof(char)); + if (c_name == NULL) + return PyErr_NoMemory(); + + err = git_branch_upstream_name(c_name, + err * sizeof(char), + self->repo->repo, + branch_name); + if (err < GIT_OK) { + free(c_name); + return Error_set(err); + } + + PyObject *py_name = to_unicode(c_name, NULL, NULL); + free(c_name); + + return py_name; +} + + PyMethodDef Branch_methods[] = { METHOD(Branch, delete, METH_NOARGS), METHOD(Branch, is_head, METH_NOARGS), @@ -226,6 +264,7 @@ PyGetSetDef Branch_getseters[] = { GETTER(Branch, branch_name), GETTER(Branch, remote_name), GETSET(Branch, upstream), + GETTER(Branch, upstream_name), {NULL} }; diff --git a/test/test_branch.py b/test/test_branch.py index 52ce9ca61..8dc62cb1a 100644 --- a/test/test_branch.py +++ b/test/test_branch.py @@ -164,6 +164,16 @@ def set_bad_upstream(): master.upstream = None self.assertTrue(master.upstream is None) + def test_branch_upstream_name(self): + self.repo.remotes[0].fetch() + remote_master = self.repo.lookup_branch('origin/master', + pygit2.GIT_BRANCH_REMOTE) + master = self.repo.create_branch('master', + self.repo[remote_master.target.hex]) + + master.upstream = remote_master + self.assertEqual(master.upstream_name, 'refs/remotes/origin/master') + if __name__ == '__main__': unittest.main()