|
| 1 | +# 📋 `git-metadata` |
| 2 | + |
| 3 | +*Porcelain for adding metadata to any object without rewriting history.* |
| 4 | + |
| 5 | +<!-- rumdl-disable MD013 --> |
| 6 | +[](https://github.com/git-ents/git-metadata/actions/workflows/CI.yml) [](https://github.com/git-ents/git-metadata/actions/workflows/CD.yml) |
| 7 | +<!-- rumdl-enable MD013 --> |
| 8 | + |
| 9 | +> [!CAUTION] |
| 10 | +> This project is in active development. |
| 11 | +> There are surely bugs and misbehaviors that have not yet been discovered. |
| 12 | +> Please file a [new issue] for any misbehaviors you find! |
| 13 | +
|
| 14 | +[new issue]: https://github.com/git-ents/git-metadata/issues/new |
| 15 | + |
| 16 | +## Overview |
| 17 | + |
| 18 | +To support a more expansive usage of the Git object database — as is the goal for other projects within the [`git-ents`](https://github.com/git-ents) organization — new tooling is needed. |
| 19 | +This project provides a command that allows users to associate arbitrary data to any object in Git's store. |
| 20 | +The `metadata` command follows `notes` semantics. |
| 21 | + |
| 22 | +[Notes] are a tragically underutilized feature of Git. |
| 23 | +For more information about `git notes` entries, Tyler Cipriani's [blog post] is an excellent introduction, and some highly-motivating examples. |
| 24 | +One such example is Google's open-source [`git-appraise`] project, which stores code review metadata as structured entries in a note blob. |
| 25 | +While impressive, that design highlights a limitation of notes: structured data, or data that does not map cleanly onto UTF-8 text, is difficult to represent in a blob format. |
| 26 | +The `git-metadata` project provides a structured alternative to the notes-blob design using Git trees objects. |
| 27 | +Just like notes, metadata added to an object does not alter the object's history. |
| 28 | + |
| 29 | +> [!TIP] |
| 30 | +> Unlike notes, `metadata` is not added to `git log`. |
| 31 | +
|
| 32 | +[Notes]: https://git-scm.com/docs/git-notes |
| 33 | +[blog post]: https://tylercipriani.com/blog/2022/11/19/git-notes-gits-coolest-most-unloved-feature/ |
| 34 | +[`git-appraise`]: https://github.com/google/git-appraise |
| 35 | + |
| 36 | +## Usage |
| 37 | + |
| 38 | +Metadata entries are paths (with optional blob content) stored in a Git tree object, associated with any target object (blob, tree, or commit) via a fanout ref. |
| 39 | +The command follows `git notes` semantics: `list`, `show`, `add`, `remove`, `copy`, `prune`, and `get-ref`. |
| 40 | + |
| 41 | +<!-- rumdl-disable MD013 --> |
| 42 | + |
| 43 | +```shell |
| 44 | +# Add a path entry to HEAD's metadata tree |
| 45 | +git metadata add labels/bug |
| 46 | +git metadata add review/status -m approved |
| 47 | + |
| 48 | +# Add metadata to a specific object |
| 49 | +git metadata add labels/urgent abc1234 |
| 50 | + |
| 51 | +# Show all metadata entries for an object |
| 52 | +git metadata show # defaults to HEAD |
| 53 | +git metadata show abc1234 |
| 54 | + |
| 55 | +# List all targets that have metadata |
| 56 | +git metadata list |
| 57 | + |
| 58 | +# Remove entries by glob pattern |
| 59 | +git metadata remove 'labels/*' |
| 60 | +git metadata remove 'labels/bug' -o abc1234 |
| 61 | + |
| 62 | +# Keep only matching entries (remove everything else) |
| 63 | +git metadata remove --keep 'review/**' |
| 64 | + |
| 65 | +# Copy metadata from one object to another |
| 66 | +git metadata copy abc1234 def5678 |
| 67 | + |
| 68 | +# Remove metadata for objects that no longer exist |
| 69 | +git metadata prune |
| 70 | +git metadata prune -n # dry run |
| 71 | + |
| 72 | +# Print the metadata ref name |
| 73 | +git metadata get-ref |
| 74 | + |
| 75 | +# Use a custom ref |
| 76 | +git metadata --ref refs/metadata/custom add labels/bug |
| 77 | +``` |
| 78 | + |
| 79 | +<!-- rumdl-enable MD013 --> |
| 80 | + |
| 81 | +For more information, see `git metadata --help`. |
| 82 | + |
| 83 | +## Installation |
| 84 | + |
| 85 | +### CLI |
| 86 | + |
| 87 | +The `git-metadata` plumbing command can be installed with `cargo install`. |
| 88 | + |
| 89 | +```shell |
| 90 | +cargo install --locked git-metadata |
| 91 | +``` |
| 92 | + |
| 93 | +If `~/.cargo/bin` is on your `PATH`, you can invoke the command with `git`. |
| 94 | + |
| 95 | +```shell |
| 96 | +git metadata -h |
| 97 | +``` |
| 98 | + |
| 99 | +### Library |
| 100 | + |
| 101 | +The `git-metadata` library can be added to your Rust project via `cargo add`. |
| 102 | + |
| 103 | +```shell |
| 104 | +cargo add git-metadata |
| 105 | +``` |
0 commit comments