Current section
Files
Jump to
Current section
Files
lib/xgit/repository/on_disk.ex
defmodule Xgit.Repository.OnDisk do
@moduledoc ~S"""
Implementation of `Xgit.Repository` that stores content on the local file system.
_IMPORTANT NOTE:_ This is intended as a reference implementation largely
for testing purposes and may not necessarily handle all of the edge cases that
the traditional `git` command-line interface will handle.
That said, it does intentionally use the same `.git` folder format as command-line
`git` so that results may be compared for similar operations.
"""
use Xgit.Repository
@doc ~S"""
Start an on-disk git repository.
Use the functions in `Xgit.Repository` to interact with this repository process.
## Options
* `:work_dir` (required): Top-level working directory. A `.git` directory should
exist at this path. Use `create/1` to create an empty on-disk repository if
necessary.
Any other options are passed through to `GenServer.start_link/3`.
## Return Value
See `GenServer.start_link/3`.
"""
@spec start_link(opts :: Keyword.t()) :: GenServer.on_start()
def start_link(opts \\ []), do: Repository.start_link(__MODULE__, opts, opts)
@impl true
def init(opts) when is_list(opts) do
# TO DO: Be smarter about bare repos and non-standard git_dir locations.
# https://github.com/elixir-git/xgit/issues/44
with {:work_dir_arg, work_dir} when is_binary(work_dir) <-
{:work_dir_arg, Keyword.get(opts, :work_dir)},
{:work_dir, true} <- {:work_dir, File.dir?(work_dir)},
git_dir <- Path.join(work_dir, ".git"),
{:git_dir, true} <- {:git_dir, File.dir?(git_dir)} do
{:ok, %{work_dir: work_dir, git_dir: git_dir}}
else
{:work_dir_arg, _} -> {:stop, :missing_arguments}
{:work_dir, _} -> {:stop, :work_dir_doesnt_exist}
{:git_dir, _} -> {:stop, :git_dir_doesnt_exist}
end
end
@doc ~S"""
Creates a new, empty git repository on the local file system.
Analogous to [`git init`](https://git-scm.com/docs/git-init).
_NOTE:_ We use the name `create` here so as to avoid a naming conflict with
`c:GenServer.init/1`.
## Parameters
`work_dir` (String) is the top-level working directory. A `.git` directory is
created inside this directory.
## Return Value
`:ok` if created successfully.
`{:error, "reason"}` if not.
"""
@spec create(work_dir :: String.t()) :: :ok | {:error, reason :: String.t()}
defdelegate create(work_dir), to: Xgit.Repository.OnDisk.Create
@impl true
defdelegate handle_put_loose_object(state, object),
to: Xgit.Repository.OnDisk.PutLooseObject
end