Skip to content
Open
Binary file added CommitTester.class
Binary file not shown.
16 changes: 16 additions & 0 deletions CommitTester.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import java.io.IOException;

public class CommitTester {
public static void main (String [] args) throws IOException {
Git myGit = new Git();
myGit.initalizeGitRepo();
myGit.stage("tester1");
myGit.stage("tester2");
System.out.println(myGit.commit("Aviv Pilipski", "Updated Tester1 and Tester2"));
myGit.stage("tester3");
System.out.println(myGit.commit("Aviv Pilipski", "Added file3"));
myGit.stage("testDir");
myGit.stage("testDirFiles");
System.out.println(myGit.commit("Aviv Pilipski", "Empty Directory + Directory with Files"));
}
}
Binary file added Git.class
Binary file not shown.
170 changes: 128 additions & 42 deletions Git.java
Original file line number Diff line number Diff line change
@@ -1,12 +1,46 @@
import java.security.MessageDigest;
import java.io.*;
import java.math.BigInteger;
import java.nio.file.Files;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public abstract class Git {
public class Git implements GitInterface {
// initalizes a Git Repo with an "objects" folder and "index" file
public static void initalizeGitRepo() {
public void stage (String filePath) {
File fileToStage = new File (filePath);
try {
blobCreation(fileToStage);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

public String commit (String author, String message) throws IOException {
return makeCommit(author, message);
}

public void checkout (String commitHash) throws IOException {
File headFile = new File ("./git/objects");
headFile.delete();
headFile.createNewFile();
BufferedWriter headBR = new BufferedWriter(new FileWriter (headFile));
headBR.write(commitHash);
headBR.close();
String commit = fileContent(headFile);
File commitFile = new File ("./git/objects", commit);
BufferedReader br = new BufferedReader (new FileReader (commitFile));
String commitFileRootTree = br.readLine();
br.close();
commitFileRootTree = commitFileRootTree.replace("tree: ", "");
File rootTreeFile = new File ("./git/objects", commitFileRootTree);
String rootTreeContents = fileContent(rootTreeFile);
File indexFile = new File ("./git/index");
BufferedWriter indexWriter = new BufferedWriter(new FileWriter(indexFile));
indexWriter.write(rootTreeContents);
indexWriter.close();
}

public static void initalizeGitRepo() throws IOException {
File gitFolder = new File("./git"); // git folder
File objectsFolder = new File("./git/objects"); // objects folder
File file = new File("./git", "index"); // index file
Expand All @@ -32,10 +66,27 @@ public static void initalizeGitRepo() {
} catch (IOException e) {
e.printStackTrace();
}

File head = new File ("./git/HEAD");
head.createNewFile();
}

// hashes the content of a file using SHA1
public static String SHA1Hashing(String file) throws IOException {
try {
MessageDigest crypt = MessageDigest.getInstance("SHA-1");
crypt.update(file.getBytes("UTF-8"));
BigInteger temp = new BigInteger(1, crypt.digest());
return temp.toString(16);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}

// this is here bc otherwise there is an error message. well can anyone actually
// bypass the "try"?
return "error";
}
public static String SHA1Hashing(File file) throws IOException {
String content;
if(file.isDirectory())
Expand Down Expand Up @@ -105,6 +156,59 @@ private static String fileContent(File file) {
return sb.toString();
}

public String generateRootTree() throws IOException {
File headFile = new File ("./git/HEAD");
File indexFile = new File ("./git/index");
String toReturn = "";
if (headFile.length() == 0) {
toReturn = SHA1Hashing(indexFile);
blobCreation(indexFile);
}
else {
String hashOfPreviousCommit = fileContent(headFile);
File previousCommit = new File ("./git/objects", hashOfPreviousCommit);
BufferedReader br = new BufferedReader (new FileReader (previousCommit));
String treeHash = br.readLine();
br.close();
treeHash = treeHash.replace("tree: ", "");
File previousTree = new File ("./git/objects", treeHash);
String contentsOfPrevious = fileContent(previousTree);
String updatedTree = contentsOfPrevious + "\n" + fileContent(indexFile);
String hashTree = SHA1Hashing(updatedTree);
File treeFile = new File ("./git/objects", hashTree);
BufferedWriter treeWriter = new BufferedWriter(new FileWriter(treeFile));
treeWriter.write(updatedTree);
treeWriter.close();
toReturn = hashTree;

}
indexFile.delete();
indexFile.createNewFile();
return toReturn;
}
public String makeCommit(String author, String message) throws IOException {
File headFile = new File ("./git/HEAD");
StringBuilder sb = new StringBuilder();
sb.append("tree: ").append(generateRootTree()).append("\n")
.append("parent: ").append(fileContent(headFile)).append("\n")
.append("author: ").append(author).append("\n")
.append("date: ").append(java.time.LocalDate.now()).append("\n")
.append("commit summary: ").append(message);
String commitHash = SHA1Hashing(sb.toString());
File commitFile = new File ("./git/objects", commitHash);
commitFile.createNewFile();
BufferedWriter bw = new BufferedWriter (new FileWriter (commitFile));
bw.write(sb.toString());
bw.close();
headFile.delete();
headFile.createNewFile();
BufferedWriter bHead = new BufferedWriter(new FileWriter (headFile));
bHead.write(commitHash);
bHead.close();
return commitHash;

}

public static void blobCreation(File file) throws IOException {
if(!file.exists()){
throw new FileNotFoundException();
Expand Down Expand Up @@ -138,6 +242,7 @@ public static void blobCreation(File file) throws IOException {
else{
name = SHA1Hashing(file); // getting hashed name
File blobFile = new File("./git/objects/" + name); // the blob file

// creates the blob file
try (BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(blobFile.getPath())); BufferedReader br = new BufferedReader(new FileReader (file))) {
while (br.ready())
Expand All @@ -150,48 +255,29 @@ public static void blobCreation(File file) throws IOException {
}
}
// adds a new line into the index file
try {
FileWriter fw = new FileWriter("./git/index", true);
BufferedWriter bufferedWriter = new BufferedWriter(fw);
// writes the content into index by first checking to see if the index file has been written into or not, (to determine if a /n is needed)
// and then if the file is a directory or not, (to determine if tree or blob) and then if the file is in a subdir or if it is in the home dir
// (to determine whether to write the parent dir or not)
FileReader checks = new FileReader("./git/index");
if (!checks.ready()) {
if (file.isDirectory()){
if(isInHomeDir(file))
bufferedWriter.write("tree " + name + " " + file.getName());
else
bufferedWriter.write("tree " + name + " " + file.getParentFile().getName() + "/" + file.getName());
}else{
if (isInHomeDir(file))
bufferedWriter.write("blob " + name + " " + file.getName());
else
bufferedWriter.write("blob " + name + " " + file.getParentFile().getName() + "/" + file.getName());
}
} else {
if (file.isDirectory()){
if (isInHomeDir(file))
bufferedWriter.write("\ntree " + name + " " + file.getName());
else
bufferedWriter.write("\ntree " + name + " " + file.getParentFile().getName() + "/" + file.getName());
} else {
if(isInHomeDir(file))
bufferedWriter.write("\nblob " + name + " " + file.getName());
else
bufferedWriter.write("\nblob " + name + " " + file.getParentFile().getName() + "/" + file.getName());
}
try (BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter("./git/index", true))) {
String entry = "";
File indexFile = new File ("./git/index");
String contents = fileContent(indexFile);
// Determine if it's a directory or a file and format the entry accordingly
if (!contents.contains(name)) {
if (file.isDirectory()) {
entry = "tree " + name + " " + file.getPath();
} else {
entry = "blob " + name + " " + file.getPath();
}
bufferedWriter.write(entry);
bufferedWriter.write("\n");
bufferedWriter.close();
}

// bufferedWriter.write(name + " " + file.getName() + "\n");
bufferedWriter.close();
checks.close();
} catch (IOException e) {
} catch (IOException e) {
e.printStackTrace();
}
}

}

private static boolean isInHomeDir (File file){
return file.getParentFile().getPath().equals(".");
return file.getPath().equals(".");
}
}
Binary file added GitInterface.class
Binary file not shown.
32 changes: 32 additions & 0 deletions GitInterface.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import java.io.IOException;

public interface GitInterface {
/**
* Stages a file for the next commit.
*
* @param filePath The path to the file to be staged.
*/
void stage(String filePath);

/**
* Creates a commit with the given author and message.
* It should capture the current state of the repository,
* update the HEAD, and return the commit hash.
*
* @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
*/
String commit(String author, String message) throws IOException;

/**
* EXTRA CREDIT: Checks out a specific commit given its hash.
* This should update the working directory to match the
* state of the repository at that commit.
*
* @param commitHash The SHA1 hash of the commit to check out.
* @throws IOException
*/
void checkout(String commitHash) throws IOException;
}
Binary file added GitTester.class
Binary file not shown.
11 changes: 7 additions & 4 deletions GitTester.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import java.nio.file.*;
import java.security.MessageDigest;
import java.io.*;

public class GitTester {
Expand All @@ -12,25 +10,30 @@ public static void main(String[] args) throws IOException {
File tester2 = fileCreation("tester2", "hi\nthis is sonarii");
Git.blobCreation(tester1);
Git.blobCreation(tester2);

File tester3 = fileCreation("tester3", "hmmm");
Git.blobCreation(tester3);


// testing blob creation: empty dir
File testDir = new File ("./testDir");
testDir.mkdir();
Git.blobCreation(testDir);

// testing blob creation: dir with files
File testDirFiles = new File ("./testDirFiles");
testDirFiles.mkdir();
Git.blobCreation(testDirFiles);


// testing blob creation: dir with files and subdirs
File testDirDirs = new File ("./testDirDirs");
File subDirs = new File ("./testDirDirs/test/testSub");
testDirDirs.mkdir();
subDirs.mkdirs();
Git.blobCreation(testDirDirs);
// testing file deletion
deleteTesters();

//deleteTesters();
}

// creates a file with given name and content
Expand Down
1 change: 1 addition & 0 deletions tempCodeRunnerFile.java
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@