From 9a921429f7f41d5d0ce56a1f8195c1593345d561 Mon Sep 17 00:00:00 2001 From: Anton Date: Sun, 23 Sep 2018 00:22:20 +0300 Subject: [PATCH 1/5] code from HW 1 --- hw_git_2/pom.xml | 64 ++++++ hw_git_2/src/main/java/hw_git/GitCli.java | 46 ++++ hw_git_2/src/main/java/hw_git/GitCore.java | 197 ++++++++++++++++++ .../src/main/java/hw_git/RepInformation.java | 39 ++++ .../java/hw_git/UnversionedException.java | 5 + hw_git_2/src/test/java/hw_git/AppTest.java | 115 ++++++++++ 6 files changed, 466 insertions(+) create mode 100644 hw_git_2/pom.xml create mode 100644 hw_git_2/src/main/java/hw_git/GitCli.java create mode 100644 hw_git_2/src/main/java/hw_git/GitCore.java create mode 100644 hw_git_2/src/main/java/hw_git/RepInformation.java create mode 100644 hw_git_2/src/main/java/hw_git/UnversionedException.java create mode 100644 hw_git_2/src/test/java/hw_git/AppTest.java diff --git a/hw_git_2/pom.xml b/hw_git_2/pom.xml new file mode 100644 index 0000000..8284e27 --- /dev/null +++ b/hw_git_2/pom.xml @@ -0,0 +1,64 @@ + + 4.0.0 + + 1 + hw_git_1 + 0.0.1-SNAPSHOT + jar + + hw_git_1 + http://maven.apache.org + + + UTF-8 + + + + + maven-compiler-plugin + + 1.8 + 1.8 + UTF-8 + + + + + + + + junit + junit + 4.12 + test + + + + + + com.fasterxml.jackson.core + jackson-core + 2.9.6 + + + + com.fasterxml.jackson.core + jackson-annotations + 2.9.6 + + + + com.fasterxml.jackson.core + jackson-databind + 2.9.6 + + + + + org.apache.commons + commons-io + 1.3.2 + + + diff --git a/hw_git_2/src/main/java/hw_git/GitCli.java b/hw_git_2/src/main/java/hw_git/GitCli.java new file mode 100644 index 0000000..ffa7e0c --- /dev/null +++ b/hw_git_2/src/main/java/hw_git/GitCli.java @@ -0,0 +1,46 @@ +package hw_git; + +import java.io.IOException; +import java.util.Arrays; + +import com.fasterxml.jackson.core.JsonGenerationException; +import com.fasterxml.jackson.databind.JsonMappingException; + +public class GitCli { + public static void main(String[] args) throws JsonGenerationException, JsonMappingException, IOException { + + GitCore core = new GitCore(); + int revision; + + try { + switch (args[0]) { + case "init": + core.makeInit(); + break; + case "commit": + System.out.println("Commiting..."); + core.makeCommit(args[1], Arrays.copyOfRange(args, 2, args.length)); + System.out.println("Commit made at revision " + core.getCurrentRevision()); + break; + case "checkout": + revision = Integer.parseInt(args[1]); + System.out.println("Check out to revision " + revision); + core.makeCheckout(revision); + break; + case "reset": + revision = Integer.parseInt(args[1]); + System.out.println("Performing reset to revision " + revision); + core.makeReset(revision); + break; + case "log": + revision = args.length == 2 ? Integer.parseInt(args[1]) : -1; + System.out.println("Log: " + core.getLog(revision)); + break; + default: + System.out.println("Unknown argument: " + args[0]); + } + } catch (UnversionedException e) { + System.out.println("This directory is not versioned"); + } + } +} diff --git a/hw_git_2/src/main/java/hw_git/GitCore.java b/hw_git_2/src/main/java/hw_git/GitCore.java new file mode 100644 index 0000000..004116b --- /dev/null +++ b/hw_git_2/src/main/java/hw_git/GitCore.java @@ -0,0 +1,197 @@ +package hw_git; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.sql.Timestamp; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.Map; +import java.util.Map.Entry; + +import com.fasterxml.jackson.core.JsonGenerationException; +import com.fasterxml.jackson.core.JsonParseException; +import com.fasterxml.jackson.databind.JsonMappingException; +import com.fasterxml.jackson.databind.ObjectMapper; + +public class GitCore { + private RepInformation inform = null; + private Path informPath = null; + private final String infoFileName = ".myGitData"; + private final String storageFolder = ".mygitdata"; + + void findRepInformation() throws JsonParseException, JsonMappingException, IOException, UnversionedException { + RepInformation result = null; + Path p = Paths.get(""); + + while (p != null && !Files.exists(p.resolve(infoFileName))) { + p = p.getParent(); + } + + if (p != null) { + ObjectMapper omapper = new ObjectMapper(); + result = omapper.readValue(p.resolve(infoFileName).toFile(), RepInformation.class); + } + + if (result == null) { + throw new UnversionedException(); + } + inform = result; + informPath = p; + } + + private void updateRepInformation() throws JsonGenerationException, JsonMappingException, IOException { + ObjectMapper omapper = new ObjectMapper(); + System.out.println("writing to path: " + informPath.toString()); + omapper.writeValue(informPath.resolve(infoFileName).toFile(), inform); + } + + void makeInit() throws JsonGenerationException, JsonMappingException, IOException, UnversionedException { + try { + findRepInformation(); + } catch (UnversionedException e) { + //ObjectMapper omapper = new ObjectMapper(); + //omapper.writeValue(Paths.get("").resolve(filename).toFile(), new RepInformation()); + informPath = Paths.get(""); + inform = new RepInformation(); + //inform.allFiles.put(Paths.get(""), 0); + updateRepInformation(); + System.out.println("Ok."); + } + } + + void increaseRevisionNumber() { + inform.revision++; + } + + private Path getPathRealRelative(String filename) { + return informPath.relativize(Paths.get("")).resolve(filename); + } + + private Path getStoragePath(String filename, int revision) { + Path rel = getPathRealRelative(filename); + String fname = rel.getFileName().toString(); + + rel = rel.getParent(); + + Path storage = informPath.resolve(storageFolder).resolve(rel).resolve(fname + revision); + + return storage; + } + + private void addFile(String filename) throws IOException { + int revision = inform.revision; + Path storage = getStoragePath(filename, revision); + storage.getParent().toFile().mkdirs(); + //System.out.println("trying write file to " + storage); + Files.copy(Paths.get("").resolve(filename), getStoragePath(filename, revision)); + ArrayList revisions = inform.allFiles.get(getPathRealRelative(filename).toString()); + if (revisions == null) { + revisions = new ArrayList<>(); + inform.allFiles.put(getPathRealRelative(filename).toString(), revisions); + } + revisions.add(revision); + } + + void makeCommit(String message, String[] filenames) throws IOException, UnversionedException { + findRepInformation(); + increaseRevisionNumber(); + inform.commitMessages.add(message); + inform.timestamps.add(new Timestamp(System.currentTimeMillis())); + for (String fname : filenames) { + addFile(fname); + } + updateRepInformation(); + } + + private void deleteVersionedFiles(File root) { + if (root.isFile()) { + String key = informPath.toAbsolutePath() + .relativize(Paths.get(root.getAbsolutePath())) + .toString(); + + //System.out.println("key: " + key); + + if (inform.allFiles.containsKey(key)) { + System.out.println("deleting " + root.getName()); + root.delete(); + } + return; + } + if (root.isDirectory()) { + for (File f : root.listFiles()) { + if (f.getName().equals(infoFileName) || f.getName().equals(storageFolder)) { + continue; + } + deleteVersionedFiles(f); + } + } + } + + private int getIndexOfLessEq(ArrayList list, int val) { + int curr = 0; + int prev = -1; + while (curr < list.size() && list.get(curr) <= val) { + prev = curr; + curr++; + } + + return prev; + } + + private void restoreVersionedFiles(int revision) throws IOException { + for (Map.Entry> ent : inform.allFiles.entrySet()) { + int revisionIdx = getIndexOfLessEq(ent.getValue(), revision); + if (revisionIdx >= 0) { + int revNumber = ent.getValue().get(revisionIdx); + Files.copy(informPath.resolve(storageFolder).resolve(ent.getKey() + revNumber), + informPath.resolve(ent.getKey())); + System.out.println("restored " + ent.getKey()); + } + } + } + + void makeCheckout(int revision) throws IOException, UnversionedException { + findRepInformation(); + deleteVersionedFiles(informPath.toAbsolutePath().toFile()); + restoreVersionedFiles(revision); + } + + void makeReset(int revision) throws JsonParseException, JsonMappingException, IOException, UnversionedException { + findRepInformation(); + Iterator>> it = inform.allFiles.entrySet().iterator(); + while(it.hasNext()) { + Map.Entry> ent = it.next(); + int revisionIndex = getIndexOfLessEq(ent.getValue(), revision); + if (revisionIndex == -1) { + it.remove(); + } else { + ent.getValue().subList(revisionIndex + 1, ent.getValue().size()).clear(); + } + + } + inform.revision = revision; + inform.commitMessages.subList(revision , inform.commitMessages.size()).clear(); + inform.timestamps.subList(revision, inform.timestamps.size()).clear(); + updateRepInformation(); + } + + String getLog(int revision) throws JsonParseException, JsonMappingException, IOException, UnversionedException { + findRepInformation(); + if (revision == -1) { + revision = inform.revision; + } + if(revision == 0) { + return "Empty log"; + } + return "revision: " + revision + "\n" + + inform.commitMessages.get(revision - 1) + "\n" + + inform.timestamps.get(revision - 1); + } + + int getCurrentRevision() { + return inform.revision; + } +} diff --git a/hw_git_2/src/main/java/hw_git/RepInformation.java b/hw_git_2/src/main/java/hw_git/RepInformation.java new file mode 100644 index 0000000..89c288e --- /dev/null +++ b/hw_git_2/src/main/java/hw_git/RepInformation.java @@ -0,0 +1,39 @@ +package hw_git; + +import java.sql.Timestamp; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.TreeMap; + +public class RepInformation { + int revision = 0; + ArrayList commitMessages = new ArrayList<>(); + ArrayList timestamps = new ArrayList<>(); + Map> allFiles = new TreeMap<>(); + + public int getRevision() { + return revision; + } + public void setRevision(int revision) { + this.revision = revision; + } + public List getCommitMessages() { + return commitMessages; + } + public void setCommitMessages(ArrayList commitMessages) { + this.commitMessages = commitMessages; + } + public List getTimestamps() { + return timestamps; + } + public void setTimestamps(ArrayList timestamps) { + this.timestamps = timestamps; + } + public Map> getAllFiles() { + return allFiles; + } + public void setAllFiles(Map> allFiles) { + this.allFiles = allFiles; + } +} diff --git a/hw_git_2/src/main/java/hw_git/UnversionedException.java b/hw_git_2/src/main/java/hw_git/UnversionedException.java new file mode 100644 index 0000000..33f9cf9 --- /dev/null +++ b/hw_git_2/src/main/java/hw_git/UnversionedException.java @@ -0,0 +1,5 @@ +package hw_git; + +public class UnversionedException extends Exception { + +} diff --git a/hw_git_2/src/test/java/hw_git/AppTest.java b/hw_git_2/src/test/java/hw_git/AppTest.java new file mode 100644 index 0000000..7fbeb02 --- /dev/null +++ b/hw_git_2/src/test/java/hw_git/AppTest.java @@ -0,0 +1,115 @@ +package hw_git; + +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.io.PrintWriter; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.Scanner; + +import org.apache.commons.io.FileUtils; + + +import com.fasterxml.jackson.core.JsonGenerationException; +import com.fasterxml.jackson.databind.JsonMappingException; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +public class AppTest extends Assert { + + @Before + public void setUp() throws IOException { + //System.out.println("setUp"); + Files.createDirectories(Paths.get("testdir/dir1")); + Files.createFile(Paths.get("testdir/dir1/file_d1.txt")); + Files.createFile(Paths.get("testdir/file.txt")); + } + + @After + public void tearDown() throws IOException { + //System.out.println("tearDown"); + FileUtils.deleteDirectory(Paths.get("testdir").toFile()); + FileUtils.deleteDirectory(Paths.get(".mygitdata").toFile()); + if (Files.exists(Paths.get(".myGitData"))) { + Files.delete(Paths.get(".myGitData")); + } + } + + @Test + public void testInformationLoad() throws JsonGenerationException, JsonMappingException, IOException, UnversionedException { + GitCli.main(new String[] {"init"}); + GitCore core = new GitCore(); + core.findRepInformation(); + assertEquals(core.getCurrentRevision(), 0); + //Files.delete(Paths.get(".myGitData")); + } + + @Test(expected = UnversionedException.class) + public void testUnversioned() throws IOException, UnversionedException { + GitCore core = new GitCore(); + core.findRepInformation(); + //core.makeCheckout(0); + } + + @Test + public void testCheckout() throws JsonGenerationException, JsonMappingException, IOException { + GitCli.main(new String[] {"init"}); + GitCli.main(new String[] {"commit", "message 1", "testdir/file.txt"}); + GitCli.main(new String[] {"commit", "message 2", "testdir/dir1/file_d1.txt"}); + + GitCli.main(new String[] {"checkout", "1"}); + assertTrue(Files.exists(Paths.get("testdir/file.txt"))); + assertFalse(Files.exists(Paths.get("testdir/dir1/file_d1.txt"))); + + GitCli.main(new String[] {"checkout", "2"}); + assertTrue(Files.exists(Paths.get("testdir/file.txt"))); + assertTrue(Files.exists(Paths.get("testdir/dir1/file_d1.txt"))); + } + + @Test + public void testFileChangeBetweenCommits() throws JsonGenerationException, JsonMappingException, IOException { + GitCli.main(new String[] {"init"}); + try (PrintWriter out = new PrintWriter(new File("testdir/file.txt"))) { + out.print("commit 1 content"); + } + GitCli.main(new String[] {"commit", "message 1", "testdir/file.txt"}); + GitCli.main(new String[] {"commit", "message 2", "testdir/dir1/file_d1.txt"}); + + try (PrintWriter out = new PrintWriter(new File("testdir/file.txt"))) { + out.print("commit 3 content"); + } + + GitCli.main(new String[] {"commit", "message 3", "testdir/file.txt"}); + + GitCli.main(new String[] {"checkout", "2"}); + try (Scanner in = new Scanner(new File("testdir/file.txt"))) { + assertEquals(in.nextLine(), "commit 1 content"); + } + + GitCli.main(new String[] {"checkout", "3"}); + try (Scanner in = new Scanner(new File("testdir/file.txt"))) { + assertEquals(in.nextLine(), "commit 3 content"); + } + } + + @Test + public void testReset() throws JsonGenerationException, JsonMappingException, IOException { + GitCli.main(new String[] {"init"}); + GitCli.main(new String[] {"commit", "message 1", "testdir/file.txt"}); + String s1; + try (Scanner in = new Scanner(new File(".myGitData"))) { + s1 = in.nextLine(); + } + GitCli.main(new String[] {"commit", "message 2", "testdir/dir1/file_d1.txt"}); + GitCli.main(new String[] {"reset", "1"}); + String s2; + try (Scanner in = new Scanner(new File(".myGitData"))) { + s2 = in.nextLine(); + } + assertEquals(s1, s2); + } +} From a1810e6e4dcc15ad48cac5bee0b579319dc15e8e Mon Sep 17 00:00:00 2001 From: Anton Date: Sun, 23 Sep 2018 13:57:43 +0300 Subject: [PATCH 2/5] =?UTF-8?q?commit=20=D1=80=D0=B0=D0=B7=D0=B4=D0=B5?= =?UTF-8?q?=D0=BB=D1=91=D0=BD=20=D0=BD=D0=B0=20add=20=D0=B8=20commit?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- hw_git_2/pom.xml | 4 +- hw_git_2/src/main/java/hw_git/GitCli.java | 6 +- hw_git_2/src/main/java/hw_git/GitCore.java | 85 +++++++++++++++------- hw_git_2/src/test/java/hw_git/AppTest.java | 21 ++++-- 4 files changed, 79 insertions(+), 37 deletions(-) diff --git a/hw_git_2/pom.xml b/hw_git_2/pom.xml index 8284e27..cf559c8 100644 --- a/hw_git_2/pom.xml +++ b/hw_git_2/pom.xml @@ -3,11 +3,11 @@ 4.0.0 1 - hw_git_1 + hw_git_2 0.0.1-SNAPSHOT jar - hw_git_1 + hw_git_2 http://maven.apache.org diff --git a/hw_git_2/src/main/java/hw_git/GitCli.java b/hw_git_2/src/main/java/hw_git/GitCli.java index ffa7e0c..1c6ac8b 100644 --- a/hw_git_2/src/main/java/hw_git/GitCli.java +++ b/hw_git_2/src/main/java/hw_git/GitCli.java @@ -17,9 +17,13 @@ public static void main(String[] args) throws JsonGenerationException, JsonMappi case "init": core.makeInit(); break; + case "add": + System.out.println("Addition..."); + core.makeAdd(Arrays.copyOfRange(args, 1, args.length)); + break; case "commit": System.out.println("Commiting..."); - core.makeCommit(args[1], Arrays.copyOfRange(args, 2, args.length)); + core.makeCommit(args[1]); System.out.println("Commit made at revision " + core.getCurrentRevision()); break; case "checkout": diff --git a/hw_git_2/src/main/java/hw_git/GitCore.java b/hw_git_2/src/main/java/hw_git/GitCore.java index 004116b..a687785 100644 --- a/hw_git_2/src/main/java/hw_git/GitCore.java +++ b/hw_git_2/src/main/java/hw_git/GitCore.java @@ -2,15 +2,20 @@ import java.io.File; import java.io.IOException; +import java.nio.file.FileVisitResult; +import java.nio.file.FileVisitor; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; +import java.nio.file.attribute.BasicFileAttributes; import java.sql.Timestamp; import java.util.ArrayList; import java.util.Iterator; import java.util.Map; import java.util.Map.Entry; +import org.apache.commons.io.FileUtils; + import com.fasterxml.jackson.core.JsonGenerationException; import com.fasterxml.jackson.core.JsonParseException; import com.fasterxml.jackson.databind.JsonMappingException; @@ -21,6 +26,7 @@ public class GitCore { private Path informPath = null; private final String infoFileName = ".myGitData"; private final String storageFolder = ".mygitdata"; + private final String stageFolder = ".stageData"; void findRepInformation() throws JsonParseException, JsonMappingException, IOException, UnversionedException { RepInformation result = null; @@ -44,7 +50,6 @@ void findRepInformation() throws JsonParseException, JsonMappingException, IOExc private void updateRepInformation() throws JsonGenerationException, JsonMappingException, IOException { ObjectMapper omapper = new ObjectMapper(); - System.out.println("writing to path: " + informPath.toString()); omapper.writeValue(informPath.resolve(infoFileName).toFile(), inform); } @@ -52,11 +57,8 @@ void makeInit() throws JsonGenerationException, JsonMappingException, IOExceptio try { findRepInformation(); } catch (UnversionedException e) { - //ObjectMapper omapper = new ObjectMapper(); - //omapper.writeValue(Paths.get("").resolve(filename).toFile(), new RepInformation()); informPath = Paths.get(""); inform = new RepInformation(); - //inform.allFiles.put(Paths.get(""), 0); updateRepInformation(); System.out.println("Ok."); } @@ -70,39 +72,68 @@ private Path getPathRealRelative(String filename) { return informPath.relativize(Paths.get("")).resolve(filename); } - private Path getStoragePath(String filename, int revision) { - Path rel = getPathRealRelative(filename); - String fname = rel.getFileName().toString(); - - rel = rel.getParent(); - - Path storage = informPath.resolve(storageFolder).resolve(rel).resolve(fname + revision); - - return storage; - } - - private void addFile(String filename) throws IOException { + private void addFile(Path filename) throws IOException { int revision = inform.revision; - Path storage = getStoragePath(filename, revision); + Path keyPath = filename.subpath(1, filename.getNameCount()); + Path storage = informPath.resolve(storageFolder) + .resolve(keyPath.getParent()) + .resolve(keyPath.getFileName().toString() + revision); storage.getParent().toFile().mkdirs(); - //System.out.println("trying write file to " + storage); - Files.copy(Paths.get("").resolve(filename), getStoragePath(filename, revision)); - ArrayList revisions = inform.allFiles.get(getPathRealRelative(filename).toString()); + Files.copy(filename, storage); + String keyName = keyPath.toString(); + ArrayList revisions = inform.allFiles.get(keyName); if (revisions == null) { revisions = new ArrayList<>(); - inform.allFiles.put(getPathRealRelative(filename).toString(), revisions); + inform.allFiles.put(keyName, revisions); } revisions.add(revision); } - void makeCommit(String message, String[] filenames) throws IOException, UnversionedException { + void makeAdd(String[] filenames) throws IOException, UnversionedException { + findRepInformation(); + for (String fname : filenames) { + Path orig = getPathRealRelative(fname); + Path dest = informPath.resolve(stageFolder).resolve(orig); + //Files.copy(orig, dest); + FileUtils.copyFile(orig.toFile(), dest.toFile()); + } + } + + void makeCommit(String message) throws IOException, UnversionedException { findRepInformation(); increaseRevisionNumber(); inform.commitMessages.add(message); inform.timestamps.add(new Timestamp(System.currentTimeMillis())); - for (String fname : filenames) { - addFile(fname); - } + Files.walkFileTree( + informPath.resolve(stageFolder), + new FileVisitor() { + + @Override + public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException { + // TODO Auto-generated method stub + return FileVisitResult.CONTINUE; + } + + @Override + public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { + System.out.println("walking " + file); + addFile(file); + Files.delete(file); + return FileVisitResult.CONTINUE; + } + + @Override + public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOException { + // TODO Auto-generated method stub + return FileVisitResult.CONTINUE; + } + + @Override + public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException { + // TODO Auto-generated method stub + return FileVisitResult.CONTINUE; + } + }); updateRepInformation(); } @@ -146,8 +177,8 @@ private void restoreVersionedFiles(int revision) throws IOException { int revisionIdx = getIndexOfLessEq(ent.getValue(), revision); if (revisionIdx >= 0) { int revNumber = ent.getValue().get(revisionIdx); - Files.copy(informPath.resolve(storageFolder).resolve(ent.getKey() + revNumber), - informPath.resolve(ent.getKey())); + FileUtils.copyFile(informPath.resolve(storageFolder).resolve(ent.getKey() + revNumber).toFile(), + informPath.resolve(ent.getKey()).toFile()); System.out.println("restored " + ent.getKey()); } } diff --git a/hw_git_2/src/test/java/hw_git/AppTest.java b/hw_git_2/src/test/java/hw_git/AppTest.java index 7fbeb02..28052eb 100644 --- a/hw_git_2/src/test/java/hw_git/AppTest.java +++ b/hw_git_2/src/test/java/hw_git/AppTest.java @@ -58,8 +58,10 @@ public void testUnversioned() throws IOException, UnversionedException { @Test public void testCheckout() throws JsonGenerationException, JsonMappingException, IOException { GitCli.main(new String[] {"init"}); - GitCli.main(new String[] {"commit", "message 1", "testdir/file.txt"}); - GitCli.main(new String[] {"commit", "message 2", "testdir/dir1/file_d1.txt"}); + GitCli.main(new String[] {"add", "testdir/file.txt"}); + GitCli.main(new String[] {"commit", "message 1"}); + GitCli.main(new String[] {"add", "testdir/dir1/file_d1.txt"}); + GitCli.main(new String[] {"commit", "message 2"}); GitCli.main(new String[] {"checkout", "1"}); assertTrue(Files.exists(Paths.get("testdir/file.txt"))); @@ -76,14 +78,17 @@ public void testFileChangeBetweenCommits() throws JsonGenerationException, JsonM try (PrintWriter out = new PrintWriter(new File("testdir/file.txt"))) { out.print("commit 1 content"); } - GitCli.main(new String[] {"commit", "message 1", "testdir/file.txt"}); - GitCli.main(new String[] {"commit", "message 2", "testdir/dir1/file_d1.txt"}); + GitCli.main(new String[] {"add", "testdir/file.txt"}); + GitCli.main(new String[] {"commit", "message 1"}); + GitCli.main(new String[] {"add", "testdir/dir1/file_d1.txt"}); + GitCli.main(new String[] {"commit", "message 2"}); try (PrintWriter out = new PrintWriter(new File("testdir/file.txt"))) { out.print("commit 3 content"); } - GitCli.main(new String[] {"commit", "message 3", "testdir/file.txt"}); + GitCli.main(new String[] {"add", "testdir/file.txt"}); + GitCli.main(new String[] {"commit", "message 3"}); GitCli.main(new String[] {"checkout", "2"}); try (Scanner in = new Scanner(new File("testdir/file.txt"))) { @@ -99,12 +104,14 @@ public void testFileChangeBetweenCommits() throws JsonGenerationException, JsonM @Test public void testReset() throws JsonGenerationException, JsonMappingException, IOException { GitCli.main(new String[] {"init"}); - GitCli.main(new String[] {"commit", "message 1", "testdir/file.txt"}); + GitCli.main(new String[] {"add", "testdir/file.txt"}); + GitCli.main(new String[] {"commit", "message 1"}); String s1; try (Scanner in = new Scanner(new File(".myGitData"))) { s1 = in.nextLine(); } - GitCli.main(new String[] {"commit", "message 2", "testdir/dir1/file_d1.txt"}); + GitCli.main(new String[] {"add", "testdir/dir1/file_d1.txt"}); + GitCli.main(new String[] {"commit", "message 2"}); GitCli.main(new String[] {"reset", "1"}); String s2; try (Scanner in = new Scanner(new File(".myGitData"))) { From 12c33452cd02087d2acd6fef648d8a79d81959ac Mon Sep 17 00:00:00 2001 From: Anton Date: Mon, 24 Sep 2018 19:46:52 +0300 Subject: [PATCH 3/5] task finished --- hw_git_2/src/main/java/hw_git/GitCli.java | 30 ++++- hw_git_2/src/main/java/hw_git/GitCore.java | 126 ++++++++++++++++++--- hw_git_2/src/test/java/hw_git/AppTest.java | 54 +++++++++ 3 files changed, 194 insertions(+), 16 deletions(-) diff --git a/hw_git_2/src/main/java/hw_git/GitCli.java b/hw_git_2/src/main/java/hw_git/GitCli.java index 1c6ac8b..833bc21 100644 --- a/hw_git_2/src/main/java/hw_git/GitCli.java +++ b/hw_git_2/src/main/java/hw_git/GitCli.java @@ -27,9 +27,13 @@ public static void main(String[] args) throws JsonGenerationException, JsonMappi System.out.println("Commit made at revision " + core.getCurrentRevision()); break; case "checkout": - revision = Integer.parseInt(args[1]); - System.out.println("Check out to revision " + revision); - core.makeCheckout(revision); + try { + revision = Integer.parseInt(args[1]); + System.out.println("Check out to revision " + revision); + core.makeCheckout(revision); + } catch (NumberFormatException e) { + core.makeCheckout(Arrays.copyOfRange(args, 2, args.length)); + } break; case "reset": revision = Integer.parseInt(args[1]); @@ -40,6 +44,26 @@ public static void main(String[] args) throws JsonGenerationException, JsonMappi revision = args.length == 2 ? Integer.parseInt(args[1]) : -1; System.out.println("Log: " + core.getLog(revision)); break; + case "rm": + System.out.println("Removing..."); + core.makeRM(Arrays.copyOfRange(args, 1, args.length)); + break; + case "status": + core.findRepInformation(); + System.out.println("Status:"); + System.out.println("Deleted files:\n________________"); + for (String fname : core.getDeletedFiles()) { + System.out.println(fname); + } + System.out.println("Changed files:\n________________"); + for (String fname : core.getChangedFiles()) { + System.out.println(fname); + } + System.out.println("Untracked files:\n________________"); + for (String fname : core.getUntrackedFiles()) { + System.out.println(fname); + } + break; default: System.out.println("Unknown argument: " + args[0]); } diff --git a/hw_git_2/src/main/java/hw_git/GitCore.java b/hw_git_2/src/main/java/hw_git/GitCore.java index a687785..f1cf503 100644 --- a/hw_git_2/src/main/java/hw_git/GitCore.java +++ b/hw_git_2/src/main/java/hw_git/GitCore.java @@ -11,6 +11,7 @@ import java.sql.Timestamp; import java.util.ArrayList; import java.util.Iterator; +import java.util.List; import java.util.Map; import java.util.Map.Entry; @@ -27,7 +28,10 @@ public class GitCore { private final String infoFileName = ".myGitData"; private final String storageFolder = ".mygitdata"; private final String stageFolder = ".stageData"; - + + private int getLastItem(ArrayList list) { + return list.get(list.size() - 1); + } void findRepInformation() throws JsonParseException, JsonMappingException, IOException, UnversionedException { RepInformation result = null; Path p = Paths.get(""); @@ -69,17 +73,21 @@ void increaseRevisionNumber() { } private Path getPathRealRelative(String filename) { - return informPath.relativize(Paths.get("")).resolve(filename); + return informPath.relativize(Paths.get(filename)); + } + + private Path getStoragePath(Path keyPath, int revision) { + return informPath.resolve(storageFolder) + .resolve(keyPath.getParent()) + .resolve(keyPath.getFileName().toString() + revision); } - private void addFile(Path filename) throws IOException { + private void addFile(Path filepath) throws IOException { int revision = inform.revision; - Path keyPath = filename.subpath(1, filename.getNameCount()); - Path storage = informPath.resolve(storageFolder) - .resolve(keyPath.getParent()) - .resolve(keyPath.getFileName().toString() + revision); + Path keyPath = filepath.subpath(1, filepath.getNameCount()); + Path storage = getStoragePath(keyPath, revision); storage.getParent().toFile().mkdirs(); - Files.copy(filename, storage); + Files.copy(filepath, storage); String keyName = keyPath.toString(); ArrayList revisions = inform.allFiles.get(keyName); if (revisions == null) { @@ -116,7 +124,6 @@ public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) th @Override public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { - System.out.println("walking " + file); addFile(file); Files.delete(file); return FileVisitResult.CONTINUE; @@ -142,11 +149,8 @@ private void deleteVersionedFiles(File root) { String key = informPath.toAbsolutePath() .relativize(Paths.get(root.getAbsolutePath())) .toString(); - - //System.out.println("key: " + key); if (inform.allFiles.containsKey(key)) { - System.out.println("deleting " + root.getName()); root.delete(); } return; @@ -179,7 +183,6 @@ private void restoreVersionedFiles(int revision) throws IOException { int revNumber = ent.getValue().get(revisionIdx); FileUtils.copyFile(informPath.resolve(storageFolder).resolve(ent.getKey() + revNumber).toFile(), informPath.resolve(ent.getKey()).toFile()); - System.out.println("restored " + ent.getKey()); } } } @@ -190,6 +193,17 @@ void makeCheckout(int revision) throws IOException, UnversionedException { restoreVersionedFiles(revision); } + void makeCheckout(String[] files) throws JsonParseException, JsonMappingException, IOException, UnversionedException { + findRepInformation(); + for (String fname : files) { + String key = getPathRealRelative(fname).toString(); + System.out.println("checkout key: " + key); + FileUtils.copyFile(getStoragePath(getPathRealRelative(fname), + getLastItem(inform.allFiles.get(key))).toFile(), + informPath.resolve(key).toFile()); + } + } + void makeReset(int revision) throws JsonParseException, JsonMappingException, IOException, UnversionedException { findRepInformation(); Iterator>> it = inform.allFiles.entrySet().iterator(); @@ -222,7 +236,93 @@ String getLog(int revision) throws JsonParseException, JsonMappingException, IOE + inform.timestamps.get(revision - 1); } + List getDeletedFiles() throws JsonParseException, JsonMappingException, IOException, UnversionedException { + ArrayList result = new ArrayList<>(); + findRepInformation(); + + for (String keypath : inform.allFiles.keySet()) { + if (!Files.exists(informPath.resolve(keypath))) { + result.add(Paths.get("").relativize(Paths.get(keypath)).toString()); + } + } + + return result; + } + + List getChangedFiles() throws JsonParseException, JsonMappingException, IOException, UnversionedException { + ArrayList result = new ArrayList<>(); + findRepInformation(); + + for (String keypath : inform.allFiles.keySet()) { + if (Files.exists(informPath.resolve(keypath)) + && !FileUtils.contentEquals( + informPath.resolve(keypath).toFile(), + getStoragePath(Paths.get(keypath), getLastItem(inform.allFiles.get(keypath)) + ).toFile() + )) { + result.add(Paths.get("").relativize(Paths.get(keypath)).toString()); + } + } + + return result; + } + + List getUntrackedFiles() throws IOException { + ArrayList result = new ArrayList<>(); + Files.walkFileTree(Paths.get(""), new FileVisitor() { + + @Override + public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException { + // TODO Auto-generated method stub + return dir.equals(Paths.get(stageFolder)) || dir.equals(Paths.get(storageFolder)) + ? FileVisitResult.SKIP_SUBTREE : FileVisitResult.CONTINUE; + } + + @Override + public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { + // TODO Auto-generated method stub + if (!inform.allFiles.containsKey(informPath.relativize(file).toString())) { + result.add(file.toString()); + } + return FileVisitResult.CONTINUE; + } + + @Override + public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOException { + // TODO Auto-generated method stub + return FileVisitResult.CONTINUE; + } + + @Override + public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException { + // TODO Auto-generated method stub + return FileVisitResult.CONTINUE; + } + }); + + return result; + } + int getCurrentRevision() { return inform.revision; } + + + private void removeFromRep(String filename) throws IOException { + Path keypath = getPathRealRelative(filename); + System.out.println("keypath: " + keypath); + for (int revision : inform.allFiles.get(keypath.toString())) { + Files.delete(getStoragePath(keypath, revision)); + } + Files.deleteIfExists(informPath.resolve(stageFolder).resolve(keypath)); + inform.allFiles.remove(keypath.toString()); + } + + void makeRM(String[] files) throws IOException, UnversionedException { + findRepInformation(); + for (String filename : files) { + removeFromRep(filename); + } + updateRepInformation(); + } } diff --git a/hw_git_2/src/test/java/hw_git/AppTest.java b/hw_git_2/src/test/java/hw_git/AppTest.java index 28052eb..b031b58 100644 --- a/hw_git_2/src/test/java/hw_git/AppTest.java +++ b/hw_git_2/src/test/java/hw_git/AppTest.java @@ -6,6 +6,7 @@ import java.io.PrintWriter; import java.nio.file.Files; import java.nio.file.Paths; +import java.util.Arrays; import java.util.Scanner; import org.apache.commons.io.FileUtils; @@ -72,6 +73,24 @@ public void testCheckout() throws JsonGenerationException, JsonMappingException, assertTrue(Files.exists(Paths.get("testdir/dir1/file_d1.txt"))); } + @Test + public void testCheckoutFiles() throws JsonGenerationException, JsonMappingException, IOException { + GitCli.main(new String[] {"init"}); + try (PrintWriter out = new PrintWriter(new File("testdir/file.txt"))) { + out.println("text 1"); + } + GitCli.main(new String[] {"add", "testdir/file.txt"}); + GitCli.main(new String[] {"commit", "message 1"}); + try (PrintWriter out = new PrintWriter(new File("testdir/file.txt"))) { + out.println("text 2"); + } + + GitCli.main(new String[] {"checkout", "--", "testdir/file.txt"}); + try (Scanner in = new Scanner(new File("testdir/file.txt"))) { + assertTrue(in.nextLine().equals("text 1")); + } + } + @Test public void testFileChangeBetweenCommits() throws JsonGenerationException, JsonMappingException, IOException { GitCli.main(new String[] {"init"}); @@ -119,4 +138,39 @@ public void testReset() throws JsonGenerationException, JsonMappingException, IO } assertEquals(s1, s2); } + + @Test + public void testRM() throws JsonGenerationException, JsonMappingException, IOException { + GitCli.main(new String[] {"init"}); + GitCli.main(new String[] {"add", "testdir/file.txt"}); + GitCli.main(new String[] {"commit", "message 1"}); + Files.delete(Paths.get("testdir/file.txt")); + GitCli.main(new String[] {"rm", "testdir/file.txt"}); + GitCli.main(new String[] {"checkout", "1"}); + assertFalse(Files.exists(Paths.get("testdir/file.txt"))); + } + + @Test + public void testStatus() throws JsonGenerationException, JsonMappingException, IOException, UnversionedException { + GitCli.main(new String[] {"init"}); + GitCli.main(new String[] {"add", "testdir/file.txt"}); + GitCli.main(new String[] {"commit", "message 1"}); + + GitCore core = new GitCore(); + core.findRepInformation(); + + assertEquals(core.getChangedFiles(), Arrays.asList()); + //assertEquals(core.getUntrackedFiles(), Arrays.asList("testdir/dir1/file_d1.txt")); + assertEquals(core.getDeletedFiles(), Arrays.asList()); + + try (PrintWriter out = new PrintWriter(new File("testdir/file.txt"))) { + out.print("commit 3 content"); + } + + assertEquals(core.getChangedFiles(), Arrays.asList("testdir/file.txt")); + + Files.delete(Paths.get("testdir/file.txt")); + + assertEquals(core.getDeletedFiles(), Arrays.asList("testdir/file.txt")); + } } From 024ab95db6cc283683dad3f2d35a785283ad8bbd Mon Sep 17 00:00:00 2001 From: Anton Date: Mon, 24 Sep 2018 19:50:53 +0300 Subject: [PATCH 4/5] README changed --- README.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 4314260..8feee6a 100644 --- a/README.md +++ b/README.md @@ -1 +1,7 @@ -# java_homeworks \ No newline at end of file +## Мой GIT. +Для запуска выполните +``` + +mvn exec:java -Dexec.mainClass=hw_git.GitCli -Dexec.args="commit commessage testdir/file1" + +``` From 4f4e20a474e9677852bf4deeb9632f0e806d23f7 Mon Sep 17 00:00:00 2001 From: Anton Date: Tue, 2 Oct 2018 23:05:10 +0300 Subject: [PATCH 5/5] adding revision numbers to file names in storage with symbol "r" --- hw_git_2/src/main/java/hw_git/GitCore.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/hw_git_2/src/main/java/hw_git/GitCore.java b/hw_git_2/src/main/java/hw_git/GitCore.java index f1cf503..9213b75 100644 --- a/hw_git_2/src/main/java/hw_git/GitCore.java +++ b/hw_git_2/src/main/java/hw_git/GitCore.java @@ -79,7 +79,7 @@ private Path getPathRealRelative(String filename) { private Path getStoragePath(Path keyPath, int revision) { return informPath.resolve(storageFolder) .resolve(keyPath.getParent()) - .resolve(keyPath.getFileName().toString() + revision); + .resolve(keyPath.getFileName().toString() + "r" + revision); } private void addFile(Path filepath) throws IOException { @@ -181,7 +181,8 @@ private void restoreVersionedFiles(int revision) throws IOException { int revisionIdx = getIndexOfLessEq(ent.getValue(), revision); if (revisionIdx >= 0) { int revNumber = ent.getValue().get(revisionIdx); - FileUtils.copyFile(informPath.resolve(storageFolder).resolve(ent.getKey() + revNumber).toFile(), + FileUtils.copyFile( + informPath.resolve(getStoragePath(Paths.get(ent.getKey()), revNumber)).toFile(), informPath.resolve(ent.getKey()).toFile()); } }