Allow creation of refs
This commit is contained in:
@@ -128,6 +128,7 @@ static ErlNifFunc geef_funcs[] =
|
|||||||
{"reference_resolve", 1, geef_reference_resolve},
|
{"reference_resolve", 1, geef_reference_resolve},
|
||||||
{"reference_target", 1, geef_reference_target},
|
{"reference_target", 1, geef_reference_target},
|
||||||
{"reference_type", 1, geef_reference_type},
|
{"reference_type", 1, geef_reference_type},
|
||||||
|
{"reference_create", 5, geef_reference_create},
|
||||||
{"oid_fmt", 1, geef_oid_fmt},
|
{"oid_fmt", 1, geef_oid_fmt},
|
||||||
{"oid_parse", 1, geef_oid_parse},
|
{"oid_parse", 1, geef_oid_parse},
|
||||||
{"object_lookup", 2, geef_object_lookup},
|
{"object_lookup", 2, geef_object_lookup},
|
||||||
|
|||||||
@@ -246,3 +246,58 @@ geef_reference_type(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[])
|
|||||||
|
|
||||||
return term_type;
|
return term_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ERL_NIF_TERM
|
||||||
|
geef_reference_create(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[])
|
||||||
|
{
|
||||||
|
geef_repository *repo;
|
||||||
|
geef_ref *ref;
|
||||||
|
ErlNifBinary name, target;
|
||||||
|
ERL_NIF_TERM term_ref;
|
||||||
|
int error, force;
|
||||||
|
const char *pname, *ptarget;
|
||||||
|
|
||||||
|
if (!enif_get_resource(env, argv[0], geef_repository_type, (void **) &repo))
|
||||||
|
return enif_make_badarg(env);
|
||||||
|
|
||||||
|
if (!enif_inspect_iolist_as_binary(env, argv[1], &name))
|
||||||
|
return enif_make_badarg(env);
|
||||||
|
|
||||||
|
if (!enif_inspect_iolist_as_binary(env, argv[3], &target))
|
||||||
|
return enif_make_badarg(env);
|
||||||
|
|
||||||
|
/* Allocate the extra byte for the NUL terminator */
|
||||||
|
if (!enif_realloc_binary(&name, name.size + 1))
|
||||||
|
return atoms.error;
|
||||||
|
|
||||||
|
name.data[name.size-1] = '\0';
|
||||||
|
|
||||||
|
ref = enif_alloc_resource(geef_ref_type, sizeof(geef_ref));
|
||||||
|
|
||||||
|
force = enif_is_identical(argv[4], atoms.true);
|
||||||
|
|
||||||
|
pname = (const char *) name.data;
|
||||||
|
if (enif_is_identical(argv[2], atoms.oid)) {
|
||||||
|
const git_oid *oid = (const git_oid *) target.data;
|
||||||
|
error = git_reference_create(&ref->ref, repo->repo, pname, oid, force);
|
||||||
|
} else if (enif_is_identical(argv[2], atoms.symbolic)) {
|
||||||
|
/* Allocate the extra byte for the NUL terminator */
|
||||||
|
if (!enif_realloc_binary(&target, target.size + 1))
|
||||||
|
return atoms.error;
|
||||||
|
|
||||||
|
target.data[target.size - 1] = '\0';
|
||||||
|
ptarget = (const char *) target.data;
|
||||||
|
error = git_reference_symbolic_create(&ref->ref, repo->repo, pname, ptarget, force);
|
||||||
|
} else {
|
||||||
|
return enif_make_badarg(env);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (error < 0)
|
||||||
|
return geef_error(env);
|
||||||
|
|
||||||
|
term_ref = enif_make_resource(env, ref);
|
||||||
|
enif_release_resource(ref);
|
||||||
|
|
||||||
|
return enif_make_tuple2(env, atoms.ok, term_ref);
|
||||||
|
|
||||||
|
}
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ ERL_NIF_TERM geef_reference_lookup(ErlNifEnv *env, int argc, const ERL_NIF_TERM
|
|||||||
ERL_NIF_TERM geef_reference_resolve(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]);
|
ERL_NIF_TERM geef_reference_resolve(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]);
|
||||||
ERL_NIF_TERM geef_reference_target(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]);
|
ERL_NIF_TERM geef_reference_target(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]);
|
||||||
ERL_NIF_TERM geef_reference_type(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]);
|
ERL_NIF_TERM geef_reference_type(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]);
|
||||||
|
ERL_NIF_TERM geef_reference_create(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]);
|
||||||
|
|
||||||
void geef_ref_free(ErlNifEnv *env, void *cd);
|
void geef_ref_free(ErlNifEnv *env, void *cd);
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
%%% NIF functions, not to be used directly.
|
%%% NIF functions, not to be used directly.
|
||||||
|
|
||||||
-module(geef_nif).
|
-module(geef_nif).
|
||||||
-export([reference_list/1,
|
-export([reference_list/1, reference_create/5,
|
||||||
reference_to_id/2, reference_glob/2, reference_lookup/2, reference_resolve/1,
|
reference_to_id/2, reference_glob/2, reference_lookup/2, reference_resolve/1,
|
||||||
reference_target/1, reference_type/1, odb_object_exists/2, odb_write/3]).
|
reference_target/1, reference_type/1, odb_object_exists/2, odb_write/3]).
|
||||||
|
|
||||||
@@ -60,6 +60,9 @@ repository_discover(_Path) ->
|
|||||||
reference_list(_Repo) ->
|
reference_list(_Repo) ->
|
||||||
nif_error(?LINE).
|
nif_error(?LINE).
|
||||||
|
|
||||||
|
reference_create(_Repo, _Refname, _Type, _Target, _Force) ->
|
||||||
|
?NIF_FN.
|
||||||
|
|
||||||
reference_to_id(_Repo, _Refname) ->
|
reference_to_id(_Repo, _Refname) ->
|
||||||
nif_error(?LINE).
|
nif_error(?LINE).
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
-module(geef_ref).
|
-module(geef_ref).
|
||||||
|
|
||||||
-export([lookup/2, resolve/1, target/1, name_to_id/2]).
|
-export([lookup/2, resolve/1, target/1, name_to_id/2, create/4]).
|
||||||
|
|
||||||
-include("geef_records.hrl").
|
-include("geef_records.hrl").
|
||||||
|
|
||||||
@@ -16,6 +16,12 @@ new(Handle) ->
|
|||||||
end,
|
end,
|
||||||
#ref{handle=Handle, type=Type, target=Target}.
|
#ref{handle=Handle, type=Type, target=Target}.
|
||||||
|
|
||||||
|
-spec create(pid(), iolist(), oid() | binary(), boolean()) -> {ok, ref()} | {error, term()}
|
||||||
|
.
|
||||||
|
create(Repo, Refname, Target, Force) ->
|
||||||
|
{ok, Ref} = geef_repo:create_reference(Repo, Refname, Target, Force),
|
||||||
|
{ok, new(Ref)}.
|
||||||
|
|
||||||
-spec lookup(pid(), iolist()) -> {ok, ref()} | {error, term()}.
|
-spec lookup(pid(), iolist()) -> {ok, ref()} | {error, term()}.
|
||||||
lookup(Repo, Refname) ->
|
lookup(Repo, Refname) ->
|
||||||
case geef_repo:lookup_reference(Repo, Refname) of
|
case geef_repo:lookup_reference(Repo, Refname) of
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
%% API
|
%% API
|
||||||
-export([open/1, init/2, path/1, workdir/1, odb/1, is_bare/1, references/1, discover/1,
|
-export([open/1, init/2, path/1, workdir/1, odb/1, is_bare/1, references/1, discover/1,
|
||||||
lookup_object/2, lookup_reference/2, revwalk/1, stop/1, handle/1]).
|
lookup_object/2, lookup_reference/2, create_reference/4, revwalk/1, stop/1, handle/1]).
|
||||||
|
|
||||||
-include("geef_records.hrl").
|
-include("geef_records.hrl").
|
||||||
-record(state, {handle}).
|
-record(state, {handle}).
|
||||||
@@ -85,6 +85,10 @@ lookup_object(Pid, Oid) ->
|
|||||||
lookup_reference(Pid, Name) ->
|
lookup_reference(Pid, Name) ->
|
||||||
gen_server:call(Pid, {lookup_reference, Name}).
|
gen_server:call(Pid, {lookup_reference, Name}).
|
||||||
|
|
||||||
|
%% @private
|
||||||
|
create_reference(Pid, Name, Target, Force) ->
|
||||||
|
gen_server:call(Pid, {create_reference, Name, Target, Force}).
|
||||||
|
|
||||||
%% @doc Create a revision walker for the given repository.
|
%% @doc Create a revision walker for the given repository.
|
||||||
revwalk(Pid) ->
|
revwalk(Pid) ->
|
||||||
gen_server:call(Pid, revwalk).
|
gen_server:call(Pid, revwalk).
|
||||||
@@ -127,6 +131,9 @@ handle_call({lookup_object, Oid}, _From, State = #state{handle=Handle}) ->
|
|||||||
handle_call({lookup_reference, Name}, _From, State = #state{handle=Handle}) ->
|
handle_call({lookup_reference, Name}, _From, State = #state{handle=Handle}) ->
|
||||||
Reply = geef_nif:reference_lookup(Handle, Name),
|
Reply = geef_nif:reference_lookup(Handle, Name),
|
||||||
{reply, Reply, State};
|
{reply, Reply, State};
|
||||||
|
handle_call({create_reference, Name, Target, Force}, _From, State = #state{handle=Handle}) ->
|
||||||
|
Reply = handle_create_reference(Handle, Name, Target, Force),
|
||||||
|
{reply, Reply, State};
|
||||||
handle_call(stop, _From, State) ->
|
handle_call(stop, _From, State) ->
|
||||||
{stop, normal, ok, State};
|
{stop, normal, ok, State};
|
||||||
handle_call(revwalk, _From, State = #state{handle=Handle}) ->
|
handle_call(revwalk, _From, State = #state{handle=Handle}) ->
|
||||||
@@ -182,3 +189,8 @@ handle_revwalk(Handle) ->
|
|||||||
Error ->
|
Error ->
|
||||||
Error
|
Error
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
handle_create_reference(Repo, Refname, #oid{oid=Oid}, Force) ->
|
||||||
|
geef_nif:reference_create(Repo, Refname, oid, Oid, Force);
|
||||||
|
handle_create_reference(Repo, Refname, Target, Force) ->
|
||||||
|
geef_nif:reference_create(Repo, Refname, symbolic, Target, Force).
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
-include_lib("eunit/include/eunit.hrl").
|
-include_lib("eunit/include/eunit.hrl").
|
||||||
|
|
||||||
repo_test_() ->
|
repo_test_() ->
|
||||||
{foreach, fun start/0, fun stop/1, [fun bare_test/1, fun odb_write_test/1]}.
|
{foreach, fun start/0, fun stop/1, [fun bare_test/1, fun odb_write_test/1, fun create_ref_test/1]}.
|
||||||
|
|
||||||
start() ->
|
start() ->
|
||||||
{A, B, C} = now(),
|
{A, B, C} = now(),
|
||||||
@@ -22,5 +22,15 @@ odb_write_test(Repo) ->
|
|||||||
Expected = geef_oid:parse("c300118399f01fe52b316061b5d32beb27e0adfd"),
|
Expected = geef_oid:parse("c300118399f01fe52b316061b5d32beb27e0adfd"),
|
||||||
[?_assertEqual(Actual, Expected)].
|
[?_assertEqual(Actual, Expected)].
|
||||||
|
|
||||||
|
create_ref_test(Repo) ->
|
||||||
|
odb_write_test(Repo),
|
||||||
|
Id = geef_oid:parse("c300118399f01fe52b316061b5d32beb27e0adfd"),
|
||||||
|
{ok, _} = geef_ref:create(Repo, "refs/heads/branch", Id, true),
|
||||||
|
{ok, _} = geef_ref:create(Repo, "refs/heads/other", "refs/heads/branch", true),
|
||||||
|
{ok, Ref0} = geef_ref:lookup(Repo, "refs/heads/branch"),
|
||||||
|
{ok, Ref1} = geef_ref:lookup(Repo, "refs/heads/other"),
|
||||||
|
[?_assertEqual(geef_ref:target(Ref0), Id),
|
||||||
|
?_assertEqual(geef_ref:target(Ref1), <<"refs/heads/branch">>)].
|
||||||
|
|
||||||
stop(Repo) ->
|
stop(Repo) ->
|
||||||
geef_repo:stop(Repo).
|
geef_repo:stop(Repo).
|
||||||
|
|||||||
Reference in New Issue
Block a user