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
3 changes: 2 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ concurrency:
env:
CARGO_TERM_COLOR: always
RUST_VERSION_STABLE: stable
RUST_VERSION_NIGHTLY: nightly

jobs:
test:
Expand Down Expand Up @@ -51,7 +52,7 @@ jobs:
- name: Install Rust toolchain
uses: actions-rs/toolchain@v1
with:
toolchain: ${{ env.RUST_VERSION_STABLE }}
toolchain: ${{ env.RUST_VERSION_NIGHTLY }}
profile: minimal
components: rustfmt, clippy
override: true
Expand Down
18 changes: 18 additions & 0 deletions .rustfmt.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Stable
match_block_trailing_comma = true
newline_style = "Unix"
use_field_init_shorthand = true
use_try_shorthand = true

# Nightly
imports_granularity = "Module"
combine_control_expr = false
condense_wildcard_suffixes = true
format_code_in_doc_comments = true
format_macro_matchers = true
hex_literal_case = "Lower"
normalize_comments = true
normalize_doc_attributes = true
overflow_delimited_expr = true
reorder_impl_items = true
group_imports = "StdExternalCrate"
23 changes: 15 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,25 @@ This is a simple attempt at re-creating some of the functionality of the `git` c
## Features

- `hash-object` - Compute the hash of an object and optionally write it to the object database.
- `-w` flag to write the object to the object database.
- `-t` flag to specify the type of the object (supported: `blob`).
- `<file>` argument to specify the file to hash.
- `-w` flag to write the object to the object database.
- `-t` flag to specify the type of the object (supported: `blob`).
- `<file>` argument to specify the file to hash.
- `init` - Create an empty Git repository.
- `--bare` flag to create a bare repository.
- `-b` or `--initial-branch` flag to specify the initial branch.
- `-q` or `--quiet` flag to suppress the output.
- `<directory>` argument to specify the directory to initialize.
- `--bare` flag to create a bare repository.
- `-b` or `--initial-branch` flag to specify the initial branch.
- `-q` or `--quiet` flag to suppress the output.
- `<directory>` argument to specify the directory to initialize.
- `cat-file` - Provide content or type and size information for repository objects.
- `-t` flag to show the type of the object.
- `-s` flag to show the size of the object.
- `-p` flag to show the content of the object (pretty-print)
- `--allow-unknown-type` flag to allow unknown object types (to be used with `-t` or `-s`).
- `<object>` argument to specify the object to show.

## Testing

Due to the nature of the project, tests must be run sequentially. To run the tests, use the following command:
Due to the nature of the project, tests must be run sequentially. To run the tests, use the
following command:

```sh
cargo test -- --test-threads=1
Expand Down
104 changes: 104 additions & 0 deletions object_structure.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
# Object Structure

This document describes the structure of Git objects.

## General Object Structure

> [Reference](https://git-scm.com/book/en/v2/Git-Internals-Git-Objects) (Object Storage)

All objects are stored in the `.git/objects` directory (or `$GIT_DIR/$GIT_OBJECT_DIRECTORY`) and
have the following structure:

```plaintext
{type} {size}\0{content}
```

- `{type}` is the type of the object (blob, tree, commit, tag).
- `{size}` is the size of the content in bytes.
- `{content}` is the actual content of the object.

## Blob

> [Reference](https://git-scm.com/book/en/v2/Git-Internals-Git-Objects) (Object Storage)

A blob object is a file. Its content is just the file data.

## Tree

> [Reference](https://stackoverflow.com/a/37105125/19244184)

A tree object represents a directory. It contains a list of entries (no separator), each of which
can be either a blob or a tree object.

The format of each entry is as follows:

```plaintext
{mode} {filename}\0{hash}
```

- `{mode}` is the file mode (e.g., `100644` for a file, `040000` for a directory).
- `{filename}` is the name of the file or directory.
- `{hash}` is the SHA-1 hash of the object represented in binary form.

## Commit

> [Reference](https://stackoverflow.com/a/37438460/19244184)

A commit object represents a commit. It contains a reference to a tree object, a list of parent
commits, an author, a committer, and a commit message.

The content of a commit object is as follows:

```plaintext
tree {tree_hash}
{parents}
author {author_name} <{author_email}> {author_date_seconds} {author_date_offset}
committer {committer_name} <{committer_email}> {committer_date_seconds} {committer_date_offset}

{commit_message}
```

- `{tree_hash}` is the SHA-1 hash of the tree object.
- `{parents}` is a list of parent commit objects (if any) of the form:
```plaintext
parent {parent_1_hash}
parent {parent_2_hash}
...
```
- `{author_name}` is the name of the author.
- `{author_email}` is the email address of the author.
- `{author_date_seconds}` is the author date in seconds since the Unix epoch.
- `{author_date_offset}` is the author date offset from UTC.
- `{committer_name}` is the name of the committer.
- `{committer_email}` is the email address of the committer.
- `{committer_date_seconds}` is the committer date in seconds since the Unix epoch.
- `{committer_date_offset}` is the committer date offset from UTC.
- `{commit_message}` is the commit message.

## Tag

> [Reference](https://stackoverflow.com/a/52193441/19244184)

A tag object represents a tag. It contains a reference to an object (usually a commit), a tagger,
and
a tag message.

The content of a tag object is as follows:

```plaintext
object {object_hash}
type {object_type}
tag {tag_name}
tagger {tagger_name} <{tagger_email}> {tagger_date_seconds} {tagger_date_offset}

{tag_message}
```

- `{object_hash}` is the SHA-1 hash of the object being tagged.
- `{object_type}` is the type of the object being tagged (e.g., `commit`).
- `{tag_name}` is the name of the tag.
- `{tagger_name}` is the name of the tagger.
- `{tagger_email}` is the email address of the tagger.
- `{tagger_date_seconds}` is the tagger date in seconds since the Unix epoch.
- `{tagger_date_offset}` is the tagger date offset from UTC.
- `{tag_message}` is the tag message.
Loading
Loading