These allow you to determine whether you're dealing with a branch, tag, note or remote-tracking branch.
132 lines
4.4 KiB
Erlang
132 lines
4.4 KiB
Erlang
-module(geef_ref).
|
|
|
|
-export([lookup/2, iterator/1, iterator/2, next/1, resolve/1, create/4, create_symbolic/4, dwim/2, shorthand/1]).
|
|
-export([has_log/1, has_log/2]).
|
|
-export([is_branch/1, is_tag/1, is_note/1, is_remote/1]).
|
|
|
|
-include("geef_records.hrl").
|
|
|
|
-type iterator() :: #geef_iterator{type :: ref}.
|
|
-type type() :: oid | symbolic.
|
|
-type target() :: binary() | geef_oid:oid().
|
|
-type ref() :: #geef_reference{repo :: pid(), name :: binary()}.
|
|
-export_type([reference/0, type/0, target/0, iterator/0]).
|
|
|
|
-spec create(pid(), iolist(), geef_oid:oid(), boolean()) -> {ok, ref()} | {error, term()}.
|
|
create(Repo, Refname, Target, Force) ->
|
|
RepoHandle = geef_repo:handle(Repo),
|
|
case geef_nif:reference_create(RepoHandle, Refname, oid, Target, Force) of
|
|
ok ->
|
|
{ok, make(Repo, iolist_to_binary(Refname), oid, Target)};
|
|
Err = {error, _} ->
|
|
Err
|
|
end.
|
|
|
|
-spec create_symbolic(pid(), iolist(), iolist(), boolean()) -> {ok, ref()} | {error, term()}.
|
|
create_symbolic(Repo, Refname, Target, Force) ->
|
|
RepoHandle = geef_repo:handle(Repo),
|
|
case geef_nif:reference_create(RepoHandle, Refname, symbolic, Target, Force) of
|
|
ok ->
|
|
{ok, make(Repo, iolist_to_binary(Refname), symbolic, iolist_to_binary(Target))};
|
|
Err = {error, _} ->
|
|
Err
|
|
end.
|
|
|
|
-spec make(pid(), binary(), type(), target()) -> ref().
|
|
make(Repo, Name, oid, Target) ->
|
|
#geef_reference{repo=Repo, name=Name, type=oid, target=Target};
|
|
make(Repo, Name, symbolic, Target) ->
|
|
#geef_reference{repo=Repo, name=Name, type=symbolic, target=Target}.
|
|
|
|
-spec lookup(pid(), iolist()) -> {ok, ref()} | {error, term()}.
|
|
lookup(Repo, Refname) ->
|
|
Name = iolist_to_binary(Refname),
|
|
RepoHandle = geef_repo:handle(Repo),
|
|
case geef_nif:reference_lookup(RepoHandle, Name) of
|
|
{ok, Type, Target} ->
|
|
{ok, make(Repo, Name, Type, Target)};
|
|
Other ->
|
|
Other
|
|
end.
|
|
|
|
-spec iterator(pid(), iolist() | undefined) -> {ok, iterator()} | {error, term()}.
|
|
iterator(Repo, Regexp) ->
|
|
case geef_repo:iterator(Repo, Regexp) of
|
|
{ok, Handle} ->
|
|
{ok, #geef_iterator{type=ref, repo=Repo, regexp=Regexp, handle=Handle}};
|
|
Other ->
|
|
Other
|
|
end.
|
|
|
|
-spec iterator(pid()) -> {ok, iterator()} | {error, term()}.
|
|
iterator(Repo) ->
|
|
iterator(Repo, undefined).
|
|
|
|
-spec next(iterator()) -> {ok, ref()} | {error, term()}.
|
|
next(#geef_iterator{type=ref, repo=Repo, handle=Handle}) ->
|
|
case geef_nif:reference_next(Handle) of
|
|
{ok, Name, Type, Target} ->
|
|
{ok, make(Repo, Name, Type, Target)};
|
|
Other ->
|
|
Other
|
|
end.
|
|
|
|
-spec resolve(ref()) -> {ok, ref()} | {error, term()}.
|
|
resolve(Ref = #geef_reference{type=oid}) ->
|
|
{ok, Ref}; % resolving an oid ref is a no-op, skip going into the NIF
|
|
resolve(#geef_reference{repo=Repo, type=symbolic, target=Name}) ->
|
|
RepoHandle = geef_repo:handle(Repo),
|
|
case geef_nif:reference_resolve(RepoHandle, Name) of
|
|
{ok, ResolvedName, Target} ->
|
|
{ok, make(Repo, ResolvedName, oid, Target)};
|
|
Other = {error, _} ->
|
|
Other
|
|
end.
|
|
|
|
-spec dwim(pid(), iolist()) -> {ok, ref()} | {error, term()}.
|
|
dwim(Repo, Name) ->
|
|
RepoHandle = geef_repo:handle(Repo),
|
|
case geef_nif:reference_dwim(RepoHandle, Name) of
|
|
{ok, RealName, Type, Target} ->
|
|
{ok, make(Repo, RealName, Type, Target)};
|
|
Err = {error, _}->
|
|
Err
|
|
end.
|
|
|
|
%% @doc Get the shorthand name for a particular reference
|
|
-spec shorthand(ref() | binary()) -> binary().
|
|
shorthand(<<"refs/heads/", Rest/binary>>) ->
|
|
Rest;
|
|
shorthand(<<"refs/tags/", Rest/binary>>) ->
|
|
Rest;
|
|
shorthand(<<"refs/remotes/", Rest/binary>>) ->
|
|
Rest;
|
|
shorthand(<<"refs/", Rest/binary>>) ->
|
|
Rest;
|
|
shorthand(#geef_reference{name=Name}) ->
|
|
shorthand(Name).
|
|
|
|
%% @doc Return whether the reference has a reflog
|
|
-spec has_log(pid(), iolist() | binary()) -> {ok, boolean()} | {error, term()}.
|
|
has_log(Repo, Name) ->
|
|
geef_repo:reference_has_log(Repo, Name).
|
|
|
|
-spec has_log(ref()) -> {ok, boolean()} | {error, term()}.
|
|
has_log(#geef_reference{repo=Repo, name=Name}) ->
|
|
has_log(Repo, Name).
|
|
|
|
-define(assert_prefix(FunctionName, Prefix),
|
|
FunctionName(<<Prefix, _/binary>>) ->
|
|
true;
|
|
FunctionName(#geef_reference{name=Name}) ->
|
|
FunctionName(Name);
|
|
FunctionName(Name) when is_list(Name) ->
|
|
FunctionName(iolist_to_binary(Name));
|
|
FunctionName(_) ->
|
|
false).
|
|
|
|
?assert_prefix(is_branch, "refs/heads/").
|
|
?assert_prefix(is_tag, "refs/tags/").
|
|
?assert_prefix(is_note, "refs/notes/").
|
|
?assert_prefix(is_remote, "refs/remotes/").
|