Metadata-Version: 2.4
Name: sid-vcs
Version: 1.0.0
Summary: A beginner-friendly Git-like version control system
Author: Siddhant
License: MIT
Project-URL: Homepage, https://github.com/Siddhant/sid-vcs
Project-URL: Issues, https://github.com/Siddhant/sid-vcs/issues
Keywords: vcs,version-control,git,educational
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Education
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: Software Development :: Version Control
Requires-Python: >=3.8
Description-Content-Type: text/markdown
Provides-Extra: dev
Requires-Dist: pytest>=7.0; extra == "dev"

# Sid — A Beginner-Friendly Git-like Version Control System

<p align="center">
  <strong>🔧 Build your own VCS from scratch. Learn Git internals by doing.</strong>
</p>

Sid is a fully-functional version control system written in pure Python.
Instead of `git`, you use `sid`. It's designed for students and beginners
who want to understand how Git works under the hood.

**Key Features:**
- ✅ 50 commands across 11 levels of functionality
- ✅ Built with only Python standard libraries (no external deps)
- ✅ Clean, commented code that explains every concept
- ✅ Cross-platform: Windows, Linux, macOS
- ✅ Installable CLI — just run `sid` from anywhere

---

## Quick Start

### Installation

```bash
# Clone or download this project
cd sid

# Install in development mode
pip install -e .

# Verify installation
sid version
```

### Your First Repository

```bash
mkdir my-project
cd my-project

# Initialize a new Sid repository
sid init

# Create a file
echo "Hello, Sid!" > hello.txt

# Check what's happening
sid status

# Stage the file
sid add hello.txt

# Commit it
sid commit -m "first commit"

# View the history
sid log
```

---

## Command Reference

### Level 1 — Core Commands

| Command | Description |
|---|---|
| `sid init` | Initialize a new `.sid` repository |
| `sid add <file>` | Stage a file for commit |
| `sid add .` | Stage all files recursively |
| `sid commit -m "msg"` | Create a commit from staged files |
| `sid status` | Show working tree status |
| `sid log` | Show commit history |
| `sid diff` | Show unstaged file differences |
| `sid diff --staged` | Show staged differences |

### Level 2 — File Restore / Reset

| Command | Description |
|---|---|
| `sid restore <file>` | Restore file from index |
| `sid restore --source HEAD <file>` | Restore file from last commit |
| `sid rm <file>` | Remove file from tracking |
| `sid reset` | Unstage all files |
| `sid reset <file>` | Unstage a specific file |
| `sid reset --hard` | Reset everything to HEAD ⚠️ |

### Level 3 — Branching

| Command | Description |
|---|---|
| `sid branch` | List all branches |
| `sid branch <name>` | Create a new branch |
| `sid branch -d <name>` | Delete a branch |
| `sid checkout <branch>` | Switch to a branch |
| `sid checkout -b <name>` | Create and switch to new branch |
| `sid switch <branch>` | Switch (alias for checkout) |
| `sid switch -c <name>` | Create and switch (alias) |

### Level 4 — Commit Inspection

| Command | Description |
|---|---|
| `sid show [ref]` | Show commit details |
| `sid show HEAD` | Show latest commit |
| `sid cat-file <hash>` | Print raw object content |
| `sid ls-files` | List tracked files |

### Level 5 — Merge

| Command | Description |
|---|---|
| `sid merge <branch>` | Merge branch into current |
| `sid merge --abort` | Abort in-progress merge |

### Level 6 — Tags

| Command | Description |
|---|---|
| `sid tag` | List all tags |
| `sid tag <name>` | Create a lightweight tag |
| `sid tag -d <name>` | Delete a tag |
| `sid checkout <tag>` | Checkout tag (detached HEAD) |

### Level 7 — Ignore File

| Command | Description |
|---|---|
| `.sidignore` | Create to define ignore patterns |
| `sid check-ignore <file>` | Check if a file is ignored |

### Level 8 — Configuration

| Command | Description |
|---|---|
| `sid config user.name "Name"` | Set your name |
| `sid config user.email "email"` | Set your email |
| `sid config --list` | Show all config entries |

### Level 9 — Stash

| Command | Description |
|---|---|
| `sid stash` | Save uncommitted changes |
| `sid stash list` | Show saved stashes |
| `sid stash apply` | Apply latest stash |
| `sid stash pop` | Apply and remove stash |

### Level 10 — Local Remotes

| Command | Description |
|---|---|
| `sid remote add origin <path>` | Add a local remote |
| `sid remote -v` | Show configured remotes |
| `sid clone <src> <dest>` | Clone a repository |
| `sid push origin main` | Push to remote |
| `sid pull origin main` | Pull from remote |

### Level 11 — Utilities

| Command | Description |
|---|---|
| `sid help` | Show all commands |
| `sid version` | Show version |
| `sid doctor` | Check repository health |
| `sid graph` | Show commit graph |
| `sid clean` | Remove untracked files |

---

## How Sid Works Internally

### The `.sid` Directory

When you run `sid init`, a hidden `.sid` folder is created:

