Skip to content

Commit 9068704

Browse files
committed
Merge pull request libgit2#3749 from arthurschreiber/arthur/add-git-reference-dup
Allow creating copies of `git_reference` objects.
2 parents c30955e + 908f24f commit 9068704

File tree

3 files changed

+64
-1
lines changed

3 files changed

+64
-1
lines changed

include/git2/refs.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -461,6 +461,17 @@ GIT_EXTERN(int) git_reference_foreach_name(
461461
git_reference_foreach_name_cb callback,
462462
void *payload);
463463

464+
/**
465+
* Create a copy of an existing reference.
466+
*
467+
* Call `git_reference_free` to free the data.
468+
*
469+
* @param dest pointer where to store the copy
470+
* @param source object to copy
471+
* @return 0 or an error code
472+
*/
473+
GIT_EXTERN(int) git_reference_dup(git_reference **dest, git_reference *source);
474+
464475
/**
465476
* Free the given reference.
466477
*

src/refs.c

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,18 @@ git_reference *git_reference__set_name(
105105
return rewrite;
106106
}
107107

108+
int git_reference_dup(git_reference **dest, git_reference *source)
109+
{
110+
if (source->type == GIT_REF_SYMBOLIC)
111+
*dest = git_reference__alloc_symbolic(source->name, source->target.symbolic);
112+
else
113+
*dest = git_reference__alloc(source->name, &source->target.oid, &source->peel);
114+
115+
GITERR_CHECK_ALLOC(*dest);
116+
117+
return 0;
118+
}
119+
108120
void git_reference_free(git_reference *reference)
109121
{
110122
if (reference == NULL)
@@ -448,7 +460,7 @@ int git_reference_create_matching(
448460
{
449461
int error;
450462
git_signature *who = NULL;
451-
463+
452464
assert(id);
453465

454466
if ((error = git_reference__log_signature(&who, repo)) < 0)

tests/refs/dup.c

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
#include "clar_libgit2.h"
2+
#include "refs.h"
3+
4+
static git_repository *g_repo;
5+
6+
void test_refs_dup__initialize(void)
7+
{
8+
g_repo = cl_git_sandbox_init("testrepo.git");
9+
}
10+
11+
void test_refs_dup__cleanup(void)
12+
{
13+
cl_git_sandbox_cleanup();
14+
}
15+
16+
void test_refs_dup__direct(void)
17+
{
18+
git_reference *a, *b;
19+
20+
cl_git_pass(git_reference_lookup(&a, g_repo, "refs/heads/master"));
21+
cl_git_pass(git_reference_dup(&b, a));
22+
23+
cl_assert(git_reference_cmp(a, b) == 0);
24+
25+
git_reference_free(b);
26+
git_reference_free(a);
27+
}
28+
29+
void test_refs_dup__symbolic(void)
30+
{
31+
git_reference *a, *b;
32+
33+
cl_git_pass(git_reference_lookup(&a, g_repo, "HEAD"));
34+
cl_git_pass(git_reference_dup(&b, a));
35+
36+
cl_assert(git_reference_cmp(a, b) == 0);
37+
38+
git_reference_free(b);
39+
git_reference_free(a);
40+
}

0 commit comments

Comments
 (0)