Skip to content
Open

Gp 4 #14

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
148 changes: 148 additions & 0 deletions CommitCreator.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
import java.io.*;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;


/**
* Follows Milestone GP-4.2 instructions
* 1. Ensure repo is initialized and files are staged
* 2. Call TREE.createROOT to snapshot the working directory into tree objects
* 3. Call CommitCreator.createCommit with author and message
*
* Commit file layout
* tree: <root tree sha1>
* parent: <previous commit sha1> (omit this line for the first commit)
* author: <author name>
* date: <date string>
* message: <summary>
*/
public class CommitCreator {


public static String createCommit(String author, String message) {
ensureRepo();


// Build a fresh root tree from the current working directory
TREE.createROOT();


// Find the root tree hash
String rootHash = TraceTree.findRootTreeHash();
if (rootHash == null || rootHash.isEmpty()) {
System.out.println("No root tree found. Run staging and TREE.createROOT first");
return null;
}


// Read parent from HEAD if present
String parentHash = readHead();


// Build commit text
StringBuilder sb = new StringBuilder();
sb.append("tree: ").append(rootHash).append("\n");
if (parentHash != null && !parentHash.isEmpty()) {
sb.append("parent: ").append(parentHash).append("\n");
}
sb.append("author: ").append(author).append("\n");
sb.append("date: ").append(nowString()).append("\n");
sb.append("message: ").append(message).append("\n");
String commitText = sb.toString();


// Hash of the whole commit content
String commitHash = SHA1.encryptThisString(commitText);


// Save commit object file
File commitFile = new File("git/objects/" + commitHash);
writeString(commitFile, commitText);


// Update HEAD to point at this commit
writeString(new File("git/HEAD"), commitHash);


System.out.println("Commit created: " + commitHash);
return commitHash;
}


private static void ensureRepo() {
File git = new File("git");
if (!git.exists()) {
GitRepositoryInitializer.initGitRepo();
}
File objects = new File("git/objects");
if (!objects.exists()) {
objects.mkdir();
}
File index = new File("git/index");
if (!index.exists()) {
try {
index.createNewFile();
} catch (IOException e) {
System.out.println(e);
}
}
File head = new File("git/HEAD");
if (!head.exists()) {
try {
head.createNewFile();
}
catch (IOException e) {
System.out.println(e);
}
}
}


private static String readHead() {
File head = new File("git/HEAD");
if (!head.exists()) {
return null;
}
String text = readString(head);
if (text == null) {
return null;
}
text = text.trim();
if (text.isEmpty()) {
return null;
}
return text;
}


private static String nowString() {
LocalDateTime now = LocalDateTime.now();
DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
return now.format(fmt);
}


private static String readString(File file) {
StringBuilder sb = new StringBuilder();
try (BufferedReader br = new BufferedReader(new FileReader(file))) {
String line;
while ((line = br.readLine()) != null) {
sb.append(line).append("\n");
}
}
catch (IOException e) {
return null;
}
return sb.toString();
}


private static void writeString(File file, String text) {
try (BufferedWriter bw = new BufferedWriter(new FileWriter(file))) {
bw.write(text);
}
catch (IOException e) {
System.out.println(e);
}
}
}
193 changes: 193 additions & 0 deletions CommitTester.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,193 @@
import java.io.*;
import java.nio.file.Files;

