Skip to content
Open
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
27 changes: 27 additions & 0 deletions GitTester.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import java.io.IOException;

public class GitTester {

public static void main(String args[]) throws IOException {

/* Your tester code goes here */
GitWrapper gw = new GitWrapper();
gw.init();

gw.add("testFolder/another/here.txt");

String hashOfOldCommit = gw.commit("miles", "1 commit");

gw.add("testFolder/one_more.txt");
gw.add("testFolder/another.txt");
gw.add("testFolder/shouldbegone.txt");

String hashOfNewCommit = gw.commit("miles", "2 commit");

gw.checkout(hashOfOldCommit);
gw.checkout(hashOfNewCommit);

// in the end, nothing should change
// we checked out an older commit and then came back to the current one
}
}
100 changes: 100 additions & 0 deletions GitWrapper.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;

public class GitWrapper {

private gitRepository repo;

/**
* Initializes a new Git repository.
* This method creates the necessary directory structure
* and initial files (index, HEAD) required for a Git repository.
*
* @throws IOException
*/
public void init() throws IOException {
repo = new gitRepository(false);
};

/**
* Stages a file for the next commit.
* This method adds a file to the index file.
* If the file does not exist, it throws an IOException.
* If the file is a directory, it throws an IOException.
* If the file is already in the index, it does nothing.
* If the file is successfully staged, it creates a blob for the file.
*
* @param filePath The path to the file to be staged.
* @throws IOException
*/
public void add(String filePath) throws IOException {
File fileToAdd = new File(filePath);

if (!fileToAdd.exists()) {
throw new IOException("add: file doesn't exist");
}

if (fileToAdd.isDirectory()) {
throw new IOException("add: file is a directory");
}

repo.addFile(fileToAdd.getPath());
};

/**
* Creates a commit with the given author and message.
* It should capture the current state of the repository by building trees based
* on the index file,
* writing the tree to the objects directory,
* writing the commit to the objects directory,
* updating the HEAD file,
* and returning the commit hash.
*
* The commit should be formatted as follows:
* tree: <tree_sha>
* parent: <parent_sha>
* author: <author>
* date: <date>
* summary: <summary>
*
* @param author The name of the author making the commit.
* @param message The commit message describing the changes.
* @return The SHA1 hash of the new commit.
* @throws IOException
*/
public String commit(String author, String message) throws IOException {
return repo.commit(author, message);
};

/**
* EXTRA CREDIT:
* Checks out a specific commit given its hash.
* This method should read the HEAD file to determine the "checked out" commit.
* Then it should update the working directory to match the
* state of the repository at that commit by tracing through the root tree and
* all its children.
*
* @param commitHash The SHA1 hash of the commit to check out.
* @throws IOException
*/
public void checkout(String commitHash) throws IOException {

if (!repo.doesCommitHashExist(commitHash)) {
throw new IllegalArgumentException("commitHash doesn't exist");
}

// deletes tracked files
repo.deleteTrackedFilesFromCurrentCommit();

// generates old files
repo.regenerateTrackedFilesFromCommit(commitHash);

// rewrites head
File head = new File("git/HEAD");
head.delete();
head.createNewFile();
Files.write(head.toPath(), commitHash.getBytes());

};
}
19 changes: 18 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,4 +61,21 @@ __GP-3.1.0__ | addTreeRecursive()
4. Replaces all grouped entries in the working list with a single reference to the newly created tree object (using its hash and directory name).
5. Continues this process recursively, ascending directory levels, until the working list is collapsed to one or more entries at the root level.
6. If multiple root entries remain, combines and writes a final root tree object, then prints and returns its hash as the reference to the entire directory tree.
7. The writeTreeObj method takes a list of entries, extracts relevant parts, formats the tree content, hashes it, writes it to the "git/objects/" folder, and returns the hash.
7. The writeTreeObj method takes a list of entries, extracts relevant parts, formats the tree content, hashes it, writes it to the "git/objects/" folder, and returns the hash.

__GP-4.2__ | commit()
1. Writes a commit file to the objects folder by asking the user for their name and commit message, generating the date, generating the commit hash, and pulls the previous commit hash from the HEAD, if it exists
2. Writes the current commit hash to the HEAD

__GP-4.3__ | wrapped commit(), add(), and init()
1. init() makes a repository
2. add() wraps index and BLOB code and now correctly handles adding a file already in the index
3. wrapped commit() just delegates to GP-4.2 commit()

__GP-4.4__ | extra credit -- checkout()
1. getRootHashFromCommitHash() retrieves the root tree hash from a commitHash
2. deleteTrackedFilesFromCurrentCommit() wraps deleteRootRecursive() which deletes all files tracked from the root
3. regenerateTrackedFilesFromCommit() wraps regenRootRecursive() which regenerates all files tracked from the root
4. doesCommitHashExist() checks to see if a commitHash exists
5. getParentCommit() grabs the parent commit; null if none exists
-> Fixed an edge case where if a singular nested blob was being committed, the enclosing folders wouldn't be committed
Loading