Skip to content

Commit 98dd6eb

Browse files
Add Reference.raw_target()
1 parent a66245d commit 98dd6eb

File tree

2 files changed

+61
-12
lines changed

2 files changed

+61
-12
lines changed

src/reference.c

Lines changed: 44 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,23 @@ Reference_resolve(Reference *self, PyObject *args)
263263
}
264264

265265

266+
static PyObject *
267+
Reference_target_impl(Reference *self, const char ** c_name)
268+
{
269+
CHECK_REFERENCE(self);
270+
271+
/* Case 1: Direct */
272+
if (GIT_REF_OID == git_reference_type(self->reference))
273+
return git_oid_to_python(git_reference_target(self->reference));
274+
275+
/* Case 2: Symbolic */
276+
*c_name = git_reference_symbolic_target(self->reference);
277+
if (*c_name == NULL)
278+
PyErr_SetString(PyExc_ValueError, "no target available");
279+
280+
return NULL;
281+
}
282+
266283
PyDoc_STRVAR(Reference_target__doc__,
267284
"The reference target: If direct the value will be an Oid object, if it\n"
268285
"is symbolic it will be an string with the full name of the target\n"
@@ -271,21 +288,35 @@ PyDoc_STRVAR(Reference_target__doc__,
271288
PyObject *
272289
Reference_target__get__(Reference *self)
273290
{
274-
const char * c_name;
291+
const char * c_name = NULL;
292+
PyObject * ret;
293+
294+
ret = Reference_target_impl(self, &c_name);
295+
if (ret != NULL)
296+
return ret;
297+
if (c_name != NULL)
298+
return to_path(c_name);
299+
return NULL;
300+
}
275301

276-
CHECK_REFERENCE(self);
277302

278-
/* Case 1: Direct */
279-
if (GIT_REF_OID == git_reference_type(self->reference))
280-
return git_oid_to_python(git_reference_target(self->reference));
303+
PyDoc_STRVAR(Reference_raw_target__doc__,
304+
"The raw reference target: If direct the value will be an Oid object, if it\n"
305+
"is symbolic it will be bytes with the full name of the target\n"
306+
"reference.\n");
281307

282-
/* Case 2: Symbolic */
283-
c_name = git_reference_symbolic_target(self->reference);
284-
if (c_name == NULL) {
285-
PyErr_SetString(PyExc_ValueError, "no target available");
286-
return NULL;
287-
}
288-
return to_path(c_name);
308+
PyObject *
309+
Reference_raw_target__get__(Reference *self)
310+
{
311+
const char * c_name = NULL;
312+
PyObject * ret;
313+
314+
ret = Reference_target_impl(self, &c_name);
315+
if (ret != NULL)
316+
return ret;
317+
if (c_name != NULL)
318+
return PyBytes_FromString(c_name);
319+
return NULL;
289320
}
290321

291322
PyDoc_STRVAR(Reference_set_target__doc__,
@@ -634,6 +665,7 @@ PyGetSetDef Reference_getseters[] = {
634665
GETTER(Reference, shorthand),
635666
GETTER(Reference, raw_shorthand),
636667
GETTER(Reference, target),
668+
GETTER(Reference, raw_target),
637669
GETTER(Reference, type),
638670
{NULL}
639671
};

test/test_refs.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ def test_refs_list(testrepo):
5656
def test_head(testrepo):
5757
head = testrepo.head
5858
assert LAST_COMMIT == testrepo[head.target].hex
59+
assert LAST_COMMIT == testrepo[head.raw_target].hex
5960

6061
def test_refs_getitem(testrepo):
6162
refname = 'refs/foo'
@@ -92,12 +93,15 @@ def test_refs_get_type(testrepo):
9293
def test_refs_get_target(testrepo):
9394
reference = testrepo.references.get('HEAD')
9495
assert reference.target == 'refs/heads/master'
96+
assert reference.raw_target == b'refs/heads/master'
9597

9698
def test_refs_set_target(testrepo):
9799
reference = testrepo.references.get('HEAD')
98100
assert reference.target == 'refs/heads/master'
101+
assert reference.raw_target == b'refs/heads/master'
99102
reference.set_target('refs/heads/i18n')
100103
assert reference.target == 'refs/heads/i18n'
104+
assert reference.raw_target == b'refs/heads/i18n'
101105

102106
def test_refs_get_shorthand(testrepo):
103107
reference = testrepo.references.get('refs/heads/master')
@@ -108,11 +112,13 @@ def test_refs_get_shorthand(testrepo):
108112
def test_refs_set_target_with_message(testrepo):
109113
reference = testrepo.references.get('HEAD')
110114
assert reference.target == 'refs/heads/master'
115+
assert reference.raw_target == b'refs/heads/master'
111116
sig = Signature('foo', 'bar')
112117
testrepo.set_ident('foo', 'bar')
113118
msg = 'Hello log'
114119
reference.set_target('refs/heads/i18n', message=msg)
115120
assert reference.target == 'refs/heads/i18n'
121+
assert reference.raw_target == b'refs/heads/i18n'
116122
first = list(reference.log())[0]
117123
assert first.message == msg
118124
assert first.committer == sig
@@ -188,6 +194,7 @@ def test_refs_create_symbolic(testrepo):
188194
reference = testrepo.references.create('refs/tags/beta', 'refs/heads/master')
189195
assert reference.type == GIT_REF_SYMBOLIC
190196
assert reference.target == 'refs/heads/master'
197+
assert reference.raw_target == b'refs/heads/master'
191198

192199
# try to create existing symbolic reference
193200
with pytest.raises(ValueError):
@@ -198,6 +205,7 @@ def test_refs_create_symbolic(testrepo):
198205
force=True)
199206
assert reference.type == GIT_REF_SYMBOLIC
200207
assert reference.target == 'refs/heads/master'
208+
assert reference.raw_target == b'refs/heads/master'
201209

202210
#def test_packall_references(testrepo):
203211
# testrepo.packall_references()
@@ -206,6 +214,7 @@ def test_refs_create_symbolic(testrepo):
206214
def test_refs_peel(testrepo):
207215
ref = testrepo.references.get('refs/heads/master')
208216
assert testrepo[ref.target].id == ref.peel().id
217+
assert testrepo[ref.raw_target].id == ref.peel().id
209218

210219
commit = ref.peel(Commit)
211220
assert commit.tree.id == ref.peel(Tree).id
@@ -359,12 +368,15 @@ def test_reference_get_type(testrepo):
359368
def test_get_target(testrepo):
360369
reference = testrepo.lookup_reference('HEAD')
361370
assert reference.target == 'refs/heads/master'
371+
assert reference.raw_target == b'refs/heads/master'
362372

363373
def test_set_target(testrepo):
364374
reference = testrepo.lookup_reference('HEAD')
365375
assert reference.target == 'refs/heads/master'
376+
assert reference.raw_target == b'refs/heads/master'
366377
reference.set_target('refs/heads/i18n')
367378
assert reference.target == 'refs/heads/i18n'
379+
assert reference.raw_target == b'refs/heads/i18n'
368380

369381
def test_get_shorthand(testrepo):
370382
reference = testrepo.lookup_reference('refs/heads/master')
@@ -375,11 +387,13 @@ def test_get_shorthand(testrepo):
375387
def test_set_target_with_message(testrepo):
376388
reference = testrepo.lookup_reference('HEAD')
377389
assert reference.target == 'refs/heads/master'
390+
assert reference.raw_target == b'refs/heads/master'
378391
sig = Signature('foo', 'bar')
379392
testrepo.set_ident('foo', 'bar')
380393
msg = 'Hello log'
381394
reference.set_target('refs/heads/i18n', message=msg)
382395
assert reference.target == 'refs/heads/i18n'
396+
assert reference.raw_target == b'refs/heads/i18n'
383397
first = list(reference.log())[0]
384398
assert first.message == msg
385399
assert first.committer == sig
@@ -465,6 +479,7 @@ def test_create_symbolic_reference(testrepo):
465479
'refs/heads/master')
466480
assert reference.type == GIT_REF_SYMBOLIC
467481
assert reference.target == 'refs/heads/master'
482+
assert reference.raw_target == b'refs/heads/master'
468483

469484
# try to create existing symbolic reference
470485
with pytest.raises(AlreadyExistsError) as error:
@@ -476,6 +491,7 @@ def test_create_symbolic_reference(testrepo):
476491
'refs/heads/master', force=True)
477492
assert reference.type == GIT_REF_SYMBOLIC
478493
assert reference.target == 'refs/heads/master'
494+
assert reference.raw_target == b'refs/heads/master'
479495

480496
def test_create_invalid_reference(testrepo):
481497
repo = testrepo
@@ -493,6 +509,7 @@ def test_peel(testrepo):
493509
repo = testrepo
494510
ref = repo.lookup_reference('refs/heads/master')
495511
assert repo[ref.target].id == ref.peel().id
512+
assert repo[ref.raw_target].id == ref.peel().id
496513

497514
commit = ref.peel(Commit)
498515
assert commit.tree.id == ref.peel(Tree).id

0 commit comments

Comments
 (0)