public class CommitTester {
public static void main(String[] args) throws Exception {
System.out.println("Commit tester start");
cleanup();
GitRepositoryInitializer.initGitRepo();

// Create a small working directory
File work = new File("work");
work.mkdir();
File sub = new File("work/sub");
sub.mkdir();
File a = new File("work/a.txt");
File b = new File("work/sub/b.txt");
a.createNewFile();
b.createNewFile();
Files.write(a.toPath(), "alpha".getBytes());
Files.write(b.toPath(), "beta".getBytes());

// Stage and snapshot
BLOB.addFile("work/a.txt");
BLOB.addFile("work/sub/b.txt");
TREE.createROOT();

// Create first commit
String c1 = CommitCreator.createCommit("user", "initial snapshot");
System.out.println("\nFirst commit: " + c1);
printCommitFile(c1);
checkCommitFormat(c1, true);

// Modify a file and create another commit
Files.write(a.toPath(), "alpha v2".getBytes());
BLOB.addFile("work/a.txt");
TREE.createROOT();
String c2 = CommitCreator.createCommit("user", "updated a.txt");
System.out.println("\nSecond commit: " + c2);
printCommitFile(c2);
checkCommitFormat(c2, false);

System.out.println("\nHEAD now points to: " + readHead());

// Clean up working directory and git folder
deleteRecursively(work);
cleanup();

System.out.println("Commit tester end");
}

private static void printCommitFile(String commitHash) {
if (commitHash == null || commitHash.isEmpty()) {
System.out.println("No commit hash to print.");
return;
}
File commitFile = new File("git/objects/" + commitHash);
if (!commitFile.exists()) {
System.out.println("Commit file not found: " + commitHash);
return;
}

System.out.println("----- Commit File Content -----");
try (BufferedReader br = new BufferedReader(new FileReader(commitFile))) {
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
}
catch (IOException e) {
System.out.println("Error reading commit file: " + e.getMessage());
}
System.out.println("----- End of Commit File -----\n");
}

private static void checkCommitFormat(String commitHash, boolean firstCommit) {
if (commitHash == null || commitHash.isEmpty()) {
System.out.println("No commit hash to verify.");
return;
}
File commitFile = new File("git/objects/" + commitHash);
if (!commitFile.exists()) {
System.out.println("Commit file not found: " + commitHash);
return;
}

try (BufferedReader br = new BufferedReader(new FileReader(commitFile))) {
String line;
int lineNumber = 0;
boolean hasTree = false;
boolean hasParent = false;
boolean hasAuthor = false;
boolean hasDate = false;
boolean hasMessage = false;
boolean inOrder = true;

while ((line = br.readLine()) != null) {
lineNumber++;
if (line.startsWith("tree:")) {
hasTree = true;
if (lineNumber != 1) {
inOrder = false;
}
}
else if (line.startsWith("parent:")) {
hasParent = true;
if (firstCommit) {
System.out.println("Warning: first commit should not have parent line.");
}
}
else if (line.startsWith("author:")) {
hasAuthor = true;
}
else if (line.startsWith("date:")) {
hasDate = true;
}
else if (line.startsWith("message:")) {
hasMessage = true;
}
}

if (!hasTree || !hasAuthor || !hasDate || !hasMessage) {
System.out.println("Commit format incorrect for: " + commitHash);
if (!hasTree) {
System.out.println("Missing 'tree:' line");
}
if (!firstCommit && !hasParent) {
System.out.println("Missing 'parent:' line for non-initial commit");
}
if (!hasAuthor) {
System.out.println("Missing 'author:' line");
}
if (!hasDate) {
System.out.println("Missing 'date:' line");
}
if (!hasMessage) {
System.out.println("Missing 'message:' line");
}
}
else if (!inOrder) {
System.out.println("Commit has all lines but order may be incorrect.");
}
else {
System.out.println("Commit file format verified for: " + commitHash);
}
}
catch (IOException e) {
System.out.println("Error reading commit file: " + e.getMessage());
}
}

private static void cleanup() {
File git = new File("git");
if (git.exists()) {
deleteRecursively(git);
}
}

private static void deleteRecursively(File file) {
if (file == null) {
return;
}
if (!file.exists()) {
return;
}
if (file.isDirectory()) {
File[] kids = file.listFiles();
if (kids != null) {
for (File k : kids) {
deleteRecursively(k);
}
}
}
file.delete();
}

private static String readHead() {
File head = new File("git/HEAD");
if (!head.exists()) {
return "";
}
StringBuilder sb = new StringBuilder();
try (BufferedReader br = new BufferedReader(new FileReader(head))) {
String line;
while ((line = br.readLine()) != null) {
sb.append(line).append("\\n");
}
}
catch (IOException e) {
return "";
}
return sb.toString().trim();
}
}
Loading