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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
/git
.DS_Store
*.txt
45 changes: 36 additions & 9 deletions Git.java
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.util.Stack;
import java.util.*;
import java.util.ArrayList;
import java.util.Base64;
import java.util.Comparator;
import java.util.HashSet;
import java.util.zip.Deflater;
import java.util.zip.Inflater;
import java.time.*;
import java.time.format.*;

//LOOK AT TOP OF README FOR AN IMPORTANT EXPLANATION!

Expand Down Expand Up @@ -38,7 +40,10 @@ public static void makeDirectory(String filePath, String folderName){
File newDir = new File(path);
newDir.mkdir();
}

//IF THE HEAD EVER HAS STUFF OTHER THAN THE LATEST COMMIT, EDIT THIS METHOD
public static String retrieveLatestCommit(){
return readFile("git", "HEAD");
}
private static void deleteDirectory(File file)
{
for (File subfile : file.listFiles()) {
Expand Down Expand Up @@ -163,9 +168,9 @@ && directoryExists("git", "objects") && directoryExists(null, "git")){

deleteDirectory("git", "index"); //in case "cloggs" options
makeFile("git/objects", "index");

//FIXED: THE HEAD FILE ISN'T SUPPOSED TO BE IN THE OBEJCTS FOLDER
deleteDirectory("git", "HEAD"); //in case "cloggs" options
makeFile("git/objects", "HEAD");
makeFile("git", "HEAD");
}

public static void blobify(String filePath, String fileName){
Expand Down Expand Up @@ -307,7 +312,7 @@ public static String makeTree(String filePath, String fileName){ //returns hash

//NOTE: Does not automatically BLOB everything inside of it!
//That should have been done when indexed anyway.
public static void makeIndexTree(){
public static String makeIndexTree(){
StringBuilder rootTreeContents = new StringBuilder();
String indexFile = readFile("git/objects", "index");
String[] entriesArr = indexFile.split("\n");
Expand All @@ -334,8 +339,9 @@ public static void makeIndexTree(){
}
String contents = rootTreeContents.toString();
String hash = hash(contents);
makeFile(null, hash);
writeToFile(null, hash, contents);
makeFile("git/objects", hash);
writeToFile("git/objects", hash, contents);
return hash;
}

//returns tree hash
Expand Down Expand Up @@ -372,7 +378,28 @@ public static String makeIndexTreeHelper(ArrayList<String> entries, String direc
writeToFile("git/objects", treeHash, entryContent);
return treeHash;
}

public static String makeCommit(){
StringBuilder outputSB = new StringBuilder();
outputSB.append("tree: "+makeIndexTree()+"\n");
outputSB.append("parent: "+retrieveLatestCommit()+"\n");
Scanner sc = new Scanner(System.in);
System.out.println("Enter author name:");
outputSB.append("author: "+sc.nextLine()+"\n");
sc.reset();
//i hope geeksForGeeks was right about what this code does
LocalDateTime localDateTime = LocalDateTime.now();
DateTimeFormatter validDateTimeFormatter = DateTimeFormatter.ofPattern("dd-MM-yyyy HH:mm:ss");
outputSB.append("date: "+ localDateTime.format(validDateTimeFormatter) + "\n");
System.out.println("Enter commit message:");
outputSB.append("message: "+sc.nextLine());
sc.close();
String commitHash = hash(outputSB.toString());
makeFile("git/objects", commitHash);
writeToFile("git/objects", commitHash, outputSB.toString());
// change this if more info needs to be stored on the HEAD
writeToFile("git", "HEAD", commitHash);
return commitHash;
}
public static void main(String[] args){
cleanGit();
intializeRepo();
Expand All @@ -381,6 +408,6 @@ public static void main(String[] args){
index("A/C", "f4");
index("A", "f1");
index(null, ".gitignore");
makeIndexTree();
makeIndexTree();
}
}
82 changes: 82 additions & 0 deletions GitWrapper.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import java.nio.file.Paths;
import java.time.*;
import java.time.format.*;
public class GitWrapper {
/**
* Initializes a new Git repository.
* This method creates the necessary directory structure
* and initial files (index, HEAD) required for a Git repository.
*/
public void init() {
Git.intializeRepo();
};

/**
* 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.
*/
public void add(String filePath) {
//Shimone, this is what you get when you split the parent path, and file name
String parentPath = Paths.get(filePath).getParent().toString();
String childPath = Paths.get(filePath).getFileName().toString();
Git.index(parentPath, childPath);
Git.blobify(parentPath, childPath);
};

/**
* 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.
*/
public String commit(String author, String message) {
//this is literally a ctrl c + ctrl v without the scanner
StringBuilder outputSB = new StringBuilder();
outputSB.append("tree: "+Git.makeIndexTree()+"\n");
outputSB.append("parent: "+Git.retrieveLatestCommit()+"\n");
outputSB.append("author: "+author+"\n");
LocalDateTime localDateTime = LocalDateTime.now();
DateTimeFormatter validDateTimeFormatter = DateTimeFormatter.ofPattern("dd-MM-yyyy HH:mm:ss");
outputSB.append("date: "+ localDateTime.format(validDateTimeFormatter) + "\n");
outputSB.append("message: "+message);
String commitHash = Git.hash(outputSB.toString());
Git.makeFile("git/objects", commitHash);
Git.writeToFile("git/objects", commitHash, outputSB.toString());
// change this if more info needs to be stored on the HEAD
Git.writeToFile("git", "HEAD", commitHash);
return commitHash;
};

/**
* 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.
*/
public void checkout(String commitHash) {
// to-do: implement functionality here

};
}
33 changes: 32 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,4 +84,35 @@ decompress: takes a compressed String and returns the original

GP 3.2

makeTree: from file path, recursively creates tree by makign subtrees and blobifying subfiles. returns the name of the hash!
makeTree: from file path, recursively creates tree by makign subtrees and blobifying subfiles. returns the name of the hash!

--

GP 4.1

makeIndexTree now returns the hash of the root tree

--

GP 4.2

makeCommit: Generates a new commit file by calling makeIndexTree to make a new root hash and prompting the user for the author name and commit message. appends the HEAD with the commit's hash
retriveLastCommit: reads the HEAD (which shoudl have the most recent commit hash) CHANGE THIS IF ANY OTHER STUFF IS IN THE HEAD FILE

--

GP 4.3

GitWrapper - new wrapper class for Git
init: calls Git.initRepo
add: indexes and blobs the filepath given
commit: copy of Git.makeCommit without the scanner
checkout: WIP (I'm not quite sure how it's supposed to work)

--

Final Testing + Extras

FIXED: HEAD is no longer in the objects folder
FIXED: Date no longer throws exceptions when making commits
full wraper test implemented
74 changes: 68 additions & 6 deletions Tester.java
Original file line number Diff line number Diff line change
Expand Up @@ -215,12 +215,74 @@ public static void indexTester(){
Git.deleteDirectory(null, "testFiles");
System.out.println("PASSED");
}

public static void indexTreeTester(){
System.out.println("Index Tree Test");
//make a bunch of files and folders to test different combinations of files and folders
Git.intializeRepo();
makeLargeFileSystem();
Git.blobify("indexTreetest", "testFile1");
Git.index("indexTreeTest", "testFile1");
Git.blobify("indexTreetest", "testFile2");
Git.index("indexTreeTest", "testFile2");
Git.blobify("indexTreetest/firstLayer", "testFile3");
Git.index("indexTreeTest/firstLayer", "testFile3");
Git.blobify("indexTreeTest/firstlayer/secondLayer", "testFile4");
Git.index("indexTreeTest/firstlayer/secondLayer", "testFile4");
Git.blobify("indexTreeTest/altLayer", "testFile5");
Git.index("indexTreeTest/altLayer", "testFile5");
recursiveTreeTest(Git.makeIndexTree());
}
public static void makeLargeFileSystem(){
Git.makeDirectory(null, "indexTreeTest");
Git.makeDirectory("indexTreeTest", "firstLayer");
Git.makeDirectory("indexTreeTest/firstLayer", "secondLayer");
Git.makeDirectory("indexTreeTest", "altLayer");
Git.makeFile("indexTreeTest", "testFile1");
Git.makeFile("indexTreeTest", "testFile2");
Git.makeFile("indexTreeTest/firstLayer", "testFile3");
Git.makeFile("indexTreeTest/firstLayer/secondLayer", "testFile4");
Git.makeFile("indexTreeTest/altLayer", "testFile5");
}
public static void recursiveTreeTest(String treePath){
String contents = Git.readFile("git/objects", treePath);
String [] contentsArr = contents.split("\n");
for(String e : contentsArr){
if(e.split(" ")[1].equals("tree")){
recursiveTreeTest(e.split(" ")[2]);
}
else{
if(Git.fileExists("git/objects", e.split(" ")[2])){
System.out.println("File "+e.split(" ")[3]+" correctly blobbed, indexed, and treed");
}
}
}
}
public static void gitWrapperTest(){
GitWrapper git = new GitWrapper();
System.out.println("Full Wrapper Test Started");
System.out.println("Testing Repo Initialization");
git.init();
if (Git.fileExists("git/objects", "index") && Git.fileExists("git/objects", "HEAD")
&& Git.directoryExists("git", "objects") && Git.directoryExists(null, "git")){
System.out.println("Repo initialization sucess");
}
makeLargeFileSystem();
System.out.println("File System created");
git.add("indexTreeTest/testFile1");
git.add("indexTreeTest/testFile2");
git.add("indexTreeTest/firstLayer/testFile3");
git.add("indexTreeTest/firstLayer/secondLayer/testFile4");
System.out.println("File adding sucessful");
String commithash = git.commit("Hunter Madden", "THIS IS A TEST");
System.out.println("COMMIT EXISTS: " + Git.fileExists("git/objects", commithash));
}
public static void main(String[] args){
initializationTester();
hashTester();
blobTester();
indexTester();
Git.cleanGit();
// initializationTester();
// hashTester();
// blobTester();
// indexTester();
// indexTreeTester();
gitWrapperTest();
//Git.cleanGit();
}
}