Skip to content

Commit 7d9d266

Browse files
committed
implementing merge: merge.rst doc and implementing MergeResult as a simple type that maps git_merge_result to it
1 parent 3cd8fed commit 7d9d266

File tree

4 files changed

+82
-38
lines changed

4 files changed

+82
-38
lines changed

docs/merge.rst

+33
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,37 @@
22
Merge
33
**********************************************************************
44

5+
.. contents::
6+
57
.. automethod:: pygit2.Repository.merge_base
8+
.. automethod:: pygit2.Repository.merge
9+
10+
The merge method
11+
=================
12+
13+
The method does a merge over the current working copy.
14+
It gets an Oid object as a parameter and returns a MergeResult object.
15+
16+
As its name says, it only does the merge, does not commit nor update the
17+
branch reference in the case of a fastforward.
18+
19+
For the moment, the merge does not support options, it will perform the
20+
merge with the default ones defined in GIT_MERGE_OPTS_INIT libgit2 constant.
21+
22+
Example::
23+
24+
>>> branch_head_hex = '5ebeeebb320790caf276b9fc8b24546d63316533'
25+
>>> branch_oid = self.repo.get(branch_head_hex).oid
26+
>>> merge_result = self.repo.merge(branch_oid)
27+
28+
The MergeResult object
29+
======================
30+
31+
Represents the result of a merge and contains this fields:
32+
33+
- is_uptodate: bool, if there wasn't any merge because the repo was already
34+
up to date
35+
- is_fastforward: bool, whether the merge was fastforward or not
36+
- fastforward_oid: Oid, in the case it was a fastforward, this is the
37+
forwarded Oid.
38+
- index: represents the repository index after the merge

src/mergeresult.c