```
.sid/
├── objects/      ← Stores file content & commits (by hash)
├── refs/
│   ├── heads/    ← Branch pointers (e.g., main → commit hash)
│   └── tags/     ← Tag pointers
├── stash/        ← Saved stash entries
├── HEAD          ← Points to current branch
├── index         ← Staging area (JSON)
└── config        ← Repository settings (JSON)
```

### Content-Addressed Storage

Every file's content is hashed using **SHA-1**, producing a 40-character hex string.
The content is stored in `.sid/objects/<hash>`. If two files have the same content,
they share the same object — this is called **deduplication**.

```
"Hello, World!\n"  →  SHA-1  →  "a0b65939670bc2c010f4d5d6a0b3e4e4590fb92b"
```

### The Index (Staging Area)

The index at `.sid/index` is a JSON file mapping file paths to their blob hashes:

```json
{
  "hello.txt": "a0b659396...",
  "src/main.py": "f3e2d1c0b..."
}
```

When you run `sid add`, the file is hashed and added here.
When you run `sid commit`, this snapshot becomes the commit.

### Commit Objects

A commit is also stored in `.sid/objects/` as a JSON file:

```json
{
  "type": "commit",
  "message": "first commit",
  "author": "Siddhant",
  "email": "sid@example.com",
  "timestamp": "2025-01-01T12:00:00+00:00",
  "parent": null,
  "files": {
    "hello.txt": "a0b659396..."
  }
}
```

Commits form a **linked list** — each commit points to its parent.

### Branches

A branch is just a file in `.sid/refs/heads/` containing a commit hash.
HEAD tells Sid which branch you're currently on:

```
HEAD → "ref: refs/heads/main"
refs/heads/main → "abc123..."  (commit hash)
```

---

## Common Errors and Fixes

| Error | Fix |
|---|---|
| "not a sid repository" | Run `sid init` first |
| "nothing to commit" | Stage files with `sid add` |
| "cannot create branch — no commits yet" | Make your first commit |
| "cannot delete current branch" | Switch to another branch first |
| "merge conflict" | Edit the conflicted files, `sid add` them, then commit |

---

## Example Workflow

```bash
# Create a project
mkdir demo && cd demo
sid init
sid config user.name "Siddhant"
sid config user.email "sid@example.com"

# Create and commit files
echo "hello sid" > hello.txt
sid add hello.txt
sid commit -m "first commit"

# Make changes
echo "updated" >> hello.txt
sid diff
sid add hello.txt
sid commit -m "update hello"

# Branching
sid branch dev
sid checkout dev
echo "dev work" > dev.txt
sid add .
sid commit -m "add dev work"

# Merge
sid checkout main
sid merge dev

# Inspect
sid log
sid graph
sid show HEAD
sid doctor
```

---

## Future Improvement Ideas

- 🗜️ **Compression** — Compress blob objects (zlib) to save space
- 📦 **Binary file support** — Better handling of images, PDFs, etc.
- 🧠 **3-way merge** — Use common ancestor for smarter merging
- 🌐 **Real remote server** — Push/pull over HTTP or SSH
- 🖥️ **Web dashboard** — Browse commits and diffs in a browser
- 🏠 **GitHub-like hosting** — Self-hosted repository server
- 🔌 **Plugin system** — Custom hooks and extensions
- 🎨 **GUI app** — Visual interface for Sid operations
- 📊 **Blame command** — Show who changed each line
- 🔍 **Bisect** — Binary search for bug-introducing commits
- 📋 **Cherry-pick** — Apply specific commits to another branch
- 📝 **Interactive rebase** — Rewrite commit history

---

## Project Structure

```
sid/
├── sid/
│   ├── __init__.py      # Version constant
│   ├── cli.py           # CLI entry point (argparse)
│   ├── repository.py    # Repository initialization
│   ├── objects.py       # Blob & commit object storage
│   ├── index.py         # Staging area management
│   ├── commit.py        # Commit creation & log
│   ├── status.py        # Working tree status
│   ├── diff.py          # Unified diff display
│   ├── restore.py       # File restoration
│   ├── reset.py         # Index/tree reset
│   ├── branch.py        # Branch CRUD
│   ├── checkout.py      # Branch/tag switching
│   ├── merge.py         # Branch merging
│   ├── tags.py          # Lightweight tags
│   ├── ignore.py        # .sidignore patterns
│   ├── config.py        # Configuration management
│   ├── stash.py         # Stash save/apply
│   ├── remote.py        # Local folder remotes
│   ├── graph.py         # Commit graph display
│   ├── clean.py         # Remove untracked files
│   ├── doctor.py        # Repository health check
│   └── utils.py         # Shared helpers
├── tests/
│   ├── test_init.py
│   ├── test_add_commit.py
│   ├── test_branch.py
│   └── test_status.py
├── README.md
├── pyproject.toml
└── .sidignore.example
```

---

## Running Tests

```bash
# Install dev dependencies
pip install -e ".[dev]"

# Run all tests
python -m pytest tests/ -v

# Run a specific test file
python -m pytest tests/test_init.py -v
```

---

## License

MIT License — Feel free to use, modify, and learn from this project.

---

<p align="center">
  Built with ❤️ for learning. Happy hacking!
</p>
