Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .formatter.exs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Used by "mix format"
[
inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"]
inputs: ["{mix,.formatter}.exs", "{config,lib,test,examples}/**/*.{ex,exs}"]
]
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,15 @@ refetch. Perfect for agent loops that want snapshot semantics.

The on-disk format is a standard bare git repo — `git log`, `git fsck`, and friends all work on it.

There's a runnable worked example at
[`examples/partial_clone_demo.exs`](examples/partial_clone_demo.exs) —
`Mix.install`, partial clone, one file read, with `memory_report/1`
showing `blob_count: 0 -> 1` around the read:

```sh
elixir examples/partial_clone_demo.exs
```

### Private repos

```elixir
Expand Down
32 changes: 32 additions & 0 deletions examples/partial_clone_demo.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Partial clone, worked example.
#
# Clones a public repo under a `blob:none` filter — the server ships
# refs + commits + trees but NO file contents — then reads one file.
# The `blob_count: 0 -> 1` transition around the read is the proof
# that exactly one blob crossed the wire.
#
# Run with: elixir examples/partial_clone_demo.exs

Mix.install([{:exgit, "~> 0.1.0"}])

stats = fn repo ->
Exgit.Repository.memory_report(repo) |> Map.take([:blob_count, :tree_count, :cache_bytes])
end

# Partial clone: refs + commits + trees cross the wire. No file contents.
{:ok, repo} = Exgit.clone("https://github.com/elixir-ai-tools/just_bash", filter: {:blob, :none})
IO.inspect(stats.(repo), label: "after clone ")

# The size probe refuses to fetch — gate on it before pulling big files.
{:error, :not_local} = Exgit.FS.size(repo, "HEAD", "README.md")

# Reading ONE file fetches ONE blob.
{:ok, {_mode, blob}, repo} = Exgit.FS.read_path(repo, "HEAD", "README.md")
first_line = blob.data |> String.split("\n", parts: 2) |> hd()
IO.puts(~s(read README.md: #{byte_size(blob.data)} bytes — "#{first_line}"))
IO.inspect(stats.(repo), label: "after one read")

# Navigation stays free: directory listings come from the local
# trees, so blob_count doesn't move.
{:ok, entries, repo} = Exgit.FS.ls(repo, "HEAD", "")
IO.puts("ls /: #{length(entries)} entries — blob_count still #{stats.(repo).blob_count}")
Loading