# `HfHub.Commit`
[🔗](https://github.com/North-Shore-AI/hf_hub_ex/blob/v0.3.1/lib/hf_hub/commit.ex#L1)

Commit operations for uploading files to HuggingFace Hub.

This module provides functions to create commits that add, delete,
or copy files in a repository.

## Upload Modes

Files are uploaded in one of two modes:
- **Regular**: Base64-encoded in commit payload (for files < 10MB)
- **LFS**: Git Large File Storage protocol (for files >= 10MB)

The upload mode is automatically determined based on file size.

## Examples

    # Upload a single file
    {:ok, info} = HfHub.Commit.upload_file(
      "/path/to/model.bin",
      "model.bin",
      "my-org/my-model",
      token: token,
      commit_message: "Add model weights"
    )

    # Create a commit with multiple operations
    {:ok, info} = HfHub.Commit.create("my-model", [
      Operation.add("model.safetensors", "/path/to/model"),
      Operation.add("config.json", config_content),
      Operation.delete("old_model.bin")
    ], token: token, commit_message: "Update model")

# `commit_opts`

```elixir
@type commit_opts() :: [
  token: String.t(),
  repo_type: :model | :dataset | :space,
  revision: String.t(),
  commit_message: String.t(),
  commit_description: String.t(),
  create_pr: boolean(),
  parent_commit: String.t()
]
```

# `create`

```elixir
@spec create(String.t(), [HfHub.Commit.Operation.t()], commit_opts()) ::
  {:ok, HfHub.Commit.CommitInfo.t()} | {:error, term()}
```

Creates a commit with one or more operations.

This is the primary function for making changes to a repository.
Operations can include adding files, deleting files, or copying
existing LFS files.

## Options

- `:token` - Authentication token (required)
- `:repo_type` - Repository type: :model, :dataset, :space (default: :model)
- `:revision` - Target branch (default: "main")
- `:commit_message` - Commit message (required)
- `:commit_description` - Extended commit description
- `:create_pr` - Create a pull request instead of direct commit
- `:parent_commit` - Parent commit SHA for atomic operations

## Examples

    alias HfHub.Commit.Operation

    {:ok, info} = HfHub.Commit.create("my-model", [
      Operation.add("config.json", ~s({"hidden_size": 768})),
      Operation.delete("old_config.json")
    ], token: token, commit_message: "Update config")

# `delete_file`

```elixir
@spec delete_file(String.t(), String.t(), commit_opts()) ::
  {:ok, HfHub.Commit.CommitInfo.t()} | {:error, term()}
```

Deletes a file from a repository.

## Examples

    {:ok, info} = HfHub.Commit.delete_file(
      "old_model.bin",
      "my-model",
      token: token,
      commit_message: "Remove old weights"
    )

# `delete_folder`

```elixir
@spec delete_folder(String.t(), String.t(), commit_opts()) ::
  {:ok, HfHub.Commit.CommitInfo.t()} | {:error, term()}
```

Deletes a folder and all its contents from a repository.

# `lfs_threshold`

```elixir
@spec lfs_threshold() :: non_neg_integer()
```

Returns the LFS size threshold in bytes (10MB).

# `matches_pattern?`

```elixir
@spec matches_pattern?(String.t(), String.t()) :: boolean()
```

Checks if a file path matches a gitignore-style pattern.

## Pattern Syntax

- `*` matches any sequence except `/`
- `**` matches any sequence including `/`
- `?` matches single character
- `[abc]` matches character class

## Examples

    iex> HfHub.Commit.matches_pattern?("file.json", "*.json")
    true

    iex> HfHub.Commit.matches_pattern?("path/to/file.json", "**/*.json")
    true

    iex> HfHub.Commit.matches_pattern?("__pycache__/cache.pyc", "__pycache__/**")
    true

# `needs_lfs?`

```elixir
@spec needs_lfs?(HfHub.Commit.Operation.Add.t()) :: boolean()
```

Determines if a file needs LFS upload based on its size.

# `upload_file`

```elixir
@spec upload_file(binary() | Path.t(), String.t(), String.t(), commit_opts()) ::
  {:ok, HfHub.Commit.CommitInfo.t()} | {:error, term()}
```

Uploads a single file to a repository.

Convenience wrapper around `create/3` for single-file uploads.

## Examples

    # From file path
    {:ok, info} = HfHub.Commit.upload_file(
      "/path/to/model.bin",
      "model.bin",
      "my-model",
      token: token
    )

    # From binary content
    {:ok, info} = HfHub.Commit.upload_file(
      config_json,
      "config.json",
      "my-model",
      token: token,
      commit_message: "Update config"
    )

# `upload_folder`

```elixir
@spec upload_folder(Path.t(), String.t(), commit_opts()) ::
  {:ok, HfHub.Commit.CommitInfo.t()} | {:error, term()}
```

Uploads an entire folder to a repository.

Files are uploaded in batch with automatic LFS detection.
Use patterns to filter which files to include or exclude.

## Options

- `:token` - Authentication token (required)
- `:repo_type` - Repository type (default: :model)
- `:revision` - Target branch (default: "main")
- `:commit_message` - Commit message (default: "Upload folder")
- `:commit_description` - Extended description
- `:create_pr` - Create pull request (default: false)
- `:allow_patterns` - Only include files matching patterns
- `:ignore_patterns` - Exclude files matching patterns
- `:delete_patterns` - Delete remote files matching patterns

## Pattern Syntax

Patterns use gitignore-style matching:
- `*` matches any sequence except `/`
- `**` matches any sequence including `/`
- `?` matches single character
- `[abc]` matches character class

## Examples

    # Upload entire folder
    {:ok, info} = HfHub.Commit.upload_folder(
      "/path/to/model_dir",
      "my-org/my-model",
      token: token
    )

    # With pattern filtering
    {:ok, info} = HfHub.Commit.upload_folder(
      "/path/to/model_dir",
      "my-model",
      token: token,
      ignore_patterns: ["*.pyc", "__pycache__/**", ".git/**"],
      allow_patterns: ["*.safetensors", "*.json"]
    )

    # Delete old files matching pattern
    {:ok, info} = HfHub.Commit.upload_folder(
      "/path/to/model_dir",
      "my-model",
      token: token,
      delete_patterns: ["*.bin"]  # Delete old .bin files, upload new
    )

# `upload_large_folder`

```elixir
@spec upload_large_folder(Path.t(), String.t(), commit_opts()) ::
  {:ok, [HfHub.Commit.CommitInfo.t()]} | {:error, term()}
```

Uploads a large folder using multiple commits if needed.

For folders with many files or large total size, this function
automatically splits the upload into multiple commits.

## Options

Same as `upload_folder/3`, plus:
- `:multi_commits` - Enable automatic splitting (default: false)
- `:multi_commits_verbose` - Log progress (default: false)

## Examples

    {:ok, infos} = HfHub.Commit.upload_large_folder(
      "/path/to/huge_model",
      "my-model",
      token: token,
      multi_commits: true
    )

---

*Consult [api-reference.md](api-reference.md) for complete listing*
