242 lines
6.6 KiB
Java
242 lines
6.6 KiB
Java
import java.util.*;
|
|
import java.text.SimpleDateFormat;
|
|
|
|
public class Repository {
|
|
|
|
private String name;
|
|
private Commit head;
|
|
private int size;
|
|
|
|
public Repository(String name) {
|
|
if (name == null || name.isEmpty()) {
|
|
throw new IllegalArgumentException("Repository needs a name!");
|
|
}
|
|
|
|
this.name = name;
|
|
}
|
|
|
|
public String getRepoHead() {
|
|
if (head == null) {
|
|
return null;
|
|
}
|
|
return head.id;
|
|
}
|
|
|
|
public int getRepoSize() {
|
|
Commit temp = head;
|
|
int size = 0;
|
|
while (temp != null) {
|
|
size++;
|
|
temp = temp.past;
|
|
}
|
|
this.size = size;
|
|
return size;
|
|
}
|
|
|
|
public String toString() {
|
|
if (head == null) {
|
|
return name + " - No commits";
|
|
}
|
|
return name + " - Current head: " + head.toString();
|
|
}
|
|
|
|
public boolean contains(String targetId) {
|
|
Commit temp = head;
|
|
|
|
while (temp != null) {
|
|
if (temp.id.equals(targetId)) {
|
|
return true;
|
|
}
|
|
temp = temp.past;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
public String getHistory(int n) {
|
|
if (n <= 0) {
|
|
throw new IllegalArgumentException("do you want the history or not?");
|
|
}
|
|
|
|
Commit temp = head;
|
|
String history = "";
|
|
if (n > size) {
|
|
while (temp != null) {
|
|
history += temp.toString() + "\n";
|
|
temp = temp.past;
|
|
}
|
|
}
|
|
|
|
for (int i = 0; i < n && temp != null; i++) {
|
|
history += temp.toString() + "\n";
|
|
temp = temp.past;
|
|
}
|
|
|
|
return history;
|
|
}
|
|
|
|
public String commit(String message) {
|
|
if (head == null) {
|
|
head = new Commit(message);
|
|
return head.id;
|
|
}
|
|
Commit old = head;
|
|
head = new Commit(message, old);
|
|
size++;
|
|
return head.id;
|
|
}
|
|
|
|
public boolean drop(String targetId) {
|
|
// list is empty
|
|
if (head == null) {
|
|
return false;
|
|
}
|
|
|
|
size--;
|
|
Commit temp = head;
|
|
|
|
// front
|
|
if (temp.id.equals(targetId)) {
|
|
head = temp.past;
|
|
return true;
|
|
}
|
|
|
|
// middle
|
|
while (temp.past != null && temp.past.past != null) {
|
|
if (temp.past.id == targetId) {
|
|
temp.past = temp.past.past;
|
|
return true;
|
|
}
|
|
temp = temp.past;
|
|
}
|
|
|
|
// end
|
|
if (temp.past != null && temp.past.id.equals(targetId)) {
|
|
temp.past = null;
|
|
return true;
|
|
}
|
|
|
|
// if we get here, targetId was not found, return size to initial state
|
|
size++;
|
|
return false;
|
|
}
|
|
|
|
public void synchronize(Repository other) {
|
|
if (head == null && other.head == null) {
|
|
head = null;
|
|
} else if (head == null) {
|
|
head = other.head;
|
|
other.head = null;
|
|
} else if (other.head == null) {
|
|
other.head = null;
|
|
} else {
|
|
List<Commit> commitList = new ArrayList<>();
|
|
Comparator commitComparator = new Comparator<Commit>() {
|
|
public int compare(Commit one, Commit two) {
|
|
return Long.compare(one.timeStamp, two.timeStamp);
|
|
}
|
|
};
|
|
Commit temp = head;
|
|
while (temp != null) {
|
|
commitList.add(temp);
|
|
temp = temp.past;
|
|
}
|
|
temp = other.head;
|
|
while (temp != null) {
|
|
commitList.add(temp);
|
|
temp = temp.past;
|
|
}
|
|
commitList.sort(commitComparator);
|
|
Commit prev = null;
|
|
for (Commit commit : commitList) {
|
|
commit.past = prev;
|
|
prev = commit;
|
|
}
|
|
head = commitList.get(commitList.size() - 1);
|
|
other.head = null;
|
|
}
|
|
}
|
|
/**
|
|
* DO NOT MODIFY
|
|
* A class that represents a single commit in the repository.
|
|
* Commits are characterized by an identifier, a commit message,
|
|
* and the time that the commit was made. A commit also stores
|
|
* a reference to the immediately previous commit if it exists.
|
|
*
|
|
* Staff Note: You may notice that the comments in this
|
|
* class openly mention the fields of the class. This is fine
|
|
* because the fields of the Commit class are public. In general,
|
|
* be careful about revealing implementation details!
|
|
*/
|
|
public class Commit {
|
|
|
|
private static int currentCommitID;
|
|
|
|
/**
|
|
* The time, in milliseconds, at which this commit was created.
|
|
*/
|
|
public final long timeStamp;
|
|
|
|
/**
|
|
* A unique identifier for this commit.
|
|
*/
|
|
public final String id;
|
|
|
|
/**
|
|
* A message describing the changes made in this commit.
|
|
*/
|
|
public final String message;
|
|
|
|
/**
|
|
* A reference to the previous commit, if it exists. Otherwise, null.
|
|
*/
|
|
public Commit past;
|
|
|
|
/**
|
|
* Constructs a commit object. The unique identifier and timestamp
|
|
* are automatically generated.
|
|
* @param message A message describing the changes made in this commit.
|
|
* @param past A reference to the commit made immediately before this
|
|
* commit.
|
|
*/
|
|
public Commit(String message, Commit past) {
|
|
this.id = "" + currentCommitID++;
|
|
this.message = message;
|
|
this.timeStamp = System.currentTimeMillis();
|
|
this.past = past;
|
|
}
|
|
|
|
/**
|
|
* Constructs a commit object with no previous commit. The unique
|
|
* identifier and timestamp are automatically generated.
|
|
* @param message A message describing the changes made in this commit.
|
|
*/
|
|
public Commit(String message) {
|
|
this(message, null);
|
|
}
|
|
|
|
/**
|
|
* Returns a string representation of this commit. The string
|
|
* representation consists of this commit's unique identifier,
|
|
* timestamp, and message, in the following form:
|
|
* "[identifier] at [timestamp]: [message]"
|
|
* @return The string representation of this collection.
|
|
*/
|
|
@Override
|
|
public String toString() {
|
|
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd 'at' HH:mm:ss z");
|
|
Date date = new Date(timeStamp);
|
|
|
|
return id + " at " + formatter.format(date) + ": " + message;
|
|
}
|
|
|
|
/**
|
|
* Resets the IDs of the commit nodes such that they reset to 0.
|
|
* Primarily for testing purposes.
|
|
*/
|
|
public static void resetIds() {
|
|
Commit.currentCommitID = 0;
|
|
}
|
|
}
|
|
}
|