+1 (315) 557-6473 

Program To Build a Gitlet Program Using Java Programming Language Assignment Solution.


Instructions

Objective
Write a java assignment program to build gitlet program using programming language.

Requirements and Specifications

Create a gitlet program.
Source Code
package gitlet;
import java.io.File;
import java.io.IOException;
import java.nio.file.*;
import java.util.*;
import java.util.stream.Collectors;
public class Gitlet implements Saveable, Dumpable {
    private static final Set temp = new HashSet<>();
    static {
        temp.add("gitlet.iml");
        temp.add("src");
        temp.add("samples");
        temp.add("out");
        temp.add("lib");
        temp.add(".idea");
    }
    public static final String GITLET_HIDDEN_FOLDER = ".gitlet";
    public static final String STAGING_FOLDER = "staging";
    public static final String STAGING_RM_FOLDER = "staging-rm";
    private static final String MAIN_FILENAME = "gitlet-main";
    private transient Collection branches;
    private Collection branchHashes;
    private transient Branch currentBranch;
    private String currentBranchHash;
    private transient Commit currentCommit;
    private String currentCommitHash;
    private Gitlet(Collection branches, Branch currentBranch, Commit currentCommit) {
        this.branches = branches;
        this.currentBranch = currentBranch;
        this.currentCommit = currentCommit;
    }
    public void add(String fileName) {
        Path path = Paths.get(fileName);
        if (!Files.exists(path)) {
            throw new GitletException("File does not exist");
        }
        Blob blob = currentCommit.getBlob(fileName);
        try {
            unstageFileForRemove(fileName);
            if (blob != null) {
                if (areEquals(fileName, blob)) {
                    unstageFile(fileName);
                    return;
                }
            }
            stageFile(fileName);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    public void commit(String commitMessage) {
        commit(commitMessage, null);
    }
    private void commit(String commitMessage, Commit commit) {
        if (commitMessage.isEmpty()) {
            throw new GitletException("Please, enter a commit message");
        }
        Map fileTree = new HashMap<>(currentCommit.getFileTree());
        try {
            if (!hasStagingChanges()) {
                throw new GitletException("No changes added to the commit");
            }
            applyStagingChangesToFileTree(fileTree);
            clearStagingArea();
            Collection parentCommits = new ArrayList<>();
            parentCommits.add(currentCommit);
            if (commit != null) {
                parentCommits.add(commit);
            }
            currentCommit = new Commit(commitMessage, System.currentTimeMillis(), fileTree, parentCommits);
            for (Branch branch : branches) {
                if (branch.getName().equals(currentBranch.getName())) {
                    branch.setHead(currentCommit);
                    break;
                }
            }
            save(Paths.get(GITLET_HIDDEN_FOLDER, MAIN_FILENAME).toFile());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    public void rm(String fileName) {
        boolean removed = false;
        try {
            removed = unstageFile(fileName);
            Blob blob = currentCommit.getBlob(fileName);
            if (blob != null) {
                Files.createFile(Paths.get(GITLET_HIDDEN_FOLDER, STAGING_RM_FOLDER, fileName));
                Files.deleteIfExists(Paths.get(fileName));
                removed = true;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        if (!removed) {
            throw new GitletException("No reason to remove the file");
        }
    }
    public void log() {
        Commit commit = currentCommit;
        while (commit != null) {
            System.out.println(commit.log());
            Collection parent = commit.getParentCommits();
            if (parent.isEmpty()) {
                commit = null;
            } else {
                commit = parent.iterator().next();
            }
        }
    }
    public void globalLog() {
        for (Commit commit : collectAllCommits()) {
            System.out.println(commit.log());
        }
    }
    public void find(String message) {
        boolean found = false;
        for (Commit commit : collectAllCommits()) {
            if (commit.getCommitMessage().contains(message)) {
                found = true;
                System.out.println(commit.getCommitId());
            }
        }
        if (!found) {
            throw new GitletException("Found no commit with that message");
        }
    }
    public void status() {
        System.out.println("=== Branches ===");
        List sortedBranches = new ArrayList<>(branches);
        sortedBranches.sort(Comparator.comparing(Branch::getName));
        for (Branch branch : sortedBranches) {
            if (branch.getName().equals(currentBranch.getName())) {
                System.out.println("*" + branch.getName());
            } else {
                System.out.println(branch.getName());
            }
        }
        System.out.println();
        System.out.println("=== Staged Files ===");
        List sortedStaged = null;
        try {
           sortedStaged = getStagedFiles().stream().sorted(Comparator.naturalOrder())
                            .collect(Collectors.toList());
            for (String staged : sortedStaged) {
                System.out.println(staged);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        System.out.println();
        System.out.println("=== Removed Files ===");
        List sortedRemoved = getTrackedFiles()
                        .stream().filter(p -> !Files.exists(Paths.get(p)))
                        .sorted(Comparator.naturalOrder()).collect(Collectors.toList());
        for (String removed : sortedRemoved) {
            System.out.println(removed);
        }
        System.out.println();
        System.out.println("=== Modifications Not Staged For Commit ===");
        Map fileTree = currentCommit.getFileTree();
        Map modificationMap = new HashMap<>();
        for (Map.Entry pair : fileTree.entrySet()) {
            Path path = Paths.get(pair.getKey());
            if( Files.exists(Paths.get(GITLET_HIDDEN_FOLDER, STAGING_RM_FOLDER, pair.getKey()))) {
                continue;
            }
            if (!Files.exists(path)) {
                modificationMap.put(pair.getKey(), "deleted");
            } else {
                try {
                    byte[] bytes = Files.readAllBytes(path);
                    if (!Arrays.equals(bytes, pair.getValue().getBytes())) {
                        modificationMap.put(pair.getKey(), "modified");
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        List> sortedModified = new ArrayList<>(modificationMap.entrySet());
        sortedModified.sort(Map.Entry.comparingByKey());
        for (Map.Entry pair : sortedModified) {
            System.out.println(pair.getKey() + " (" + pair.getValue() + ")");
        }
        System.out.println();
        try {
            System.out.println("=== Untracked Files ===");
            Collection tracked = new ArrayList<>(fileTree.keySet());
            tracked.addAll(sortedStaged);
            List untracked = Files.list(Paths.get(""))
                    .map(p -> p.toFile().getName())
                    .filter(p -> !p.equals(GITLET_HIDDEN_FOLDER))
                    .filter(p -> !tracked.contains(p)).sorted(String::compareTo)
                    .collect(Collectors.toList());
            for (String untrackedFile : untracked) {
                System.out.println(untrackedFile);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    public void checkout(Path fileName) {
        Blob blob = currentCommit.getBlob(fileName.toFile().getName());
        if (blob == null) {
            throw new GitletException("File does not exist in that commit");
        }
        try {
            Files.deleteIfExists(fileName);
            Files.write(fileName, blob.getBytes());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    public void checkout(String commitId, Path fileName) {
        Set allCommits = collectAllCommits();
        Commit foundCommit = null;
        for (Commit commit : allCommits) {
            if (commit.getCommitId().startsWith(commitId)) {
                foundCommit = commit;
                break;
            }
        }
        if (foundCommit == null) {
            throw new GitletException("No commit with that id exists");
        }
        Blob blob = foundCommit.getBlob(fileName.toFile().getName());
        if (blob == null) {
            throw new GitletException("File does not exist in that commit");
        }
        try {
            Files.deleteIfExists(fileName);
            Files.write(fileName, blob.getBytes());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    public void checkout(String branchName) {
        if (branchName.equals(currentBranch.getName())) {
            throw new GitletException("No need to checkout the current branch");
        }
        Branch foundBranch = null;
        for (Branch branch : branches) {
            if (branchName.equals(branch.getName())) {
                foundBranch = branch;
                break;
            }
        }
        if (foundBranch == null) {
            throw new GitletException("No such branch exists.");
        }
        Commit commit = foundBranch.getHead();
        try {
            for (Path filePath : Files.list(Paths.get("")).collect(Collectors.toList())) {
                if (temp.contains(filePath.toString()))
                    continue;
                if (filePath.toString().equals(GITLET_HIDDEN_FOLDER))
                    continue;
                Blob blob = commit.getBlob(filePath.toString());
                if (blob != null) {
                    if (currentCommit.getBlob(filePath.toString()) == null) {
                        throw new GitletException("There is an untracked file in the way; delete it, or add and commit it first.");
                    }
                }
            }
            for (Path filePath : Files.list(Paths.get("")).collect(Collectors.toList())) {
                if (temp.contains(filePath.toString()))
                    continue;
                if (filePath.toString().equals(GITLET_HIDDEN_FOLDER))
                    continue;
                Files.deleteIfExists(filePath);
            }
            for (Map.Entry pair : commit.getFileTree().entrySet()) {
                Blob blob = pair.getValue();
                Files.write(Paths.get(pair.getKey()), blob.getBytes());
            }
            currentBranch = foundBranch;
            currentCommit = commit;
            save(Paths.get(GITLET_HIDDEN_FOLDER, MAIN_FILENAME).toFile());
        } catch (IOException e) {
        }
    }
    public void branch(String branchName) {
        for (Branch branch : branches) {
            if (branchName.equals(branch.getName())) {
                throw new GitletException("A branch with that name already exists.");
            }
        }
        Branch newBranch = new Branch(branchName, currentCommit);
        branches.add(newBranch);
        save(Paths.get(GITLET_HIDDEN_FOLDER, MAIN_FILENAME).toFile());
    }
    public void rmBranch(String branchName) {
        if (branchName.equals(currentBranch.getName())) {
            throw new GitletException("Cannot remove the current branch.");
        }
        Branch foundBranch = null;
        for (Branch branch : branches) {
            if (branchName.equals(branch.getName())) {
                foundBranch = branch;
                break;
            }
        }
        if (foundBranch == null) {
            throw new GitletException("A branch with that name does not exist.");
        }
        branches.remove(foundBranch);
        save(Paths.get(GITLET_HIDDEN_FOLDER, MAIN_FILENAME).toFile());
    }
    public void reset(String commitId) {
        Commit foundCommit = getCommitById(commitId);
        try {
            checkUntrackedOverwritten(foundCommit);
            clearWorkingDirectory();
            clearStagingArea();
            for (Map.Entry pair : foundCommit.getFileTree().entrySet()) {
                Blob blob = pair.getValue();
                Files.write(Paths.get(pair.getKey()), blob.getBytes());
            }
            currentCommit = foundCommit;
            save(Paths.get(GITLET_HIDDEN_FOLDER, MAIN_FILENAME).toFile());
        } catch (IOException e) {
        }
    }
    public void merge(String branchName) {
        if (branchName.equals(currentBranch.getName())) {
            throw new GitletException("Cannot merge a branch with itself.");
        }
        Branch foundBranch = null;
        for (Branch branch : branches) {
            if (branchName.equals(branch.getName())) {
                foundBranch = branch;
                break;
            }
        }
        if (foundBranch == null) {
            throw new GitletException("A branch with that name does not exist.");
        }
        try {
            if (Files.list(Paths.get(GITLET_HIDDEN_FOLDER, STAGING_FOLDER)).count() > 0 ||
                    Files.list(Paths.get(GITLET_HIDDEN_FOLDER, STAGING_RM_FOLDER)).count() > 0) {
                throw new GitletException("You have uncommitted changes.");
            }
        }
        catch (IOException e) {
        }
        Commit splitPoint = getSplitPoint(foundBranch);
        if (splitPoint.equals(currentCommit)) {
            throw new GitletException("Current branch fast-forwarded.");
        }
        if (splitPoint.equals(foundBranch.getHead())) {
            throw new GitletException("Given branch is an ancestor of the current branch.");
        }
        Collection currentModified = getModified(splitPoint, currentCommit);
        Collection currentAdded = getAdded(splitPoint, currentCommit);
        Collection currentRemoved = getAdded(currentCommit, splitPoint);
        Collection givenModified = getModified(splitPoint, foundBranch.getHead());
        Collection givenAdded = getAdded(splitPoint, foundBranch.getHead());
        Collection givenRemoved = getAdded(foundBranch.getHead(), splitPoint);
        try {
            if (hasStagingChanges()) {
                throw new GitletException("You have uncommitted changes.");
            }
            Collection changedFiles = new HashSet<>();
            changedFiles.addAll(givenModified);
            changedFiles.addAll(givenRemoved);
            changedFiles.addAll(givenAdded);
            for (String changedFile : changedFiles) {
                if (getUntrackedFiles().contains(changedFile)) {
                    throw new GitletException("There is an untracked file in the way; delete it, or add and commit it first.");
                }
            }
            boolean conflict = false;
            for (String givenModifiedFile : givenModified) {
                if (!currentModified.contains(givenModifiedFile) && !currentRemoved.contains(givenModifiedFile)) {
                    checkout(foundBranch.getHead().getCommitId(), Paths.get(givenModifiedFile));
                    stageFile(givenModifiedFile);
                }
                Blob givenBlob = foundBranch.getHead().getBlob(givenModifiedFile);
                if (currentModified.contains(givenModifiedFile)) {
                    Blob currentBlob = currentCommit.getBlob(givenModifiedFile);
                    if (!areEquals(currentBlob, givenBlob)) {
                        conflict = true;
                        mergeConfictFiles(givenModifiedFile, currentBlob, givenBlob);
                        stageFile(givenModifiedFile);
                    }
                }
                if (currentRemoved.contains(givenModifiedFile)) {
                    conflict = true;
                    mergeConfictFiles(givenModifiedFile, null, givenBlob);
                    stageFile(givenModifiedFile);
                }
            }
            for (String givenAddedFile : givenAdded) {
                if (!currentAdded.contains(givenAddedFile)) {
                    checkout(foundBranch.getHead().getCommitId(), Paths.get(givenAddedFile));
                    stageFile(givenAddedFile);
                }
                if (currentAdded.contains(givenAddedFile)) {
                    Blob givenBlob = foundBranch.getHead().getBlob(givenAddedFile);
                    Blob currentBlob = currentCommit.getBlob(givenAddedFile);
                    if (!areEquals(currentBlob, givenBlob)) {
                        conflict = true;
                        mergeConfictFiles(givenAddedFile, currentBlob, givenBlob);
                        stageFile(givenAddedFile);
                    }
                }
            }
            for (String givenRemovedFile : givenRemoved) {
                if (!currentModified.contains(givenRemovedFile) && !currentRemoved.contains(givenRemovedFile)) {
                    rm(givenRemovedFile);
                }
                if (currentModified.contains(givenRemovedFile)) {
                    Blob currentBlob = currentCommit.getBlob(givenRemovedFile);
                    conflict = true;
                    mergeConfictFiles(givenRemovedFile, currentBlob, null);
                    stageFile(givenRemovedFile);
                }
            }
            commit("Merged " + branchName + " into " + currentBranch.getName() + ".", foundBranch.getHead());
            if (conflict) {
                throw new GitletException("Encountered a merge conflict.");
            }
        } catch (IOException e) {
        }
    }
    @Override
    public void save(File file) {
        Saveable.super.save(file);
        for (Branch branch : branches) {
            String branchHash = Utils.sha1(branch.getName());
            File branchFile = Paths.get(GITLET_HIDDEN_FOLDER, branchHash).toFile();
            branch.save(branchFile);
        }
    }
    @Override
    public void calculateHashes() {
        branchHashes = new ArrayList<>();
        for (Branch branch : branches) {
            branchHashes.add(Utils.sha1(branch.getName()));
        }
        currentBranchHash = Utils.sha1(currentBranch.getName());
        currentCommitHash = currentCommit.getCommitId();
    }
    @Override
    public void dump() {
        String result = "Number of branches: " + branchHashes.size() + System.lineSeparator() +
                "Current branch: " + currentBranchHash + System.lineSeparator() +
                "Current commit: " + currentCommitHash + System.lineSeparator();
        System.out.println(result);
    }
    public static void init() {
        if (Files.exists(Paths.get(GITLET_HIDDEN_FOLDER))) {
            throw new GitletException("A Gitlet version-control system already exists in the current directory.");
        }
        try {
            Files.createDirectory(Paths.get(GITLET_HIDDEN_FOLDER));
            Files.createDirectory(Paths.get(GITLET_HIDDEN_FOLDER, STAGING_FOLDER));
            Files.createDirectory(Paths.get(GITLET_HIDDEN_FOLDER, STAGING_RM_FOLDER));
            Commit commit = new Commit("initial commit", 0);
            Branch branch = new Branch("master", commit);
            Gitlet gitlet = new Gitlet(Collections.singletonList(branch), branch, commit);
            gitlet.save(Paths.get(GITLET_HIDDEN_FOLDER, MAIN_FILENAME).toFile());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    public static Gitlet run() {
        if (!Files.exists(Paths.get(GITLET_HIDDEN_FOLDER))) {
            throw new GitletException("Not in an initialized Gitlet directory.");
        }
        assert Files.exists(Paths.get(GITLET_HIDDEN_FOLDER, STAGING_FOLDER));
        return load(Paths.get(GITLET_HIDDEN_FOLDER, MAIN_FILENAME).toFile());
    }
    public static Gitlet load(File file) {
        Gitlet gitlet = Utils.readObject(file, Gitlet.class);
        gitlet.currentCommit = Commit.load(Paths.get(GITLET_HIDDEN_FOLDER, gitlet.currentCommitHash).toFile());
        gitlet.currentBranch = Branch.load(Paths.get(GITLET_HIDDEN_FOLDER, gitlet.currentBranchHash).toFile());
        gitlet.branches = new ArrayList<>();
        for (String branchHash : gitlet.branchHashes) {
            gitlet.branches.add(Branch.load(Paths.get(GITLET_HIDDEN_FOLDER, branchHash).toFile()));
        }
        return gitlet;
    }
    private Set collectAllCommits() {
        Set allCommits = new HashSet<>();
        for (Branch branch : branches) {
            collectAllCommitsStep(branch.getHead(), allCommits);
        }
        return allCommits;
    }
    private void collectAllCommitsStep(Commit commit, Set allCommits) {
        allCommits.add(commit);
        for (Commit parent : commit.getParentCommits()) {
            collectAllCommitsStep(parent, allCommits);
        }
    }
    private void clearStagingArea() throws IOException {
        clearArea(Paths.get(GITLET_HIDDEN_FOLDER, STAGING_FOLDER));
        clearArea(Paths.get(GITLET_HIDDEN_FOLDER, STAGING_RM_FOLDER));
    }
    private void clearWorkingDirectory() throws IOException {
        clearArea(Paths.get(""));
    }
    private void clearArea(Path path) throws IOException {
        Files.list(path)
                .forEach(p -> {
                    try {
                        if ((!p.toString().equals(GITLET_HIDDEN_FOLDER))
                                && (!temp.contains(p.toString())))
                            Files.deleteIfExists(p);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                });
    }
    private void checkUntrackedOverwritten(Commit newCommit) throws IOException {
        for (Path filePath : Files.list(Paths.get("")).collect(Collectors.toList())) {
            if (temp.contains(filePath.toString()))
                continue;
            if (filePath.toString().equals(GITLET_HIDDEN_FOLDER))
                continue;
            Blob blob = newCommit.getBlob(filePath.toString());
            if (blob != null) {
                if (currentCommit.getBlob(filePath.toString()) == null) {
                    throw new GitletException("There is an untracked file in the way; delete it, or add and commit it first.");
                }
            }
        }
    }
    private Commit getSplitPoint(Branch branch) {
        Map prevCommits = new HashMap<>();
        getPrevCommitsStep(prevCommits, 0, currentCommit);
        Set givenBranchCommits = new HashSet<>();
        collectAllCommitsStep(branch.getHead(), givenBranchCommits);
        String splitPoint = null;
        int distance = Integer.MAX_VALUE;
        for (Commit commit : givenBranchCommits) {
            if (prevCommits.containsKey(commit.getCommitId())) {
                int currDistance = prevCommits.get(commit.getCommitId());
                if (currDistance < distance) {
                    splitPoint = commit.getCommitId();
                    distance = currDistance;
                }
            }
        }
        return getCommitById(splitPoint);
    }
    private void getPrevCommitsStep(Map prevCommits, int distance, Commit commit) {
        prevCommits.put(commit.getCommitId(), distance);
        if (commit.getParentCommits() != null) {
            for (Commit parentCommit : commit.getParentCommits()) {
                getPrevCommitsStep(prevCommits, distance + 1, parentCommit);
            }
        }
    }
    private Commit getCommitById(String commitId) {
        Collection allCommits = collectAllCommits();
        Commit foundCommit = null;
        for (Commit commit : allCommits) {
            if (commit.getCommitId().startsWith(commitId)) {
                foundCommit = commit;
                break;
            }
        }
        if (foundCommit == null) {
            throw new GitletException("No commit with that id exists.");
        }
        return foundCommit;
    }
    private Collection getAdded(Commit oldCommit, Commit newCommit) {
        Collection result = new ArrayList<>();
        Map oldTree = oldCommit.getFileTree();
        Map newTree = newCommit.getFileTree();
        for (Map.Entry pair : newTree.entrySet()) {
            String file = pair.getKey();
            if (!oldTree.containsKey(file)) {
                result.add(file);
            }
        }
        return result;
    }
    private Collection getModified(Commit oldCommit, Commit newCommit) {
        Collection result = new ArrayList<>();
        Map oldTree = oldCommit.getFileTree();
        Map newTree = newCommit.getFileTree();
        for (Map.Entry pair : oldTree.entrySet()) {
            String file = pair.getKey();
            if (newTree.containsKey(file)) {
                byte[] oldBytes = pair.getValue().getBytes();
                byte[] newBytes = newTree.get(file).getBytes();
                if (!Arrays.equals(oldBytes, newBytes)) {
                    result.add(file);
                }
            }
        }
        return result;
    }
    private void stageFile(String fileName) throws IOException{
        Files.copy(Paths.get(fileName), Paths.get(GITLET_HIDDEN_FOLDER, STAGING_FOLDER, fileName));
    }
    private boolean unstageFile(String fileName) throws IOException {
        Path path = Paths.get(GITLET_HIDDEN_FOLDER, STAGING_FOLDER, fileName);
        boolean removed = Files.exists(path);
        if (removed) {
            Files.delete(path);
            return true;
        }
        return false;
    }
    private boolean unstageFileForRemove(String fileName) throws IOException {
        Path path = Paths.get(GITLET_HIDDEN_FOLDER, STAGING_RM_FOLDER, fileName);
        boolean removed = Files.exists(path);
        if (removed) {
            Files.delete(path);
            return true;
        }
        return false;
    }
    private boolean areEquals(String fileName, Blob blob) throws IOException {
        byte[] bytes = Files.readAllBytes(Paths.get(fileName));
        return Arrays.equals(bytes, blob.getBytes());
    }
    private boolean areEquals(Blob blob1, Blob blob2) throws IOException {
        return Arrays.equals(blob1.getBytes(), blob2.getBytes());
    }
    private boolean hasStagingChanges() throws IOException{
        return (Files.list(Paths.get(GITLET_HIDDEN_FOLDER, STAGING_FOLDER)).count() != 0)
                || (Files.list(Paths.get(GITLET_HIDDEN_FOLDER, STAGING_RM_FOLDER)).count() != 0);
    }
    private void applyStagingChangesToFileTree(Map fileTree) throws IOException {
        Files.list(Paths.get(GITLET_HIDDEN_FOLDER, STAGING_FOLDER)).forEach(path -> {
                    try {
                        byte[] bytes = Files.readAllBytes(path);
                        File file = path.toFile();
                        Blob blob = new Blob(file.getName(), file.lastModified(), bytes);
                        fileTree.put(file.getName(), blob);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
        );
        Files.list(Paths.get(GITLET_HIDDEN_FOLDER, STAGING_RM_FOLDER)).forEach(path -> {
                    File file = path.toFile();
                    fileTree.remove(file.getName());
                }
        );
    }
    private Set getStagedFiles() throws IOException {
        return Files.list(Paths.get(GITLET_HIDDEN_FOLDER, STAGING_FOLDER))
                .map(p -> p.toFile().getName()).collect(Collectors.toSet());
    }
    private Set getTrackedFiles() {
        return getTrackedFiles(currentCommit);
    }
    private Set getTrackedFiles(Commit commit) {
        return commit.getFileTree().keySet();
    }
    private Set getUntrackedFiles() throws IOException{
        return getUntrackedFiles(currentCommit);
    }
    private Set getUntrackedFiles(Commit commit) throws IOException {
        return Files.list(Paths.get("")).map(p -> p.toFile().getName())
                .filter(f -> !getTrackedFiles(commit).contains(f))
                .filter(f -> !temp.contains(f)).collect(Collectors.toSet());
    }
    private void mergeConfictFiles(String fileName, Blob currentBlob, Blob givenBlob) throws IOException {
        String content = "<<<<<< HEAD" + System.lineSeparator()
                + (currentBlob == null ? "" : new String(currentBlob.getBytes())) + "======" + System.lineSeparator()
                + (givenBlob == null ? "" : new String(givenBlob.getBytes())) + ">>>>>>";
        Files.write(Paths.get(fileName), content.getBytes());
    }
}