Get rid of the tagged OID

This means we no longer accept any iolist in some of the functions,
but we might bring it back later.

There is also a new function, geef_ref:create_symbolic() to create
symbolic references, since we can no longer differentiate between a
name and an OID.
This commit is contained in:
Carlos Martín Nieto
2013-09-03 20:26:57 +02:00
parent a400d3ca85
commit 0d24afb089
18 changed files with 58 additions and 138 deletions

View File

@@ -96,7 +96,7 @@ ERL_NIF_TERM
geef_index_add(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[])
{
geef_index *index;
const ERL_NIF_TERM *eentry, *oid;
const ERL_NIF_TERM *eentry;
int arity;
ErlNifBinary path, id;
git_index_entry entry;
@@ -122,11 +122,8 @@ geef_index_add(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[])
return geef_oom(env);
entry.path = (char *) path.data;
/* Extract the oid from the tuple */
if (!enif_get_tuple(env, eentry[9], &arity, &oid))
return enif_make_badarg(env);
if (!enif_inspect_binary(env, oid[1], &id))
if (!enif_inspect_binary(env, eentry[9], &id))
return enif_make_badarg(env);
git_oid_fromraw(&entry.oid, id.data);

View File

@@ -376,7 +376,7 @@ geef_reference_create(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[])
geef_repository *repo;
ErlNifBinary name, target;
int error, force;
git_reference *ref;
git_reference *ref = NULL;
const char *pname, *ptarget;
if (!enif_get_resource(env, argv[0], geef_repository_type, (void **) &repo))

View File

@@ -1,22 +1,6 @@
defrecord Geef.Oid, Record.extract(:geef_oid, from: "src/geef_records.hrl") do
alias Geef.Oid
defmodule Geef.Oid do
@doc false
defmacro to_erl(oid) do
quote do
set_elem(unquote(oid), 0, :geef_oid)
end
end
@doc false
defmacro from_erl(oid) do
quote do
set_elem(unquote(oid), 0, Geef.Oid)
end
end
defp maybe_oid({:ok, oid}), do: from_erl(oid)
defp maybe_oid(error = {:error, _}), do: error
@type t :: <<_ :: 160>>
@spec parse(iolist) :: t
def parse(str) do
@@ -24,8 +8,8 @@ defrecord Geef.Oid, Record.extract(:geef_oid, from: "src/geef_records.hrl") do
end
@spec hex(t) :: String.t
def hex(oid = Oid[]) do
:geef_oid.hex(to_erl(oid))
def hex(oid) do
:geef_oid.hex(oid)
end
end

View File

@@ -1,22 +1,9 @@
defrecord Geef.Reference, Record.extract(:geef_reference, from: "src/geef_records.hrl") do
import Geef
alias Geef.Reference
alias Geef.Oid
import Oid, only: :macros
def from_erl(ref) do
case set_elem(ref, 0, Geef.Reference) do
ref = Reference[type: :symbolic] -> ref
ref = Reference[type: :oid, target: oid] -> ref.target(set_elem(oid, 0, Geef.Oid))
end
end
def to_erl(ref = Reference[type: :symbolic]) do
set_elem(ref, 0, :geef_reference)
end
def to_erl(ref = Reference[type: :oid, target: oid]) do
ref |> set_elem(0, :geef_reference) |> set_elem(4, set_elem(oid, 0, :geef_oid))
end
def from_erl(ref), do: set_elem(ref, 0, Geef.Reference)
def to_erl(ref), do: set_elem(ref, 0, :geef_reference)
defp maybe_ref({:ok, ref}), do: {:ok, Reference.from_erl ref}
defp maybe_ref(err = {:error, _}), do: err

View File

@@ -27,7 +27,7 @@ content(#geef_object{type=blob, handle=Handle}) ->
blob_size_test() ->
{ok, Repo} = geef_repo:open(".."),
{ok, Blob} = lookup(Repo, "80d5c15a040c93a4f98f4496a05ebf30cdd58650"),
{ok, Blob} = lookup(Repo, geef_oid:parse("80d5c15a040c93a4f98f4496a05ebf30cdd58650")),
?assertMatch(889, ?MODULE:size(Blob)),
?assertMatch(889, erlang:size(content(Blob))).

View File

@@ -8,8 +8,7 @@
-spec tree_id(commit()) -> geef_oid:oid().
tree_id(#geef_object{type=commit,handle=Handle}) ->
Oid = geef_nif:commit_tree_id(Handle),
#geef_oid{oid=Oid}.
geef_nif:commit_tree_id(Handle).
-spec tree(commit()) -> {ok, geef_tree:tree()} | {error, term()}.
tree(#geef_object{type=commit,handle=Handle}) ->
@@ -20,6 +19,6 @@ tree(#geef_object{type=commit,handle=Handle}) ->
Other
end.
-spec lookup(pid(), geef_oid:oid() | iolist()) -> {ok, commit()} | {error, term()}.
-spec lookup(pid(), geef_oid:oid()) -> {ok, commit()} | {error, term()}.
lookup(Repo, Id) ->
geef_obj:lookup(Repo, Id, commit).

View File

@@ -75,7 +75,7 @@ nth(Pid, Nth) ->
maybe_entry(gen_server:call(Pid, {nth, Nth})).
maybe_entry({ok, Path, Id, Mode, Size}) ->
{ok, #geef_index_entry{path=Path, id=#geef_oid{oid=Id}, mode=Mode, size=Size}};
{ok, #geef_index_entry{path=Path, id=Id, mode=Mode, size=Size}};
maybe_entry(Error = {error, _}) ->
Error.
@@ -107,13 +107,11 @@ handle_call(write, _From, State = #state{handle=Handle}) ->
Reply = geef_nif:index_write(Handle),
{reply, Reply, State};
handle_call(write_tree, _From, State = #state{handle=Handle}) ->
{ok, Oid} = geef_nif:index_write_tree(Handle),
Reply = #geef_oid{oid=Oid},
Reply = geef_nif:index_write_tree(Handle),
{reply, Reply, State};
handle_call({write_tree, Repo}, _From, State = #state{handle=Handle}) ->
RepoHandle = geef_repo:handle(Repo),
{ok, Oid} = geef_nif:index_write_tree(Handle, RepoHandle),
Reply = {ok, #geef_oid{oid=Oid}},
Reply = geef_nif:index_write_tree(Handle, RepoHandle),
{reply, Reply, State};
handle_call(clear, _From, State = #state{handle=Handle}) ->
Reply = geef_nif:index_clear(Handle),

View File

@@ -40,7 +40,7 @@ repository_discover(_Path) ->
reference_list(_Repo) ->
nif_error(?LINE).
-spec reference_create(term(), iolist(), geef_ref:type(), binary(), boolean()) -> ok | {error, term()}.
-spec reference_create(term(), iolist(), geef_ref:type(), iolist() | geef_oid:oid(), boolean()) -> ok | {error, term()}.
reference_create(_Repo, _Refname, _Type, _Target, _Force) ->
?NIF_FN.
@@ -62,7 +62,7 @@ reference_iterator(_Repo, _Regexp) ->
reference_next(_Handle) ->
nif_error(?LINE).
-spec reference_resolve(term(), binary()) -> {ok, geef_ref:type(), binary()} | {error, term()}.
-spec reference_resolve(term(), binary()) -> {ok, binary(), binary()} | {error, term()}.
reference_resolve(_RepoHandle, _Name) ->
nif_error(?LINE).

View File

@@ -14,18 +14,16 @@
-export([lookup/2, lookup/3]).
-spec lookup(pid(), geef_oid:oid() | iolist()) -> {ok, object()} | {error, term()}.
lookup(Repo, Id = #geef_oid{oid=Oid}) ->
case geef_repo:lookup_object(Repo, Oid) of
lookup(Repo, Id) ->
case geef_repo:lookup_object(Repo, Id) of
{ok, Type, Handle} ->
{ok, #geef_object{type=Type, id=Id, handle=Handle}};
{error, Err} ->
{error, Err}
end;
lookup(Repo, Id) ->
lookup(Repo, geef_oid:parse(Id)).
end.
%% As lookup/2, but it asserts that the type is correct
-spec lookup(pid(), geef_oid:oid() | iolist(), atom()) -> {ok, object()} | {error, term()}.
-spec lookup(pid(), geef_oid:oid(), atom()) -> {ok, object()} | {error, term()}.
lookup(Repo, Id, Type) ->
case lookup(Repo, Id) of
{ok, Obj = #geef_object{type=Type}} ->
@@ -38,16 +36,13 @@ lookup(Repo, Id, Type) ->
lookup_test() ->
{ok, Repo} = geef_repo:open(".."),
{ok, #geef_object{type=commit}} = lookup(Repo, geef_oid:parse("b5b68cce8b92ca0e7bd48430617ac10c0f2c2923")),
{ok, #geef_object{type=commit}} = lookup(Repo, "b5b68cce8b92ca0e7bd48430617ac10c0f2c2923"),
{ok, #geef_object{type=commit}} = lookup(Repo, ["b5b68cce8b92ca0e7", "bd48430617ac10c0f2c2923"]),
{ok, #geef_object{type=commit}} = lookup(Repo, <<"b5b68cce8b92ca0e7bd48430617ac10c0f2c2923">>).
{ok, #geef_object{type=commit}} = lookup(Repo, geef_oid:parse("b5b68cce8b92ca0e7bd48430617ac10c0f2c2923")).
id_test() ->
{ok, Repo} = geef_repo:open(".."),
Sha = <<"b5b68cce8b92ca0e7bd48430617ac10c0f2c2923">>,
Id = geef_oid:parse(Sha),
{ok, Commit = #geef_object{type=commit}} = lookup(Repo, Sha),
{ok, Commit = #geef_object{type=commit}} = lookup(Repo, Id),
Id = Commit#geef_object.id.
-endif.

View File

@@ -48,12 +48,7 @@ handle_call({exists, Oid}, _From, State = #state{handle=Handle}) ->
{reply, Reply, State};
handle_call({write, Content, Type}, _From, State = #state{handle=Handle}) ->
Reply = case geef_nif:odb_write(Handle, Content, Type) of
{ok, Oid} ->
{ok, #geef_oid{oid=Oid}};
Other ->
Other
end,
Reply = geef_nif:odb_write(Handle, Content, Type),
{reply, Reply, State};
handle_call(stop, _From, State) ->
@@ -84,12 +79,9 @@ code_change(_OldVsn, State, _Extra) ->
-include_lib("eunit/include/eunit.hrl").
-endif.
-spec exists(pid(), geef_oid:oid() | iolist()) -> boolean().
exists(Pid, #geef_oid{oid=Oid}) ->
gen_server:call(Pid, {exists, Oid});
exists(Pid, Sha) ->
#geef_oid{oid=Oid} = geef_oid:parse(Sha),
gen_server:call(Pid, {exists, Oid}).
-spec exists(pid(), geef_oid:oid()) -> boolean().
exists(Pid, Id) ->
gen_server:call(Pid, {exists, Id}).
-spec write(pid(), iolist(), atom()) -> {ok, geef_oid:oid()} | {error, term()}.
write(Pid, Contents, Type) ->
@@ -100,7 +92,6 @@ write(Pid, Contents, Type) ->
exists_test() ->
{ok, Repo} = geef_repo:open(".."),
{ok, Odb} = geef_repo:odb(Repo),
?assert(exists(Odb, "80d5c15a040c93a4f98f4496a05ebf30cdd58650")),
?assert(exists(Odb, geef_oid:parse("80d5c15a040c93a4f98f4496a05ebf30cdd58650"))).
-endif.

View File

@@ -7,21 +7,20 @@
-include("geef_records.hrl").
-type oid() :: #geef_oid{oid :: binary()}.
-type oid() :: <<_:160>>.
-export_type([oid/0]).
-export([parse/1, hex/1]).
%% @doc Get a hex-encoded string of the hash
-spec hex(geef_oid:oid()) -> binary().
hex(#geef_oid{oid=Oid}) ->
hex(Oid) ->
geef_nif:oid_fmt(Oid).
%% @doc Parse an iolist as a hash
-spec parse(iolist() | binary()) -> geef_oid:oid().
-spec parse(iolist()) -> geef_oid:oid().
parse(Sha) ->
Oid = geef_nif:oid_parse(Sha),
#geef_oid{oid=Oid}.
geef_nif:oid_parse(Sha).
-ifdef(TEST).

View File

@@ -1,5 +1,4 @@
-record(geef_reference, {repo :: pid(), name :: binary(), type :: geef_ref:type(), target :: geef_ref:target()}).
-record(geef_oid, {oid :: binary()}).
-record(geef_object, {type :: atom(), id :: geef_oid:oid(), handle}).
-record(geef_index_entry,
{ctime :: non_neg_integer(), mtime :: non_neg_integer(),

View File

@@ -1,6 +1,6 @@
-module(geef_ref).
-export([lookup/2, iterator/1, iterator/2, next/1, resolve/1, create/4, dwim/2, shorthand/1]).
-export([lookup/2, iterator/1, iterator/2, next/1, resolve/1, create/4, create_symbolic/4, dwim/2, shorthand/1]).
-include("geef_records.hrl").
@@ -10,31 +10,29 @@
-type ref() :: #geef_reference{name :: binary()}.
-export_type([reference/0, type/0, target/0, iterator/0]).
-spec create(pid(), iolist(), target(), boolean()) -> {ok, ref()} | {error, term()}.
-spec create(pid(), iolist(), geef_oid:oid(), boolean()) -> {ok, ref()} | {error, term()}.
create(Repo, Refname, Target, Force) ->
RepoHandle = geef_repo:handle(Repo),
case do_create(RepoHandle, Refname, Target, Force) of
case geef_nif:reference_create(RepoHandle, Refname, oid, Target, Force) of
ok ->
{ok, make(Repo, iolist_to_binary(Refname), Target)};
{ok, make(Repo, iolist_to_binary(Refname), oid, Target)};
Err = {error, _} ->
Err
end.
-spec do_create(term(), iolist(), target(), boolean()) -> ok | {error, term()}.
do_create(RepoHandle, Refname, #geef_oid{oid=Oid}, Force) ->
geef_nif:reference_create(RepoHandle, Refname, oid, Oid, Force);
do_create(RepoHandle, Refname, Target, Force) ->
geef_nif:reference_create(RepoHandle, Refname, symbolic, Target, Force).
-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(), target()) -> ref().
make(Repo, Name, #geef_oid{oid=Oid}) ->
make(Repo, Name, oid, Oid);
make(Repo, Name, Target) ->
make(Repo, Name, symbolic, Target).
-spec make(pid(), binary(), type(), binary()) -> ref().
-spec make(pid(), binary(), type(), target()) -> ref().
make(Repo, Name, oid, Target) ->
#geef_reference{repo=Repo, name=Name, type=oid, target=#geef_oid{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}.

View File

@@ -16,7 +16,7 @@
%% API
-export([open/1, init/2, path/1, workdir/1, odb/1, is_bare/1, references/1, discover/1,
lookup_object/2, lookup_reference/2, create_reference/4, revwalk/1, stop/1,
lookup_object/2, lookup_reference/2, revwalk/1, stop/1,
reference_dwim/2, handle/1, iterator/2]).
-include("geef_records.hrl").
@@ -95,10 +95,6 @@ iterator(Pid, Regexp) ->
reference_dwim(Pid, Name) ->
gen_server:call(Pid, {dwim_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.
revwalk(Pid) ->
gen_server:call(Pid, revwalk).
@@ -147,9 +143,6 @@ handle_call({iterator, Regexp}, _From, State = #state{handle=Handle}) ->
handle_call({dwim_reference, Name}, _From, State = #state{handle=Handle}) ->
Reply = geef_nif:reference_dwim(Handle, Name),
{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) ->
{stop, normal, ok, State};
handle_call(revwalk, _From, State = #state{handle=Handle}) ->
@@ -204,8 +197,3 @@ handle_revwalk(Handle) ->
Error ->
Error
end.
handle_create_reference(Repo, Refname, #geef_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).

View File

@@ -28,22 +28,15 @@
%% @doc Push a commit. This commit and its parents will be included in
%% the walk as long as they haven't been hidden. At least one commit
%% must be pushed before starting a walk.
-spec push(pid(), geef_oid:oid() | iolist()) -> ok | {error, binary()}.
push(Pid, #geef_oid{oid=Oid}) ->
gen_server:call(Pid, {push, Oid});
-spec push(pid(), geef_oid:oid()) -> ok | {error, binary()}.
push(Pid, Id) ->
#geef_oid{oid=Oid} = geef_oid:parse(Id),
gen_server:call(Pid, {push, Oid}).
gen_server:call(Pid, {push, Id}).
%% @doc Hide a commit. Hide a commit and its parents. Any Parent of
%% this commit won't be included in the walk.
-spec hide(pid(), geef_oid:oid() | iolist()) -> ok | {error, binary()}.
hide(Pid, #geef_oid{oid=Oid}) ->
gen_server:call(Pid, {hide, Oid});
-spec hide(pid(), geef_oid:oid()) -> ok | {error, binary()}.
hide(Pid, Id) ->
#geef_oid{oid=Oid} = geef_oid:parse(Id),
gen_server:call(Pid, {hide, Oid}).
gen_server:call(Pid, {hide, Id}).
%% @doc Select the sorting method
@@ -90,7 +83,7 @@ handle_call({hide, Oid}, _From, State = #state{handle=Handle}) ->
Reply = geef_nif:revwalk_push(Handle, Oid, true),
{reply, Reply, State};
handle_call(next, _From, State = #state{handle=Handle}) ->
Reply = handle_next(Handle),
Reply = geef_nif:revwalk_next(Handle),
{reply, Reply, State};
handle_call(stop, _From, State) ->
{stop, normal, ok, State}.
@@ -114,11 +107,3 @@ code_change(_OldVsn, State, _Extra) ->
%%%===================================================================
%%% Internal functions
%%%===================================================================
handle_next(Handle) ->
case geef_nif:revwalk_next(Handle) of
{ok, Oid} ->
{ok, #geef_oid{oid=Oid}};
Other ->
Other
end.

View File

@@ -18,8 +18,8 @@ lookup(Repo, Id) ->
-spec peel(tag()) -> {ok, geef_obj:object()} | {error, term()}.
peel(#geef_object{type=tag, handle=Handle}) ->
case geef_nif:tag_peel(Handle) of
{ok, Type, Oid, PeeledHandle} ->
{ok, #geef_object{type=Type, id=#geef_oid{oid=Oid}, handle=PeeledHandle}};
{ok, Type, Id, PeeledHandle} ->
{ok, #geef_object{type=Type, id=Id, handle=PeeledHandle}};
Err = {error, _} ->
Err
end.

View File

@@ -13,8 +13,8 @@
-export_type([tree/0, entry/0]).
from_nif({ok, Mode, Type, Oid, Name}) ->
{ok, #geef_tree_entry{mode=Mode, type=Type, id=#geef_oid{oid=Oid}, name=Name}};
from_nif({ok, Mode, Type, Id, Name}) ->
{ok, #geef_tree_entry{mode=Mode, type=Type, id=Id, name=Name}};
from_nif(Err = {error, _}) ->
Err.

View File

@@ -44,7 +44,7 @@ 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, _} = geef_ref:create_symbolic(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"),
{ok, Ref2} = geef_ref:resolve(Ref0),
@@ -59,7 +59,7 @@ ref_iter_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, _} = geef_ref:create_symbolic(Repo, "refs/heads/other", "refs/heads/branch", true),
{ok, Iter0} = geef_ref:iterator(Repo),
{ok, Ref0} = geef_ref:next(Iter0),
{ok, Ref1} = geef_ref:next(Iter0),