+31-29
Original file line numberDiff line numberDiff line change
@@ -39,26 +39,14 @@ extern PyTypeObject IndexType;
3939
PyObject *
4040
git_merge_result_to_python(git_merge_result *merge_result, Repository *repo)
4141
{
42-
git_oid fastforward_oid;
4342
MergeResult *py_merge_result;
4443

4544
py_merge_result = PyObject_New(MergeResult, &MergeResultType);
45+
if (!py_merge_result)
46+
return NULL;
4647

47-
py_merge_result->is_uptodate = git_merge_result_is_uptodate(merge_result) == GIT_CVAR_TRUE;
48-
49-
if (git_merge_result_is_fastforward(merge_result) == GIT_CVAR_TRUE)
50-
{
51-
py_merge_result->is_fastforward = GIT_CVAR_TRUE;
52-
git_merge_result_fastforward_oid(&fastforward_oid, merge_result);
53-
py_merge_result->fastforward_oid = git_oid_to_python((const git_oid *)&fastforward_oid);
54-
}
55-
else
56-
{
57-
py_merge_result->is_fastforward = GIT_CVAR_FALSE;
58-
py_merge_result->fastforward_oid = NULL;
59-
}
60-
61-
py_merge_result->status = Repository_status(repo);
48+
py_merge_result->result = merge_result;
49+
py_merge_result->repo = repo;
6250

6351
return (PyObject*) py_merge_result;
6452
}
@@ -68,7 +56,7 @@ PyDoc_STRVAR(MergeResult_is_uptodate__doc__, "Is up to date");
6856
PyObject *
6957
MergeResult_is_uptodate__get__(MergeResult *self)
7058
{
71-
if (self->is_uptodate)
59+
if (git_merge_result_is_uptodate(self->result))
7260
Py_RETURN_TRUE;
7361
else
7462
Py_RETURN_FALSE;
@@ -79,7 +67,7 @@ PyDoc_STRVAR(MergeResult_is_fastforward__doc__, "Is fastforward");
7967
PyObject *
8068
MergeResult_is_fastforward__get__(MergeResult *self)
8169
{
82-
if (self->is_fastforward)
70+
if (git_merge_result_is_fastforward(self->result))
8371
Py_RETURN_TRUE;
8472
else
8573
Py_RETURN_FALSE;
@@ -90,29 +78,43 @@ PyDoc_STRVAR(MergeResult_fastforward_oid__doc__, "Fastforward Oid");
9078
PyObject *
9179
MergeResult_fastforward_oid__get__(MergeResult *self)
9280
{
93-
if (self->is_fastforward)
94-
{
95-
Py_INCREF(self->fastforward_oid);
96-
return self->fastforward_oid;
81+
if (git_merge_result_is_fastforward(self->result)) {
82+
git_oid fastforward_oid;
83+
git_merge_result_fastforward_oid(&fastforward_oid, self->result);
84+
return git_oid_to_python((const git_oid *)&fastforward_oid);
9785
}
98-
else
99-
Py_RETURN_NONE;
86+
else Py_RETURN_NONE;
10087
}
10188

102-
PyDoc_STRVAR(MergeResult_status__doc__, "Merge repository status");
89+
PyDoc_STRVAR(MergeResult_index__doc__, "Merge repository index");
10390

10491
PyObject *
105-
MergeResult_status__get__(MergeResult *self)
92+
MergeResult_index__get__(MergeResult *self)
10693
{
107-
Py_INCREF(self->status);
108-
return self->status;
94+
git_index *index;
95+
Index *py_index;
96+
int err;
97+
98+
err = git_repository_index(&index, self->repo->repo);
99+
if (err < 0)
100+
return NULL;
101+
102+
py_index = PyObject_GC_New(Index, &IndexType);
103+
if (!py_index) {
104+
return NULL;
105+
}
106+
107+
py_index->repo = self->repo;
108+
py_index->index = index;
109+
Py_INCREF(py_index);
110+
return (PyObject*) py_index;
109111
}
110112

111113
PyGetSetDef MergeResult_getseters[] = {
112114
GETTER(MergeResult, is_uptodate),
113115
GETTER(MergeResult, is_fastforward),
114116
GETTER(MergeResult, fastforward_oid),
115-
GETTER(MergeResult, status),
117+
GETTER(MergeResult, index),
116118
{NULL},
117119
};
118120

src/repository.c

-1
Original file line numberDiff line numberDiff line change
@@ -621,7 +621,6 @@ Repository_merge(Repository *self, PyObject *py_oid)
621621
py_merge_result = git_merge_result_to_python(merge_result, self);
622622

623623
git_merge_head_free(oid_merge_head);
624-
git_merge_result_free(merge_result);
625624

626625
return py_merge_result;
627626

test/test_repository.py

+18-8
Original file line numberDiff line numberDiff line change
@@ -314,7 +314,7 @@ def test_merge_uptodate(self):
314314
self.assertTrue(merge_result.is_uptodate)
315315
self.assertFalse(merge_result.is_fastforward)
316316
self.assertEquals(None, merge_result.fastforward_oid)
317-
self.assertEquals({}, merge_result.status)
317+
self.assertEquals({}, self.repo.status())
318318

319319
def test_merge_fastforward(self):
320320
branch_head_hex = 'e97b4cfd5db0fb4ebabf4f203979ca4e5d1c7c87'
@@ -325,29 +325,39 @@ def test_merge_fastforward(self):
325325
# Asking twice to assure the reference counting is correct
326326
self.assertEquals(branch_head_hex, merge_result.fastforward_oid.hex)
327327
self.assertEquals(branch_head_hex, merge_result.fastforward_oid.hex)
328-
self.assertEquals({}, merge_result.status)
328+
self.assertEquals({}, self.repo.status())
329329

330330
def test_merge_no_fastforward_no_conflicts(self):
331331
branch_head_hex = '03490f16b15a09913edb3a067a3dc67fbb8d41f1'
332332
branch_oid = self.repo.get(branch_head_hex).oid
333333
merge_result = self.repo.merge(branch_oid)
334334
self.assertFalse(merge_result.is_uptodate)
335335
self.assertFalse(merge_result.is_fastforward)
336-
self.assertEquals(None, merge_result.fastforward_oid)
337336
# Asking twice to assure the reference counting is correct
338-
self.assertEquals({'bye.txt': 1}, merge_result.status)
339-
self.assertEquals({'bye.txt': 1}, merge_result.status)
337+
self.assertEquals(None, merge_result.fastforward_oid)
338+
self.assertEquals(None, merge_result.fastforward_oid)
339+
self.assertEquals({'bye.txt': 1}, self.repo.status())
340+
self.assertEquals({'bye.txt': 1}, self.repo.status())
341+
# Checking the index works as expected
342+
merge_result.index.remove('bye.txt')
343+
merge_result.index.write()
344+
self.assertEquals({'bye.txt': 128}, self.repo.status())
340345

341346
def test_merge_no_fastforward_conflicts(self):
342347
branch_head_hex = '1b2bae55ac95a4be3f8983b86cd579226d0eb247'
343348
branch_oid = self.repo.get(branch_head_hex).oid
344349
merge_result = self.repo.merge(branch_oid)
345350
self.assertFalse(merge_result.is_uptodate)
346351
self.assertFalse(merge_result.is_fastforward)
347-
self.assertEquals(None, merge_result.fastforward_oid)
348352
# Asking twice to assure the reference counting is correct
349-
self.assertEquals({'.gitignore': 132}, merge_result.status)
350-
self.assertEquals({'.gitignore': 132}, merge_result.status)
353+
self.assertEquals(None, merge_result.fastforward_oid)
354+
self.assertEquals(None, merge_result.fastforward_oid)
355+
self.assertEquals({'.gitignore': 132}, self.repo.status())
356+
self.assertEquals({'.gitignore': 132}, self.repo.status())
357+
# Checking the index works as expected
358+
merge_result.index.add('.gitignore')
359+
merge_result.index.write()
360+
self.assertEquals({'.gitignore': 2}, self.repo.status())
351361

352362
def test_merge_invalid_hex(self):
353363
branch_head_hex = '12345678'

0 commit comments

Comments
 (0)