# Gitlet Design Document
Name: Jamsheed Mistri & Alina Trinh
## Classes and Data Structures
### Blob
Essentially the contents of files. Implements Serializable.
#### Fields
1. `int id`: unique integer ID that serves as a reference to the object
2. `String name`: name of the blob file
3. `ArrayList<String> file`: contents of the file
### Commit
Combinations of log messages, other metadata (commit date, author, etc.), a reference to a tree, and references to parent commits. The repository also maintains a mapping from branch heads to references to commits, so that certain important commits have symbolic names.
#### Fields
1. `int id`: unique integer ID that serves as a reference to the object
2. `Commit parent`: parent
3. `String msg`: log message
4. `ArrayList<Blob> files`: a mapping of file names to blob references
5. `Date time`: timestamp
### Repository
#### Fields
- `Branch current`: current branch
- `ArrayList<Branch> branches`: all branches
- `File cwd`: working directory File
- `ArrayList<Blob> stagedForAddition`: blobs staged for addition
- `ArrayList<Blob> stagedForRemoval`: blobs staged for removal
### Branch
#### Fields
- `Commit head`: head commit for this repository
- `String name`: name of branch
## Algorithms
### Main
1. `init()`: creates the persistence directories presented in the **Persistence** header below
2. `log()`: returns an `ArrayList<Commit>` in descending order of recent commits
3. `global_log()`: returns an `ArrayList<Commit>` of all commits ever made
4. `find(int id)`: searches in all `Tree`s and outputs all `Commit`s with `id` as `id`
5. `status()`: searches all `Tree`s' blobs and outputs all branches, all `staged` files, all files where `rm` is true, all files that are `tracked`, and all other files that meet the requirements specified in the spec
### Blob
1. `diff(Blob otherBlob)`: computes a diff which returns an `ArrayList<Integer> added` of indices where each integer represents a line that was added, and `ArrayList<Integer> removed` of indices where each integer represents a line that was removed
### Commit
1. `new Commit()`: create an empty `Commit` with an `id`, null `parent`, "initial commit" `msg`, null `files`, and a `time`.
2. `new Commit(ArrayList<Blob> blobs, Commit parent)`: creates a new `Commit` object, then update the `blobs` that have been passed in, adding an `id`, `msg`, and `time`; make`parent` `Commit` the new `Commit`'s `parent`
3. `merge(Commit otherCommit)`: merges another Commit _into_ this Commit. Iterates through each parent commit and merges recursively until there are no parent commits left. At the base case, the Blobs are merged together using `diff()`
4. `rm(Blob blob)`: if the `Blob` is not `tracked`, unstages the `Blob` by making its `staged` boolean `false`; else, change `staged` to `true` and `rm` to `true` to indicate the file is to be removed, then remove the blob from the directory `tree`
### Repository
1. `init()`: creates an initial `Commit`, an initial master branch, and an initial head pointer for the branch pointing to the initial commit.
2. `commit()`: calls `Branch`'s `commit()` method, passing in the Blobs in both staged lists to be commit; then, clears both lists after the commit is done. Should also change head to most recent commit
3. `add(String fileName)`: creates blob and adds to `stagedForAddition`
### Branch
1. `commit(ArrayList<Blob> blobs)`: calls `Commit` constructor to create a new commit object, passing in the necessary blobs, for the current branch, and then adds that commit to the collection of commits in the branch, moving `head` to the new `Commit`.
## Persistence
All files are stored in the subdirectory `.gitlet` per Gitlet project. This can be initialized using the _init_ call.
### Structure
- **.gitlet** (directory) - where everything is stored
- **repository** (file) - stores the repository object
- **branches** (directory) - directory of all branch files. Each branch file's contents contains its HEAD commit hash
- **blobs** (directory) - directory of all blob files
- **commits** (directory) - directory of all commit files
- **staged** (directory) - creates a blob based on a file that is staged for addition here. The file is moved to the blobs directory when committed.