From b684645ead29b00e42d23c6ae87b7c6a14947139 Mon Sep 17 00:00:00 2001 From: EdmondFrank Date: Sat, 22 Oct 2022 21:24:20 +0800 Subject: [PATCH] Trying to fix a non-existent HEAD --- apps/gitrekt/c_src/geef.c | 1 + apps/gitrekt/c_src/repository.c | 26 +++++++++++++++++++++++++- apps/gitrekt/c_src/repository.h | 1 + apps/gitrekt/lib/gitrekt/git.ex | 8 ++++++++ apps/gitrekt/lib/gitrekt/git_agent.ex | 11 ++++++++++- 5 files changed, 45 insertions(+), 2 deletions(-) diff --git a/apps/gitrekt/c_src/geef.c b/apps/gitrekt/c_src/geef.c index 60b99d01..65e5da8c 100644 --- a/apps/gitrekt/c_src/geef.c +++ b/apps/gitrekt/c_src/geef.c @@ -313,6 +313,7 @@ static ErlNifFunc geef_funcs[] = {"repository_get_odb", 1, geef_repository_odb, 0}, {"repository_get_index", 1, geef_repository_index, 0}, {"repository_get_config", 1, geef_repository_config, 0}, + {"repository_set_head", 2, geef_repository_set_head, 0}, {"odb_object_hash", 2, geef_odb_hash, 0}, {"odb_object_exists?", 2, geef_odb_exists, 0}, {"odb_read", 2, geef_odb_read, 0}, diff --git a/apps/gitrekt/c_src/repository.c b/apps/gitrekt/c_src/repository.c index da901a62..e8163d99 100644 --- a/apps/gitrekt/c_src/repository.c +++ b/apps/gitrekt/c_src/repository.c @@ -238,4 +238,28 @@ geef_repository_index(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) enif_release_resource(index); return enif_make_tuple2(env, atoms.ok, term_index); -} \ No newline at end of file +} + +ERL_NIF_TERM +geef_repository_set_head(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) +{ + int error; + geef_repository *repo; + ErlNifBinary bin; + + if (!enif_get_resource(env, argv[0], geef_repository_type, (void **)&repo)) + return enif_make_badarg(env); + + if (!enif_inspect_binary(env, argv[1], &bin)) + return enif_make_badarg(env); + + if (!geef_terminate_binary(&bin)) + return geef_oom(env); + + error = git_repository_set_head(repo->repo, (char *)bin.data); + enif_release_binary(&bin); + if (error < 0) + return geef_error_struct(env, error); + + return atoms.ok; +} diff --git a/apps/gitrekt/c_src/repository.h b/apps/gitrekt/c_src/repository.h index 8d8fbb2e..c317f45b 100644 --- a/apps/gitrekt/c_src/repository.h +++ b/apps/gitrekt/c_src/repository.h @@ -16,6 +16,7 @@ ERL_NIF_TERM geef_repository_is_empty(ErlNifEnv *env, int argc, const ERL_NIF_TE ERL_NIF_TERM geef_repository_odb(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]); ERL_NIF_TERM geef_repository_index(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]); ERL_NIF_TERM geef_repository_config(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]); +ERL_NIF_TERM geef_repository_set_head(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]); void geef_repository_free(ErlNifEnv *env, void *cd); diff --git a/apps/gitrekt/lib/gitrekt/git.ex b/apps/gitrekt/lib/gitrekt/git.ex index 192cfed0..f0363286 100644 --- a/apps/gitrekt/lib/gitrekt/git.ex +++ b/apps/gitrekt/lib/gitrekt/git.ex @@ -379,6 +379,14 @@ defmodule GitRekt.Git do raise Code.LoadError, file: nif_path() <> ".so" end + @doc """ + Make the `repo` HEAD point to the specified reference. + """ + @spec repository_set_head(repo, binary) :: :ok | {:error, term} + def repository_set_head(_repo, _refname) do + raise Code.LoadError, file: nif_path() <> ".so" + end + @doc """ Initializes a new repository at the given `path`. """ diff --git a/apps/gitrekt/lib/gitrekt/git_agent.ex b/apps/gitrekt/lib/gitrekt/git_agent.ex index f69e44b6..d98b32a5 100644 --- a/apps/gitrekt/lib/gitrekt/git_agent.ex +++ b/apps/gitrekt/lib/gitrekt/git_agent.ex @@ -755,7 +755,16 @@ defmodule GitRekt.GitAgent do {:ok, name, shorthand, oid} -> {:ok, resolve_reference({name, shorthand, :oid, oid})} {:error, reason} -> - {:error, reason} + case Git.reference_stream(handle, "refs/heads/*") do + {:ok, stream} -> + with %GitRef{name: name} = + ref <- Enum.at(Stream.map(stream, &resolve_reference_peel!(&1, :undefined, handle)), 0), + :ok <- Git.repository_set_head(handle, "refs/heads/#{name}") do + {:ok, ref} + end || {:error, reason} + {:error, reason} -> + {:error, reason} + end end end