Skip to content

Commit 2dbd481

Browse files
committed
Improve readme
1 parent e48f3aa commit 2dbd481

16 files changed

+846
-64
lines changed

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
cmake_minimum_required(VERSION 3.13)
22

3-
project(codecrafters-git)
3+
project(recreate-git)
44

55
set(CMAKE_CXX_STANDARD 23) # Enable the C++23 standard
66

README.md

Lines changed: 154 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,59 +1,174 @@
1-
[![progress-banner](https://backend.codecrafters.io/progress/git/b764456b-a007-4b20-aeac-f24c9d0c8560)](https://app.codecrafters.io/users/codecrafters-bot?r=2qF)
1+
# mygit - A C++ Implementation of Core Git Commands
22

3-
This is a starting point for C++ solutions to the
4-
["Build Your Own Git" Challenge](https://codecrafters.io/challenges/git).
3+
**mygit** is a from-scratch implementation of several core Git commands in modern C++23. It was created as a portfolio project to gain a fundamental understanding of Git's internal object model, packfile protocol, and data structures. This project is inspired by the "Build Your Own X" initiative.
54

6-
In this challenge, you'll build a small Git implementation that's capable of
7-
initializing a repository, creating commits and cloning a public repository.
8-
Along the way we'll learn about the `.git` directory, Git objects (blobs,
9-
commits, trees etc.), Git's transfer protocols and more.
5+
## Core Workflow Demo
106

11-
**Note**: If you're viewing this repo on GitHub, head over to
12-
[codecrafters.io](https://codecrafters.io) to try the challenge.
7+
This demo shows how to build `mygit` and then use its plumbing commands to create a Git commit from scratch, demonstrating the core object model in action.
138

14-
# Passing the first stage
9+
#### Step 1: Build the `mygit` Executable
1510

16-
The entry point for your Git implementation is in `src/main.cpp`. Study and
17-
uncomment the relevant code, and push your changes to pass the first stage:
11+
First, clone this repository and run the build script.
1812

19-
```sh
20-
git commit -am "pass 1st stage" # any msg
21-
git push origin master
13+
```bash
14+
# Clone the repository (replace with your actual repo URL)
15+
$ git clone https://github.com/Mathis-L/recreate-git.git mygit
16+
$ cd mygit
17+
18+
# Run the build script
19+
$ chmod +x build.sh
20+
$ ./build.sh
21+
--- Starting mygit build process ---
22+
Step 1: Configuring with CMake...
23+
-- The CXX compiler identification is GNU 11.4.0
24+
...
25+
Step 2: Building the executable...
26+
[ 50%] Built target mygit
27+
...
28+
[100%] Built target mygit
29+
30+
✅ Build complete!
31+
The executable is located at: ./build/mygit
32+
33+
$ export PATH=$PWD/build:$PATH
34+
$ cd ..
35+
```
36+
37+
#### Step 2: Create a Commit from Scratch
38+
39+
Now that `mygit` is built, let's use it to create a new project.
40+
41+
```bash
42+
# Create a new project directory and navigate into it
43+
$ mkdir my-test-project && cd my-test-project
44+
45+
# Use the 'mygit' we just built to initialize a repository
46+
$ mygit init
47+
Initialized empty Git repository in /path/to/my-test-project/.git/
48+
49+
# Create a file and add it to the object database as a "blob"
50+
$ echo "hello git" > hello.txt
51+
$ mygit hash-object -w hello.txt
52+
d90f1b40cf83b5d4313c4155abdaac3265b53026
53+
54+
# Create a "tree" object that captures the state of the directory
55+
$ mygit write-tree
56+
7c7394336c9966133c945b63cf476902d28f0b9f
57+
58+
# Create a "commit" object, linking the tree with a message
59+
$ mygit commit-tree 7c7394336c9966133c945b63cf476902d28f0b9f -m "Initial commit"
60+
1b2e67a423e8b0ed5d46924d567027582b12367d
61+
62+
# Inspect the final commit object we just created
63+
$ /mygit cat-file -p 1b2e67a423e8b0ed5d46924d567027582b12367d
64+
tree 7c7394336c9966133c945b63cf476902d28f0b9f
65+
author Mathis-L <mathislafon@gmail.com> 1721245200 +0000
66+
committer Mathis-L <mathislafon@gmail.com> 1721245200 +0000
67+
68+
Initial commit
2269
```
2370

24-
That's all!
71+
## Features & Implemented Commands
72+
73+
This project implements the plumbing and porcelain commands necessary to support a basic `clone` and `inspect` workflow.
74+
75+
* `init`: Initializes an empty `.git` directory structure.
76+
* `cat-file`: Inspects a Git object from the database (`-p` pretty-print option is supported).
77+
* `hash-object`: Computes an object ID and optionally creates a blob from a file (`-w` write option is supported).
78+
* `ls-tree`: Lists the contents of a tree object (`--name-only` is supported).
79+
* `write-tree`: Creates a tree object from the current directory state.
80+
* `commit-tree`: Creates a new commit object from a tree, parent, and message.
81+
* `clone`: Fetches a complete repository from a remote server over the Smart HTTP protocol.
82+
83+
## Project Foundations: Understanding Git's Internals
84+
85+
To understand how `mygit` works, it is essential to first understand Git's elegant and powerful design. The following document provides a detailed overview of the core concepts that this project implements, from the `.git` directory structure to the fundamental object model.
86+
87+
* **[📄 Deep Dive: Git's Internal Structure and Object Model](./docs/git_internals.md)**
2588

26-
# Stage 2 & beyond
89+
## Technical Deep Dive: The Clone Process
2790

28-
Note: This section is for stages 2 and beyond.
91+
The most complex command implemented is `clone`, which involves a multi-stage conversation with a remote server using Git's Smart HTTP Protocol.
2992

30-
1. Ensure you have `cmake` installed locally
31-
1. Run `./your_program.sh` to run your Git implementation, which is implemented
32-
in `src/main.cpp`.
33-
1. Commit your changes and run `git push origin master` to submit your solution
34-
to CodeCrafters. Test output will be streamed to your terminal.
93+
For a detailed, step-by-step breakdown of how `mygit` handles reference discovery, packfile negotiation, and delta resolution, please see the **[Git Clone Deep Dive Document](./docs/CLONE_DEEP_DIVE.md)**.
3594

36-
# Testing locally
3795

38-
The `your_program.sh` script is expected to operate on the `.git` folder inside
39-
the current working directory. If you're running this inside the root of this
40-
repository, you might end up accidentally damaging your repository's `.git`
41-
folder.
96+
## Current Limitations
4297

43-
We suggest executing `your_program.sh` in a different folder when testing
44-
locally. For example:
98+
As a learning project, this implementation focuses on the "happy path" and has several limitations compared to the real Git:
99+
* `clone` only supports the HTTP/HTTPS protocols. SSH is not supported.
100+
* `clone` performs a full, shallow clone and does not support complex history negotiation (i.e., it has no `have` lines).
101+
* Plumbing commands like `commit-tree` use hardcoded author information.
102+
* There is no concept of an index/staging area (`git add`). `write-tree` works directly from the file system.
45103

46-
```sh
47-
mkdir -p /tmp/testing && cd /tmp/testing
48-
/path/to/your/repo/your_program.sh init
104+
105+
## Getting Started
106+
107+
### Prerequisites
108+
109+
You will need a C++23 compatible compiler and the following dependencies:
110+
* `build-essential` (for `g++`, `make`, etc.)
111+
* `cmake` (version 3.13+)
112+
* `libssl-dev` (for SHA-1 hashing)
113+
* `zlib1g-dev` (for object compression)
114+
* `cpr` (for HTTP requests, installed by the build workflow)
115+
116+
On Debian/Ubuntu, you can install them with:
117+
```bash
118+
sudo apt-get update
119+
sudo apt-get install -y build-essential cmake libssl-dev zlib1g-dev
120+
```
121+
122+
And for cpr you will have to do :
123+
```bash
124+
# 1. Clone the cpr repository
125+
git clone https://github.com/libcpr/cpr.git
126+
cd cpr
127+
128+
# 2. Configure, build, and install the library system-wide
129+
mkdir build && cd build
130+
cmake .. -DCPR_USE_SYSTEM_CURL=ON
131+
cmake --build .
132+
sudo cmake --install .
133+
134+
# 3. Go back to your original directory
135+
cd ../..
136+
```
137+
138+
### Building the Project
139+
140+
A convenience script is provided to build the project.
141+
142+
```bash
143+
# Make the build script executable
144+
chmod +x build.sh
145+
146+
# Run the script to configure and build
147+
./build.sh
49148
```
50149

51-
To make this easier to type out, you could add a
52-
[shell alias](https://shapeshed.com/unix-alias/):
150+
The final executable will be located at `./build/mygit`.
151+
152+
### Running Tests
53153

54-
```sh
55-
alias mygit=/path/to/your/repo/your_program.sh
154+
The project includes a suite of integration tests written as shell scripts. To run them:
155+
```bash
156+
# Navigate to the tests directory
157+
cd tests
56158

57-
mkdir -p /tmp/testing && cd /tmp/testing
58-
mygit init
159+
# Make the test scripts executable
160+
chmod +x *.sh
161+
162+
# Run the main test runner
163+
./run_all_tests.sh
59164
```
165+
A successful run will end with the message: `✅ All tests passed.`
166+
167+
## Future Work
168+
169+
This project provides a solid foundation. Future work could include implementing more of Git's core features:
170+
* **Index Management:** `add`, `rm`
171+
* **Status & Diffs:** `status`, `diff`
172+
* **Branching & Merging:** `branch`, `checkout`, `merge`
173+
* **Protocol Enhancements:** Support for the v2 protocol, SSH.
174+

build.sh

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#!/bin/sh
2+
# Exit early if any commands fail
3+
set -e
4+
5+
echo "--- Starting mygit build process ---"
6+
7+
# Ensure all steps are run from within the repository's root directory
8+
cd "$(dirname "$0")"
9+
10+
# 1. Configure the project with CMake
11+
echo "Step 1: Configuring with CMake..."
12+
cmake -B build -S .
13+
14+
# 2. Build the project using the generated build files
15+
echo "Step 2: Building the executable..."
16+
cmake --build ./build
17+
18+
echo ""
19+
echo "✅ Build complete!"
20+
echo " The executable is located at: ./build/mygit"
21+
echo " You can now run commands, for example: ./build/mygit --help"

0 commit comments

Comments
 (0)