From 4deb0f4b79365bcf77f26cd0d557b83e3db160af Mon Sep 17 00:00:00 2001 From: Anton Date: Tue, 2 Oct 2018 23:18:37 +0300 Subject: [PATCH 01/16] code from previous milestone --- hw_git/pom.xml | 64 ++++ hw_git/src/main/java/hw_git/GitCli.java | 74 ++++ hw_git/src/main/java/hw_git/GitCore.java | 329 ++++++++++++++++++ .../src/main/java/hw_git/RepInformation.java | 39 +++ .../java/hw_git/UnversionedException.java | 5 + hw_git/src/test/java/hw_git/AppTest.java | 176 ++++++++++ 6 files changed, 687 insertions(+) create mode 100644 hw_git/pom.xml create mode 100644 hw_git/src/main/java/hw_git/GitCli.java create mode 100644 hw_git/src/main/java/hw_git/GitCore.java create mode 100644 hw_git/src/main/java/hw_git/RepInformation.java create mode 100644 hw_git/src/main/java/hw_git/UnversionedException.java create mode 100644 hw_git/src/test/java/hw_git/AppTest.java diff --git a/hw_git/pom.xml b/hw_git/pom.xml new file mode 100644 index 0000000..cf559c8 --- /dev/null +++ b/hw_git/pom.xml @@ -0,0 +1,64 @@ + + 4.0.0 + + 1 + hw_git_2 + 0.0.1-SNAPSHOT + jar + + hw_git_2 + 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/src/main/java/hw_git/GitCli.java b/hw_git/src/main/java/hw_git/GitCli.java new file mode 100644 index 0000000..833bc21 --- /dev/null +++ b/hw_git/src/main/java/hw_git/GitCli.java @@ -0,0 +1,74 @@ +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 "add": + System.out.println("Addition..."); + core.makeAdd(Arrays.copyOfRange(args, 1, args.length)); + break; + case "commit": + System.out.println("Commiting..."); + core.makeCommit(args[1]); + System.out.println("Commit made at revision " + core.getCurrentRevision()); + break; + case "checkout": + 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]); + 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; + 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]); + } + } catch (UnversionedException e) { + System.out.println("This directory is not versioned"); + } + } +} diff --git a/hw_git/src/main/java/hw_git/GitCore.java b/hw_git/src/main/java/hw_git/GitCore.java new file mode 100644 index 0000000..9213b75 --- /dev/null +++ b/hw_git/src/main/java/hw_git/GitCore.java @@ -0,0 +1,329 @@ +package hw_git; + +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.List; +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; +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"; + 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(""); + + 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(); + omapper.writeValue(informPath.resolve(infoFileName).toFile(), inform); + } + + void makeInit() throws JsonGenerationException, JsonMappingException, IOException, UnversionedException { + try { + findRepInformation(); + } catch (UnversionedException e) { + informPath = Paths.get(""); + inform = new RepInformation(); + updateRepInformation(); + System.out.println("Ok."); + } + } + + void increaseRevisionNumber() { + inform.revision++; + } + + private Path getPathRealRelative(String 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() + "r" + revision); + } + + private void addFile(Path filepath) throws IOException { + int revision = inform.revision; + Path keyPath = filepath.subpath(1, filepath.getNameCount()); + Path storage = getStoragePath(keyPath, revision); + storage.getParent().toFile().mkdirs(); + Files.copy(filepath, storage); + String keyName = keyPath.toString(); + ArrayList revisions = inform.allFiles.get(keyName); + if (revisions == null) { + revisions = new ArrayList<>(); + inform.allFiles.put(keyName, revisions); + } + revisions.add(revision); + } + + 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())); + 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 { + 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(); + } + + private void deleteVersionedFiles(File root) { + if (root.isFile()) { + String key = informPath.toAbsolutePath() + .relativize(Paths.get(root.getAbsolutePath())) + .toString(); + + if (inform.allFiles.containsKey(key)) { + 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); + FileUtils.copyFile( + informPath.resolve(getStoragePath(Paths.get(ent.getKey()), revNumber)).toFile(), + informPath.resolve(ent.getKey()).toFile()); + } + } + } + + void makeCheckout(int revision) throws IOException, UnversionedException { + findRepInformation(); + deleteVersionedFiles(informPath.toAbsolutePath().toFile()); + 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(); + 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); + } + + 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/src/main/java/hw_git/RepInformation.java b/hw_git/src/main/java/hw_git/RepInformation.java new file mode 100644 index 0000000..89c288e --- /dev/null +++ b/hw_git/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/src/main/java/hw_git/UnversionedException.java b/hw_git/src/main/java/hw_git/UnversionedException.java new file mode 100644 index 0000000..33f9cf9 --- /dev/null +++ b/hw_git/src/main/java/hw_git/UnversionedException.java @@ -0,0 +1,5 @@ +package hw_git; + +public class UnversionedException extends Exception { + +} diff --git a/hw_git/src/test/java/hw_git/AppTest.java b/hw_git/src/test/java/hw_git/AppTest.java new file mode 100644 index 0000000..b031b58 --- /dev/null +++ b/hw_git/src/test/java/hw_git/AppTest.java @@ -0,0 +1,176 @@ +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.Arrays; +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[] {"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"))); + 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 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"}); + try (PrintWriter out = new PrintWriter(new File("testdir/file.txt"))) { + out.print("commit 1 content"); + } + 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[] {"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"))) { + 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[] {"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[] {"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"))) { + s2 = in.nextLine(); + } + 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 72b616a018c7792be0eae498d865a9a5f65430c6 Mon Sep 17 00:00:00 2001 From: Anton Date: Tue, 2 Oct 2018 23:21:26 +0300 Subject: [PATCH 02/16] readme --- 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 d0cb5a41e2ab43d23e2196bb179b8b29eb85d1a0 Mon Sep 17 00:00:00 2001 From: Anton Date: Tue, 2 Oct 2018 23:22:18 +0300 Subject: [PATCH 03/16] name in pom.xml --- hw_git/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hw_git/pom.xml b/hw_git/pom.xml index cf559c8..a0c30c3 100644 --- a/hw_git/pom.xml +++ b/hw_git/pom.xml @@ -3,11 +3,11 @@ 4.0.0 1 - hw_git_2 + hw_git 0.0.1-SNAPSHOT jar - hw_git_2 + hw_git http://maven.apache.org From 307a2cc31a23bf9182f39dc8cc0830342382feeb Mon Sep 17 00:00:00 2001 From: Anton Date: Sun, 7 Oct 2018 15:13:09 +0300 Subject: [PATCH 04/16] =?UTF-8?q?=D0=9D=D0=BE=D0=B2=D0=B0=D1=8F=20=D0=B0?= =?UTF-8?q?=D1=80=D1=85=D0=B8=D1=82=D0=B5=D0=BA=D1=82=D1=83=D1=80=D0=B0=20?= =?UTF-8?q?=D1=81=D0=BE=20=D1=81=D1=82=D0=B0=D1=80=D0=BE=D0=B9=20=D1=84?= =?UTF-8?q?=D1=83=D0=BD=D0=BA=D1=86=D0=B8=D0=BE=D0=BD=D0=B0=D0=BB=D1=8C?= =?UTF-8?q?=D0=BD=D0=BE=D1=81=D1=82=D1=8C=D1=8E.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- hw_git/src/main/java/hw_git/GitCore.java | 148 ++++++++++-------- .../src/main/java/hw_git/RepInformation.java | 119 +++++++++++++- hw_git/src/test/java/hw_git/AppTest.java | 4 +- 3 files changed, 195 insertions(+), 76 deletions(-) diff --git a/hw_git/src/main/java/hw_git/GitCore.java b/hw_git/src/main/java/hw_git/GitCore.java index 9213b75..e53e2e1 100644 --- a/hw_git/src/main/java/hw_git/GitCore.java +++ b/hw_git/src/main/java/hw_git/GitCore.java @@ -1,6 +1,7 @@ package hw_git; import java.io.File; +import java.io.FileNotFoundException; import java.io.IOException; import java.nio.file.FileVisitResult; import java.nio.file.FileVisitor; @@ -10,10 +11,9 @@ import java.nio.file.attribute.BasicFileAttributes; 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; +import java.util.Set; +import java.util.TreeSet; import org.apache.commons.io.FileUtils; @@ -29,9 +29,6 @@ public class GitCore { 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(""); @@ -59,7 +56,7 @@ private void updateRepInformation() throws JsonGenerationException, JsonMappingE void makeInit() throws JsonGenerationException, JsonMappingException, IOException, UnversionedException { try { - findRepInformation(); + findRepInformation(); } catch (UnversionedException e) { informPath = Paths.get(""); inform = new RepInformation(); @@ -72,7 +69,7 @@ void increaseRevisionNumber() { inform.revision++; } - private Path getPathRealRelative(String filename) { + private Path getKeyPath(String filename) { return informPath.relativize(Paths.get(filename)); } @@ -89,20 +86,29 @@ private void addFile(Path filepath) throws IOException { storage.getParent().toFile().mkdirs(); Files.copy(filepath, storage); String keyName = keyPath.toString(); - ArrayList revisions = inform.allFiles.get(keyName); - if (revisions == null) { - revisions = new ArrayList<>(); - inform.allFiles.put(keyName, revisions); + if (!inform.fileNumber.containsKey(keyName)) { + System.out.println(keyName); + inform.fileNumber.put(keyName, inform.nFiles++); + } + + if (inform.nCommits <= revision) { + inform.nCommits++; + inform.commitedFiles.add(new TreeSet<>()); + inform.prevCommit.add(inform.branchEnds.get(inform.currentBranchNumber)); + inform.branchEnds.put(inform.currentBranchNumber, revision); } - revisions.add(revision); + + Set currentRevisionFiles = inform.commitedFiles.get(revision); + assert inform.fileNumber.get(keyName) != null; + currentRevisionFiles.add(inform.fileNumber.get(keyName)); + } void makeAdd(String[] filenames) throws IOException, UnversionedException { findRepInformation(); for (String fname : filenames) { - Path orig = getPathRealRelative(fname); + Path orig = getKeyPath(fname); Path dest = informPath.resolve(stageFolder).resolve(orig); - //Files.copy(orig, dest); FileUtils.copyFile(orig.toFile(), dest.toFile()); } } @@ -150,7 +156,7 @@ private void deleteVersionedFiles(File root) { .relativize(Paths.get(root.getAbsolutePath())) .toString(); - if (inform.allFiles.containsKey(key)) { + if (inform.fileNumber.containsKey(key)) { root.delete(); } return; @@ -165,66 +171,66 @@ private void deleteVersionedFiles(File root) { } } - 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); + Set restoredNumbers = new TreeSet<>(); + while (revision >= 0) { + Set revFiles = inform.commitedFiles.get(revision); + for (Integer fileNumber : revFiles) { + if (restoredNumbers.contains(fileNumber)) { + continue; + } + + restoredNumbers.add(fileNumber); + + String keyName = inform.getStringByNumber(fileNumber, inform.fileNumber); FileUtils.copyFile( - informPath.resolve(getStoragePath(Paths.get(ent.getKey()), revNumber)).toFile(), - informPath.resolve(ent.getKey()).toFile()); + informPath.resolve(getStoragePath(Paths.get(keyName), revision)).toFile(), + informPath.resolve(keyName).toFile()); + } + revision = inform.prevCommit.get(revision); } } void makeCheckout(int revision) throws IOException, UnversionedException { + revision--; findRepInformation(); deleteVersionedFiles(informPath.toAbsolutePath().toFile()); restoreVersionedFiles(revision); } + private int getLastRevisionOfFile(String keyName) { + int revision = inform.currentBranchLastRevision(); + while (revision > 0 && !inform.commitedFiles.get(revision).contains(inform.fileNumber.get(keyName))) { + revision = inform.prevCommit.get(revision); + } + return revision; + } + + private void checkoutFile(Path keyPath) throws IOException { + int revision = getLastRevisionOfFile(keyPath.toString()); + if (revision == -1) { + throw new FileNotFoundException(); + } + FileUtils.copyFile(getStoragePath(keyPath, revision).toFile(), + informPath.resolve(keyPath).toFile()); + } + 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()); + System.out.println("checkout key: " + fname); + checkoutFile(getKeyPath(fname)); } } 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(); + makeCheckout(revision); + FileUtils.cleanDirectory(informPath.resolve(stageFolder).toFile()); } String getLog(int revision) throws JsonParseException, JsonMappingException, IOException, UnversionedException { + revision--; findRepInformation(); if (revision == -1) { revision = inform.revision; @@ -232,8 +238,10 @@ String getLog(int revision) throws JsonParseException, JsonMappingException, IOE if(revision == 0) { return "Empty log"; } - return "revision: " + revision + "\n" - + inform.commitMessages.get(revision - 1) + "\n" + return + "branch " + inform.getCurrentBranchName() + +"revision: " + revision + "\n" + + inform.commitMessages.get(revision - 1) + "\n" + inform.timestamps.get(revision - 1); } @@ -241,7 +249,7 @@ List getDeletedFiles() throws JsonParseException, JsonMappingException, ArrayList result = new ArrayList<>(); findRepInformation(); - for (String keypath : inform.allFiles.keySet()) { + for (String keypath : inform.fileNumber.keySet()) { if (!Files.exists(informPath.resolve(keypath))) { result.add(Paths.get("").relativize(Paths.get(keypath)).toString()); } @@ -249,19 +257,20 @@ List getDeletedFiles() throws JsonParseException, JsonMappingException, 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)) + for (String keyName : inform.fileNumber.keySet()) { + if (Files.exists(informPath.resolve(keyName)) && !FileUtils.contentEquals( - informPath.resolve(keypath).toFile(), - getStoragePath(Paths.get(keypath), getLastItem(inform.allFiles.get(keypath)) + informPath.resolve(keyName).toFile(), + getStoragePath(Paths.get(keyName), getLastRevisionOfFile(keyName) ).toFile() )) { - result.add(Paths.get("").relativize(Paths.get(keypath)).toString()); + result.add(Paths.get("").relativize(Paths.get(keyName)).toString()); } } @@ -282,7 +291,7 @@ public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) th @Override public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { // TODO Auto-generated method stub - if (!inform.allFiles.containsKey(informPath.relativize(file).toString())) { + if (!inform.fileNumber.containsKey(informPath.relativize(file).toString())) { result.add(file.toString()); } return FileVisitResult.CONTINUE; @@ -310,13 +319,18 @@ int getCurrentRevision() { private void removeFromRep(String filename) throws IOException { - Path keypath = getPathRealRelative(filename); + Path keypath = getKeyPath(filename); System.out.println("keypath: " + keypath); - for (int revision : inform.allFiles.get(keypath.toString())) { - Files.delete(getStoragePath(keypath, revision)); + for (int revision = inform.currentBranchLastRevision(); + revision >= 0; + revision = inform.prevCommit.get(revision)) { + if (inform.commitedFiles.get(revision).contains(inform.fileNumber.get(keypath.toString()))) { + Files.delete(getStoragePath(keypath, revision)); + inform.commitedFiles.get(revision).remove(inform.fileNumber.get(keypath.toString())); + } } Files.deleteIfExists(informPath.resolve(stageFolder).resolve(keypath)); - inform.allFiles.remove(keypath.toString()); + inform.fileNumber.remove(keypath.toString()); } void makeRM(String[] files) throws IOException, UnversionedException { diff --git a/hw_git/src/main/java/hw_git/RepInformation.java b/hw_git/src/main/java/hw_git/RepInformation.java index 89c288e..50fdea2 100644 --- a/hw_git/src/main/java/hw_git/RepInformation.java +++ b/hw_git/src/main/java/hw_git/RepInformation.java @@ -4,36 +4,139 @@ import java.util.ArrayList; import java.util.List; import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; import java.util.TreeMap; public class RepInformation { - int revision = 0; + + int revision = -1; + int currentBranchNumber = 0; + int nCommits = 0; + int nFiles = 0; + ArrayList commitMessages = new ArrayList<>(); + ArrayList timestamps = new ArrayList<>(); - Map> allFiles = new TreeMap<>(); + + ArrayList prevCommit = new ArrayList<>(); + + ArrayList> commitedFiles = new ArrayList<>(); + + TreeMap fileNumber = new TreeMap<>(); + + TreeMap branchNumbers = new TreeMap<>(); + + TreeMap branchEnds = new TreeMap<>(); + + public RepInformation() { + branchNumbers.put("master", -1); + branchEnds.put(0, -1); + } + + String getStringByNumber(Integer i, Map map) { + for (Entry ent : map.entrySet()) { + if (ent.getValue().equals(i)) { + return ent.getKey(); + } + } + + return null; + } + + String getCurrentBranchName() { + return getStringByNumber(currentBranchNumber, branchNumbers); + } + + int currentBranchLastRevision() { + return branchEnds.get(currentBranchNumber); + } public int getRevision() { return revision; } + public void setRevision(int revision) { this.revision = revision; } - public List getCommitMessages() { + + public int getCurrentBranchNumber() { + return currentBranchNumber; + } + + public void setCurrentBranchNumber(int currentBranchNumber) { + this.currentBranchNumber = currentBranchNumber; + } + + public int getnCommits() { + return nCommits; + } + + public void setnCommits(int nCommits) { + this.nCommits = nCommits; + } + + public ArrayList getCommitMessages() { return commitMessages; } + public void setCommitMessages(ArrayList commitMessages) { this.commitMessages = commitMessages; } - public List getTimestamps() { + + public ArrayList getTimestamps() { return timestamps; } + public void setTimestamps(ArrayList timestamps) { this.timestamps = timestamps; } - public Map> getAllFiles() { - return allFiles; + + public ArrayList getPrevCommit() { + return prevCommit; + } + + public void setPrevCommit(ArrayList prevCommit) { + this.prevCommit = prevCommit; + } + + public ArrayList> getCommitedFiles() { + return commitedFiles; + } + + public void setCommitedFiles(ArrayList> commitedFiles) { + this.commitedFiles = commitedFiles; + } + + public TreeMap getFileNumber() { + return fileNumber; + } + + public void setFileNumber(TreeMap fileNumber) { + this.fileNumber = fileNumber; + } + + public TreeMap getBranchNumbers() { + return branchNumbers; } - public void setAllFiles(Map> allFiles) { - this.allFiles = allFiles; + + public void setBranchNumbers(TreeMap branchNumbers) { + this.branchNumbers = branchNumbers; + } + + public TreeMap getBranchEnds() { + return branchEnds; + } + + public void setBranchEnds(TreeMap branchEnds) { + this.branchEnds = branchEnds; + } + + public int getnFiles() { + return nFiles; + } + + public void setnFiles(int nFiles) { + this.nFiles = nFiles; } } diff --git a/hw_git/src/test/java/hw_git/AppTest.java b/hw_git/src/test/java/hw_git/AppTest.java index b031b58..60312bc 100644 --- a/hw_git/src/test/java/hw_git/AppTest.java +++ b/hw_git/src/test/java/hw_git/AppTest.java @@ -18,6 +18,7 @@ import org.junit.After; import org.junit.Assert; import org.junit.Before; +import org.junit.Ignore; import org.junit.Test; public class AppTest extends Assert { @@ -45,7 +46,7 @@ public void testInformationLoad() throws JsonGenerationException, JsonMappingExc GitCli.main(new String[] {"init"}); GitCore core = new GitCore(); core.findRepInformation(); - assertEquals(core.getCurrentRevision(), 0); + assertEquals(core.getCurrentRevision(), -1); //Files.delete(Paths.get(".myGitData")); } @@ -120,6 +121,7 @@ public void testFileChangeBetweenCommits() throws JsonGenerationException, JsonM } } + @Ignore @Test public void testReset() throws JsonGenerationException, JsonMappingException, IOException { GitCli.main(new String[] {"init"}); From 168449d63d54a5a140b254a6a723e6015ee6a4c1 Mon Sep 17 00:00:00 2001 From: Anton Date: Mon, 8 Oct 2018 01:07:32 +0300 Subject: [PATCH 05/16] make branch and delete branch added --- hw_git/pom.xml | 12 ++-- .../java/hw_git/BranchProblemException.java | 8 +++ hw_git/src/main/java/hw_git/GitCli.java | 5 ++ hw_git/src/main/java/hw_git/GitCore.java | 71 +++++++++++++++++-- .../src/main/java/hw_git/RepInformation.java | 35 ++++++++- hw_git/src/test/java/hw_git/AppTest.java | 7 +- 6 files changed, 125 insertions(+), 13 deletions(-) create mode 100644 hw_git/src/main/java/hw_git/BranchProblemException.java diff --git a/hw_git/pom.xml b/hw_git/pom.xml index a0c30c3..59b3034 100644 --- a/hw_git/pom.xml +++ b/hw_git/pom.xml @@ -13,15 +13,15 @@ UTF-8 - - - - maven-compiler-plugin - + + + + maven-compiler-plugin + 1.8 1.8 UTF-8 - + diff --git a/hw_git/src/main/java/hw_git/BranchProblemException.java b/hw_git/src/main/java/hw_git/BranchProblemException.java new file mode 100644 index 0000000..29024a1 --- /dev/null +++ b/hw_git/src/main/java/hw_git/BranchProblemException.java @@ -0,0 +1,8 @@ +package hw_git; + +public class BranchProblemException extends Exception { + String message; + public BranchProblemException(String s) { + message = s; + } +} diff --git a/hw_git/src/main/java/hw_git/GitCli.java b/hw_git/src/main/java/hw_git/GitCli.java index 833bc21..cf79395 100644 --- a/hw_git/src/main/java/hw_git/GitCli.java +++ b/hw_git/src/main/java/hw_git/GitCli.java @@ -1,5 +1,6 @@ package hw_git; +import java.io.FileNotFoundException; import java.io.IOException; import java.util.Arrays; @@ -69,6 +70,10 @@ public static void main(String[] args) throws JsonGenerationException, JsonMappi } } catch (UnversionedException e) { System.out.println("This directory is not versioned"); + } catch (BranchProblemException e) { + System.out.println(e.message); + } catch (FileNotFoundException e) { + System.out.println(e.getLocalizedMessage()); } } } diff --git a/hw_git/src/main/java/hw_git/GitCore.java b/hw_git/src/main/java/hw_git/GitCore.java index e53e2e1..65de53b 100644 --- a/hw_git/src/main/java/hw_git/GitCore.java +++ b/hw_git/src/main/java/hw_git/GitCore.java @@ -69,6 +69,10 @@ void increaseRevisionNumber() { inform.revision++; } + void addAtIdx(ArrayList list, int idx, int inc) { + list.set(idx, list.get(idx) + inc); + } + private Path getKeyPath(String filename) { return informPath.relativize(Paths.get(filename)); } @@ -96,6 +100,7 @@ private void addFile(Path filepath) throws IOException { inform.commitedFiles.add(new TreeSet<>()); inform.prevCommit.add(inform.branchEnds.get(inform.currentBranchNumber)); inform.branchEnds.put(inform.currentBranchNumber, revision); + inform.numberOfStartedBranchesAtRevision.add(0); } Set currentRevisionFiles = inform.commitedFiles.get(revision); @@ -113,8 +118,11 @@ void makeAdd(String[] filenames) throws IOException, UnversionedException { } } - void makeCommit(String message) throws IOException, UnversionedException { + void makeCommit(String message) throws IOException, UnversionedException, BranchProblemException { findRepInformation(); + if (inform.revision != inform.currentBranchLastRevision()) { + throw new BranchProblemException("Staying not at end of some branch"); + } increaseRevisionNumber(); inform.commitMessages.add(message); inform.timestamps.add(new Timestamp(System.currentTimeMillis())); @@ -197,6 +205,19 @@ void makeCheckout(int revision) throws IOException, UnversionedException { findRepInformation(); deleteVersionedFiles(informPath.toAbsolutePath().toFile()); restoreVersionedFiles(revision); + inform.revision = revision; + updateRepInformation(); + } + + void makeCheckout(String branchName) throws JsonParseException, JsonMappingException, IOException, UnversionedException, BranchProblemException { + findRepInformation(); + Integer branchNumber = inform.branchNumbers.get(branchName); + if (branchNumber == null) { + throw new BranchProblemException("Branch not exists: " + branchName); + } + + int branchRevision = inform.branchEnds.get(branchNumber); + makeCheckout(branchRevision); } private int getLastRevisionOfFile(String keyName) { @@ -324,13 +345,14 @@ private void removeFromRep(String filename) throws IOException { for (int revision = inform.currentBranchLastRevision(); revision >= 0; revision = inform.prevCommit.get(revision)) { - if (inform.commitedFiles.get(revision).contains(inform.fileNumber.get(keypath.toString()))) { + if (inform.commitedFiles.get(revision).remove(inform.fileNumber.get(keypath.toString()))) { + System.out.println("keypath: " + keypath.toString()); Files.delete(getStoragePath(keypath, revision)); - inform.commitedFiles.get(revision).remove(inform.fileNumber.get(keypath.toString())); + break; } } Files.deleteIfExists(informPath.resolve(stageFolder).resolve(keypath)); - inform.fileNumber.remove(keypath.toString()); + //inform.fileNumber.remove(keypath.toString()); } void makeRM(String[] files) throws IOException, UnversionedException { @@ -340,4 +362,45 @@ void makeRM(String[] files) throws IOException, UnversionedException { } updateRepInformation(); } + + void makeBranch(String branchName) throws JsonParseException, JsonMappingException, IOException, UnversionedException, BranchProblemException { + findRepInformation(); + if (inform.branchNumbers.containsKey(branchName)) { + throw new BranchProblemException("Branch already exists: " + branchName); + } + + Integer newBranchNumber = inform.lastBranchNumber++; + inform.branchNumbers.put(branchName, newBranchNumber); + inform.branchEnds.put(newBranchNumber, inform.revision); + addAtIdx(inform.numberOfStartedBranchesAtRevision, inform.revision, 1); + updateRepInformation(); + } + + void makeDeleteBranch(String branchName) throws JsonParseException, JsonMappingException, IOException, UnversionedException, BranchProblemException { + findRepInformation(); + Integer branchNumber = inform.branchNumbers.get(branchName); + if (branchNumber == null) { + throw new BranchProblemException("No such branch: " + branchName); + } + + int revision = inform.branchEnds.get(branchNumber); + inform.branchEnds.remove(branchNumber); + + while (revision >= 0 && inform.numberOfStartedBranchesAtRevision.get(revision) == 0) { + for (Integer fileNumber : inform.commitedFiles.get(revision)) { + FileUtils.forceDelete( + getStoragePath( + Paths.get(inform.getStringByNumber(fileNumber, inform.fileNumber)), revision) + .toFile()); + } + inform.commitedFiles.get(revision).clear(); + revision = inform.prevCommit.get(revision); + } + + if (revision >= 0) { + addAtIdx(inform.numberOfStartedBranchesAtRevision, revision, -1); + } + + updateRepInformation(); + } } diff --git a/hw_git/src/main/java/hw_git/RepInformation.java b/hw_git/src/main/java/hw_git/RepInformation.java index 50fdea2..8dc0ced 100644 --- a/hw_git/src/main/java/hw_git/RepInformation.java +++ b/hw_git/src/main/java/hw_git/RepInformation.java @@ -14,6 +14,7 @@ public class RepInformation { int currentBranchNumber = 0; int nCommits = 0; int nFiles = 0; + int lastBranchNumber = 0; ArrayList commitMessages = new ArrayList<>(); @@ -22,6 +23,8 @@ public class RepInformation { ArrayList prevCommit = new ArrayList<>(); ArrayList> commitedFiles = new ArrayList<>(); + + ArrayList> removedFiles = new ArrayList<>(); TreeMap fileNumber = new TreeMap<>(); @@ -29,8 +32,10 @@ public class RepInformation { TreeMap branchEnds = new TreeMap<>(); + ArrayList numberOfStartedBranchesAtRevision = new ArrayList<>(); + public RepInformation() { - branchNumbers.put("master", -1); + branchNumbers.put("master", 0); branchEnds.put(0, -1); } @@ -51,7 +56,9 @@ String getCurrentBranchName() { int currentBranchLastRevision() { return branchEnds.get(currentBranchNumber); } - + +// Automatic getters and setters + public int getRevision() { return revision; } @@ -107,6 +114,14 @@ public ArrayList> getCommitedFiles() { public void setCommitedFiles(ArrayList> commitedFiles) { this.commitedFiles = commitedFiles; } + + public ArrayList> getRemovedFiles() { + return removedFiles; + } + + public void setRemovedFiles(ArrayList> removedFiles) { + this.removedFiles = removedFiles; + } public TreeMap getFileNumber() { return fileNumber; @@ -139,4 +154,20 @@ public int getnFiles() { public void setnFiles(int nFiles) { this.nFiles = nFiles; } + + public int getLastBranchNumber() { + return lastBranchNumber; + } + + public void setLastBranchNumber(int lastBranchNumber) { + this.lastBranchNumber = lastBranchNumber; + } + + public ArrayList getNumberOfStartedBranchesAtRevision() { + return numberOfStartedBranchesAtRevision; + } + + public void setNumberOfStartedBranchesAtRevision(ArrayList numberOfStartedBrancesAtRevision) { + this.numberOfStartedBranchesAtRevision = numberOfStartedBrancesAtRevision; + } } diff --git a/hw_git/src/test/java/hw_git/AppTest.java b/hw_git/src/test/java/hw_git/AppTest.java index 60312bc..ebeb332 100644 --- a/hw_git/src/test/java/hw_git/AppTest.java +++ b/hw_git/src/test/java/hw_git/AppTest.java @@ -146,10 +146,15 @@ public void testRM() throws JsonGenerationException, JsonMappingException, IOExc GitCli.main(new String[] {"init"}); GitCli.main(new String[] {"add", "testdir/file.txt"}); GitCli.main(new String[] {"commit", "message 1"}); + GitCli.main(new String[] {"add", "testdir/file.txt"}); + GitCli.main(new String[] {"commit", "message 2"}); Files.delete(Paths.get("testdir/file.txt")); GitCli.main(new String[] {"rm", "testdir/file.txt"}); - GitCli.main(new String[] {"checkout", "1"}); + GitCli.main(new String[] {"checkout", "2"}); assertFalse(Files.exists(Paths.get("testdir/file.txt"))); + + GitCli.main(new String[] {"checkout", "1"}); + assertTrue(Files.exists(Paths.get("testdir/file.txt"))); } @Test From 4f096cca257e4f096caf798eb811261a8d62f3ba Mon Sep 17 00:00:00 2001 From: Anton Date: Mon, 8 Oct 2018 02:01:12 +0300 Subject: [PATCH 06/16] remove only at current revision --- hw_git/src/main/java/hw_git/GitCli.java | 2 +- hw_git/src/main/java/hw_git/GitCore.java | 54 +++++++++---------- .../src/main/java/hw_git/RepInformation.java | 2 +- 3 files changed, 29 insertions(+), 29 deletions(-) diff --git a/hw_git/src/main/java/hw_git/GitCli.java b/hw_git/src/main/java/hw_git/GitCli.java index cf79395..574c7ca 100644 --- a/hw_git/src/main/java/hw_git/GitCli.java +++ b/hw_git/src/main/java/hw_git/GitCli.java @@ -73,7 +73,7 @@ public static void main(String[] args) throws JsonGenerationException, JsonMappi } catch (BranchProblemException e) { System.out.println(e.message); } catch (FileNotFoundException e) { - System.out.println(e.getLocalizedMessage()); + System.out.println(e.getMessage()); } } } diff --git a/hw_git/src/main/java/hw_git/GitCore.java b/hw_git/src/main/java/hw_git/GitCore.java index 65de53b..b8c28e0 100644 --- a/hw_git/src/main/java/hw_git/GitCore.java +++ b/hw_git/src/main/java/hw_git/GitCore.java @@ -98,6 +98,7 @@ private void addFile(Path filepath) throws IOException { if (inform.nCommits <= revision) { inform.nCommits++; inform.commitedFiles.add(new TreeSet<>()); + inform.removedFiles.add(new TreeSet<>()); inform.prevCommit.add(inform.branchEnds.get(inform.currentBranchNumber)); inform.branchEnds.put(inform.currentBranchNumber, revision); inform.numberOfStartedBranchesAtRevision.add(0); @@ -180,23 +181,22 @@ private void deleteVersionedFiles(File root) { } private void restoreVersionedFiles(int revision) throws IOException { - Set restoredNumbers = new TreeSet<>(); - while (revision >= 0) { - Set revFiles = inform.commitedFiles.get(revision); - for (Integer fileNumber : revFiles) { - if (restoredNumbers.contains(fileNumber)) { - continue; - } - - restoredNumbers.add(fileNumber); - - String keyName = inform.getStringByNumber(fileNumber, inform.fileNumber); - FileUtils.copyFile( - informPath.resolve(getStoragePath(Paths.get(keyName), revision)).toFile(), - informPath.resolve(keyName).toFile()); - - } - revision = inform.prevCommit.get(revision); + if (revision < 0) { + return; + } + + restoreVersionedFiles(inform.prevCommit.get(revision)); + + for (Integer fileNumber : inform.commitedFiles.get(revision)) { + String keyName = RepInformation.getStringByNumber(fileNumber, inform.fileNumber); + FileUtils.copyFile( + informPath.resolve(getStoragePath(Paths.get(keyName), revision)).toFile(), + informPath.resolve(keyName).toFile()); + } + + for (Integer fileNumber : inform.removedFiles.get(revision)) { + String keyName = RepInformation.getStringByNumber(fileNumber, inform.fileNumber); + FileUtils.forceDelete(informPath.resolve(keyName).toFile()); } } @@ -341,16 +341,16 @@ int getCurrentRevision() { private void removeFromRep(String filename) throws IOException { Path keypath = getKeyPath(filename); - System.out.println("keypath: " + keypath); - for (int revision = inform.currentBranchLastRevision(); - revision >= 0; - revision = inform.prevCommit.get(revision)) { - if (inform.commitedFiles.get(revision).remove(inform.fileNumber.get(keypath.toString()))) { - System.out.println("keypath: " + keypath.toString()); - Files.delete(getStoragePath(keypath, revision)); - break; - } + int revision = inform.revision; + + Integer fileNumber = inform.fileNumber.get(keypath.toString()); + + if (fileNumber == null) { + throw new FileNotFoundException("File not versioned: " + filename); } + + inform.removedFiles.get(revision).add(fileNumber); + Files.deleteIfExists(informPath.resolve(stageFolder).resolve(keypath)); //inform.fileNumber.remove(keypath.toString()); } @@ -390,7 +390,7 @@ void makeDeleteBranch(String branchName) throws JsonParseException, JsonMappingE for (Integer fileNumber : inform.commitedFiles.get(revision)) { FileUtils.forceDelete( getStoragePath( - Paths.get(inform.getStringByNumber(fileNumber, inform.fileNumber)), revision) + Paths.get(RepInformation.getStringByNumber(fileNumber, inform.fileNumber)), revision) .toFile()); } inform.commitedFiles.get(revision).clear(); diff --git a/hw_git/src/main/java/hw_git/RepInformation.java b/hw_git/src/main/java/hw_git/RepInformation.java index 8dc0ced..07a7e2f 100644 --- a/hw_git/src/main/java/hw_git/RepInformation.java +++ b/hw_git/src/main/java/hw_git/RepInformation.java @@ -39,7 +39,7 @@ public RepInformation() { branchEnds.put(0, -1); } - String getStringByNumber(Integer i, Map map) { + static String getStringByNumber(Integer i, Map map) { for (Entry ent : map.entrySet()) { if (ent.getValue().equals(i)) { return ent.getKey(); From 4095ec951e81210189682e02fa6b3e3f827fc2b2 Mon Sep 17 00:00:00 2001 From: Anton Date: Sun, 14 Oct 2018 15:15:26 +0300 Subject: [PATCH 07/16] =?UTF-8?q?=D0=A4=D1=83=D0=BD=D0=BA=D1=86=D0=B8?= =?UTF-8?q?=D0=BE=D0=BD=D0=B0=D0=BB=D1=8C=D0=BD=D0=BE=D1=81=D1=82=D1=8C=20?= =?UTF-8?q?=D0=B8=20=D1=82=D0=B5=D1=81=D1=82=D1=8B=20=D0=B7=D0=B0=D0=B4?= =?UTF-8?q?=D0=B0=D0=BD=D0=B8=D1=8F=203.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- hw_git/src/main/java/hw_git/GitCli.java | 81 ++++++++++- hw_git/src/main/java/hw_git/GitCore.java | 132 ++++++++++++++--- .../src/main/java/hw_git/RepInformation.java | 1 - hw_git/src/test/java/hw_git/AppTest.java | 135 +++++++++++++++++- 4 files changed, 317 insertions(+), 32 deletions(-) diff --git a/hw_git/src/main/java/hw_git/GitCli.java b/hw_git/src/main/java/hw_git/GitCli.java index 574c7ca..065ac71 100644 --- a/hw_git/src/main/java/hw_git/GitCli.java +++ b/hw_git/src/main/java/hw_git/GitCli.java @@ -1,14 +1,60 @@ package hw_git; +import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; +import java.nio.file.Path; +import java.nio.file.Paths; import java.util.Arrays; +import java.util.Scanner; 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 { + public static void printFile(Path p) { + try (Scanner in = new Scanner(new File(p.toString()))) { + System.out.println(p.toString()); + System.out.println("--------------------------------"); + while (in.hasNextLine()) { + System.out.println(in.nextLine()); + } + System.out.println("--------------------------------"); + } catch (FileNotFoundException e) { + System.out.println("File " + p.toString() + " not found"); + } + } + + public static Path conflictFileChooser(Path p1, Path p2) { + System.out.println("merge conflict between " + p1.toString() + "and" + p2.toString()); + printFile(p1); + printFile(p2); + int choice = 0; + while (!(choice == 1 || choice == 2 || choice == 3)) { + System.out.println("Enter \"1\", if you want to use first file in merging\n" + + "Enter \"2\" to use second\n" + + "Enter \"3\" to specify file manually"); + try (Scanner in = new Scanner(System.in)) { + choice = in.nextInt(); + } catch (Exception e) {} + } + + switch (choice) { + case 1: + return p1; + case 2: + return p2; + default: + String choosenPath = null; + System.out.println("Specify path to file:"); + try (Scanner in = new Scanner(System.in)) { + choosenPath = in.nextLine(); + } + return Paths.get(choosenPath); + } + } + + public static void main(String[] args) throws JsonGenerationException, JsonMappingException{ GitCore core = new GitCore(); int revision; @@ -28,12 +74,18 @@ public static void main(String[] args) throws JsonGenerationException, JsonMappi System.out.println("Commit made at revision " + core.getCurrentRevision()); break; case "checkout": - try { - revision = Integer.parseInt(args[1]); - System.out.println("Check out to revision " + revision); - core.makeCheckout(revision); - } catch (NumberFormatException e) { + if (args[1].equals("--")) { + System.out.println("Checking out files..."); core.makeCheckout(Arrays.copyOfRange(args, 2, args.length)); + } else { + try { + revision = Integer.parseInt(args[1]); + System.out.println("Check out to revision " + revision); + core.makeCheckout(revision - 1); + } catch (NumberFormatException e) { + System.out.println("Checking out branch..."); + core.makeCheckout(args[1]); + } } break; case "reset": @@ -43,7 +95,7 @@ public static void main(String[] args) throws JsonGenerationException, JsonMappi break; case "log": revision = args.length == 2 ? Integer.parseInt(args[1]) : -1; - System.out.println("Log: " + core.getLog(revision)); + System.out.println("Log: " + core.getLog(revision - 1)); break; case "rm": System.out.println("Removing..."); @@ -65,6 +117,19 @@ public static void main(String[] args) throws JsonGenerationException, JsonMappi System.out.println(fname); } break; + case "branch": + if (args[1].equals("-d")) { + System.out.println("Deleting branch " + args[2]); + core.makeDeleteBranch(args[2]); + } else { + System.out.println("Making branch " + args[1]); + core.makeBranch(args[1]); + } + break; + case "merge": + System.out.println("Merging branch " + args[1] + "to" + core.getCurrentBranchName()); + core.makeMerge(args[1], GitCli::conflictFileChooser); + break; default: System.out.println("Unknown argument: " + args[0]); } @@ -74,6 +139,8 @@ public static void main(String[] args) throws JsonGenerationException, JsonMappi System.out.println(e.message); } catch (FileNotFoundException e) { System.out.println(e.getMessage()); + } catch (IOException e) { + System.out.println("IOException: " + e.getMessage()); } } } diff --git a/hw_git/src/main/java/hw_git/GitCore.java b/hw_git/src/main/java/hw_git/GitCore.java index b8c28e0..b2e5db4 100644 --- a/hw_git/src/main/java/hw_git/GitCore.java +++ b/hw_git/src/main/java/hw_git/GitCore.java @@ -12,7 +12,11 @@ import java.sql.Timestamp; import java.util.ArrayList; import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.function.BiFunction; import java.util.Set; +import java.util.TreeMap; import java.util.TreeSet; import org.apache.commons.io.FileUtils; @@ -61,14 +65,10 @@ void makeInit() throws JsonGenerationException, JsonMappingException, IOExceptio informPath = Paths.get(""); inform = new RepInformation(); updateRepInformation(); - System.out.println("Ok."); + System.out.println("Repository initiated."); } } - void increaseRevisionNumber() { - inform.revision++; - } - void addAtIdx(ArrayList list, int idx, int inc) { list.set(idx, list.get(idx) + inc); } @@ -124,7 +124,8 @@ void makeCommit(String message) throws IOException, UnversionedException, Branch if (inform.revision != inform.currentBranchLastRevision()) { throw new BranchProblemException("Staying not at end of some branch"); } - increaseRevisionNumber(); + //increaseRevisionNumber(); + inform.revision = inform.nCommits; inform.commitMessages.add(message); inform.timestamps.add(new Timestamp(System.currentTimeMillis())); Files.walkFileTree( @@ -180,32 +181,45 @@ private void deleteVersionedFiles(File root) { } } - private void restoreVersionedFiles(int revision) throws IOException { + private void collectVersionedFiles(int revision, Map filesToRestore) throws IOException { if (revision < 0) { return; } - restoreVersionedFiles(inform.prevCommit.get(revision)); + collectVersionedFiles(inform.prevCommit.get(revision), filesToRestore); for (Integer fileNumber : inform.commitedFiles.get(revision)) { - String keyName = RepInformation.getStringByNumber(fileNumber, inform.fileNumber); - FileUtils.copyFile( - informPath.resolve(getStoragePath(Paths.get(keyName), revision)).toFile(), - informPath.resolve(keyName).toFile()); + filesToRestore.put(fileNumber, revision); } for (Integer fileNumber : inform.removedFiles.get(revision)) { - String keyName = RepInformation.getStringByNumber(fileNumber, inform.fileNumber); - FileUtils.forceDelete(informPath.resolve(keyName).toFile()); + filesToRestore.remove(fileNumber); } + } + private void restoreFile(Integer fileNumber, Integer revision) throws IOException { + String keyName = RepInformation.getStringByNumber(fileNumber, inform.fileNumber); + FileUtils.copyFile( + informPath.resolve(getStoragePath(Paths.get(keyName), revision)).toFile(), + informPath.resolve(keyName).toFile() + ); + } + void makeCheckout(int revision) throws IOException, UnversionedException { - revision--; + //revision--; findRepInformation(); deleteVersionedFiles(informPath.toAbsolutePath().toFile()); - restoreVersionedFiles(revision); + + Map filesToRestore = new TreeMap<>(); + collectVersionedFiles(revision, filesToRestore); + + for (Entry fileEntry : filesToRestore.entrySet()) { + restoreFile(fileEntry.getKey(), fileEntry.getValue()); + } + inform.revision = revision; + inform.currentBranchNumber = -1; updateRepInformation(); } @@ -217,12 +231,15 @@ void makeCheckout(String branchName) throws JsonParseException, JsonMappingExcep } int branchRevision = inform.branchEnds.get(branchNumber); + makeCheckout(branchRevision); + inform.currentBranchNumber = branchNumber; + updateRepInformation(); } private int getLastRevisionOfFile(String keyName) { int revision = inform.currentBranchLastRevision(); - while (revision > 0 && !inform.commitedFiles.get(revision).contains(inform.fileNumber.get(keyName))) { + while (revision >= 0 && !inform.commitedFiles.get(revision).contains(inform.fileNumber.get(keyName))) { revision = inform.prevCommit.get(revision); } return revision; @@ -231,7 +248,7 @@ private int getLastRevisionOfFile(String keyName) { private void checkoutFile(Path keyPath) throws IOException { int revision = getLastRevisionOfFile(keyPath.toString()); if (revision == -1) { - throw new FileNotFoundException(); + throw new FileNotFoundException("No file " + keyPath.toString() + " found"); } FileUtils.copyFile(getStoragePath(keyPath, revision).toFile(), informPath.resolve(keyPath).toFile()); @@ -251,7 +268,7 @@ void makeReset(int revision) throws JsonParseException, JsonMappingException, IO } String getLog(int revision) throws JsonParseException, JsonMappingException, IOException, UnversionedException { - revision--; + //revision--; findRepInformation(); if (revision == -1) { revision = inform.revision; @@ -369,7 +386,7 @@ void makeBranch(String branchName) throws JsonParseException, JsonMappingExcepti throw new BranchProblemException("Branch already exists: " + branchName); } - Integer newBranchNumber = inform.lastBranchNumber++; + Integer newBranchNumber = ++inform.lastBranchNumber; inform.branchNumbers.put(branchName, newBranchNumber); inform.branchEnds.put(newBranchNumber, inform.revision); addAtIdx(inform.numberOfStartedBranchesAtRevision, inform.revision, 1); @@ -377,21 +394,31 @@ void makeBranch(String branchName) throws JsonParseException, JsonMappingExcepti } void makeDeleteBranch(String branchName) throws JsonParseException, JsonMappingException, IOException, UnversionedException, BranchProblemException { + makeCheckout(branchName); findRepInformation(); Integer branchNumber = inform.branchNumbers.get(branchName); if (branchNumber == null) { throw new BranchProblemException("No such branch: " + branchName); } - int revision = inform.branchEnds.get(branchNumber); + Integer revision = inform.branchEnds.get(branchNumber); + if (inform.numberOfStartedBranchesAtRevision.get(revision) > 0) { + throw new BranchProblemException("There is no free end of branch " + branchName); + } + inform.branchEnds.remove(branchNumber); + inform.branchNumbers.remove(branchName); + while (revision >= 0 && inform.numberOfStartedBranchesAtRevision.get(revision) == 0) { for (Integer fileNumber : inform.commitedFiles.get(revision)) { - FileUtils.forceDelete( + Files.deleteIfExists( getStoragePath( Paths.get(RepInformation.getStringByNumber(fileNumber, inform.fileNumber)), revision) - .toFile()); + ); + Files.deleteIfExists( + informPath.resolve( + RepInformation.getStringByNumber(fileNumber, inform.fileNumber))); } inform.commitedFiles.get(revision).clear(); revision = inform.prevCommit.get(revision); @@ -400,7 +427,66 @@ void makeDeleteBranch(String branchName) throws JsonParseException, JsonMappingE if (revision >= 0) { addAtIdx(inform.numberOfStartedBranchesAtRevision, revision, -1); } + + inform.currentBranchNumber = -1; + updateRepInformation(); + } + + void makeMerge(String otherBranchName, BiFunction fileChooser) throws JsonParseException, JsonMappingException, IOException, UnversionedException, BranchProblemException { + findRepInformation(); + Integer otherBranchNumber = inform.branchNumbers.get(otherBranchName); + if (otherBranchNumber == null) { + throw new BranchProblemException("No branch with name " + otherBranchName + " found."); + } + + if (inform.currentBranchNumber == -1) { + throw new BranchProblemException("You have to stay at some branch before merging"); + } + + int currRev = inform.currentBranchLastRevision(); + int otherRev = inform.branchEnds.get(otherBranchNumber); + + Map + filesToRestoreCurrent = new TreeMap<>(), + filesToRestoreOther = new TreeMap<>(); + + collectVersionedFiles(currRev, filesToRestoreCurrent); + collectVersionedFiles(otherRev, filesToRestoreOther); + + for (Entry fileEntry : filesToRestoreCurrent.entrySet()) { + if (!filesToRestoreOther.containsKey(fileEntry.getKey()) + || fileEntry.getValue() + .equals(filesToRestoreOther.get(fileEntry.getKey()))) { + restoreFile(fileEntry.getKey(), fileEntry.getValue()); + } else { + Path keyPath = Paths.get(RepInformation.getStringByNumber(fileEntry.getValue(), inform.fileNumber)); + boolean choosenSuccessfully = false; + while (!choosenSuccessfully) { + try { + FileUtils.copyFile( + fileChooser.apply( + getStoragePath(keyPath, currRev), + getStoragePath(keyPath, otherRev)).toFile(), + informPath.resolve(keyPath).toFile()); + choosenSuccessfully = true; + } catch (FileNotFoundException e) { + + } + } + } + } + + for (Entry fileEntry : filesToRestoreOther.entrySet()) { + if (!filesToRestoreCurrent.containsKey(fileEntry.getKey())) { + restoreFile(fileEntry.getKey(), fileEntry.getValue()); + } + } updateRepInformation(); } + + String getCurrentBranchName() throws JsonParseException, JsonMappingException, IOException, UnversionedException { + findRepInformation(); + return inform.getCurrentBranchName(); + } } diff --git a/hw_git/src/main/java/hw_git/RepInformation.java b/hw_git/src/main/java/hw_git/RepInformation.java index 07a7e2f..7cdde3f 100644 --- a/hw_git/src/main/java/hw_git/RepInformation.java +++ b/hw_git/src/main/java/hw_git/RepInformation.java @@ -2,7 +2,6 @@ import java.sql.Timestamp; import java.util.ArrayList; -import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Set; diff --git a/hw_git/src/test/java/hw_git/AppTest.java b/hw_git/src/test/java/hw_git/AppTest.java index ebeb332..bff8fdf 100644 --- a/hw_git/src/test/java/hw_git/AppTest.java +++ b/hw_git/src/test/java/hw_git/AppTest.java @@ -1,18 +1,21 @@ package hw_git; import java.io.File; -import java.io.FileReader; +import java.io.FileNotFoundException; import java.io.IOException; import java.io.PrintWriter; import java.nio.file.Files; +import java.nio.file.Path; import java.nio.file.Paths; import java.util.Arrays; import java.util.Scanner; +import java.util.function.BiFunction; import org.apache.commons.io.FileUtils; import com.fasterxml.jackson.core.JsonGenerationException; +import com.fasterxml.jackson.core.JsonParseException; import com.fasterxml.jackson.databind.JsonMappingException; import org.junit.After; @@ -180,4 +183,134 @@ public void testStatus() throws JsonGenerationException, JsonMappingException, I assertEquals(core.getDeletedFiles(), Arrays.asList("testdir/file.txt")); } + + @Test + public void testAddBranch() throws UnversionedException, JsonParseException, IOException { + GitCore core = new GitCore(); + GitCli.main(new String[] {"init"}); + GitCli.main(new String[] {"add", "testdir/file.txt"}); + GitCli.main(new String[] {"commit", "message 1"}); + + assertEquals("master", core.getCurrentBranchName()); + + GitCli.main(new String[] {"branch", "b1"}); + + assertEquals("master", core.getCurrentBranchName()); + + GitCli.main(new String[] {"checkout", "b1"}); + + assertEquals("b1", core.getCurrentBranchName()); + } + + @Test + public void testFilesInBranches() throws JsonGenerationException, JsonMappingException, FileNotFoundException { + GitCli.main(new String[] {"init"}); + GitCli.main(new String[] {"add", "testdir/file.txt"}); + GitCli.main(new String[] {"commit", "message 1"}); + + GitCli.main(new String[] {"branch", "b1"}); + GitCli.main(new String[] {"checkout", "b1"}); + + try(PrintWriter out = new PrintWriter(new File("testdir/dir1/file_d1.txt"))) { + out.println("b1 content"); + } + GitCli.main(new String[] {"add", "testdir/dir1/file_d1.txt"}); + GitCli.main(new String[] {"commit", "message 2"}); + + assertTrue(Files.exists(Paths.get("testdir/file.txt"))); + assertTrue(Files.exists(Paths.get("testdir/dir1/file_d1.txt"))); + + GitCli.main(new String[] {"checkout", "master"}); + + assertFalse(Files.exists(Paths.get("testdir/dir1/file_d1.txt"))); + + GitCli.main(new String[] {"branch", "b2"}); + GitCli.main(new String[] {"checkout", "b2"}); + + try(PrintWriter out = new PrintWriter(new File("testdir/dir1/file_d1.txt"))) { + out.println("b2 content"); + } + GitCli.main(new String[] {"add", "testdir/dir1/file_d1.txt"}); + GitCli.main(new String[] {"commit", "message 3"}); + + GitCli.main(new String[] {"checkout", "b1"}); + try (Scanner in = new Scanner(new File("testdir/dir1/file_d1.txt"))) { + assertEquals("b1 content", in.nextLine()); + } + GitCli.main(new String[] {"checkout", "b2"}); + try (Scanner in = new Scanner(new File("testdir/dir1/file_d1.txt"))) { + assertEquals("b2 content", in.nextLine()); + } + } + + @Test(expected = BranchProblemException.class) + public void testIncorrectBranchRm() throws JsonParseException, IOException, UnversionedException, BranchProblemException { + GitCli.main(new String[] {"init"}); + GitCli.main(new String[] {"add", "testdir/file.txt"}); + GitCli.main(new String[] {"commit", "message 1"}); + + GitCli.main(new String[] {"branch", "b1"}); + GitCli.main(new String[] {"checkout", "b1"}); + + GitCli.main(new String[] {"add", "testdir/dir1/file_d1.txt"}); + GitCli.main(new String[] {"commit", "message 2"}); + + GitCore core = new GitCore(); + core.makeDeleteBranch("master"); + } + + @Test + public void testBranchDeleteAndRestore() throws JsonParseException, IOException, UnversionedException, BranchProblemException { + GitCli.main(new String[] {"init"}); + GitCli.main(new String[] {"add", "testdir/file.txt"}); + GitCli.main(new String[] {"commit", "message 1"}); + + GitCli.main(new String[] {"branch", "b1"}); + GitCli.main(new String[] {"checkout", "b1"}); + + GitCli.main(new String[] {"add", "testdir/dir1/file_d1.txt"}); + GitCli.main(new String[] {"commit", "message 2"}); + + GitCli.main(new String[] {"branch", "-d", "b1"}); + + GitCore core = new GitCore(); + assertNull(core.getCurrentBranchName()); + + assertFalse(Files.exists(Paths.get("testdir/dir1/file_d1.txt"))); + assertTrue(Files.exists(Paths.get("testdir/file.txt"))); + + core.makeBranch("b1"); + core.makeCheckout("b1"); + assertFalse(Files.exists(Paths.get("testdir/dir1/file_d1.txt"))); + assertTrue(Files.exists(Paths.get("testdir/file.txt"))); + } + + @Test + public void testMerge() throws JsonParseException, IOException, UnversionedException, BranchProblemException { + GitCli.main(new String[] {"init"}); + GitCli.main(new String[] {"add", "testdir/file.txt"}); + GitCli.main(new String[] {"commit", "message 1"}); + + GitCli.main(new String[] {"branch", "b1"}); + GitCli.main(new String[] {"checkout", "b1"}); + + GitCli.main(new String[] {"add", "testdir/dir1/file_d1.txt"}); + GitCli.main(new String[] {"commit", "message 2"}); + + GitCli.main(new String[] {"checkout", "master"}); + + GitCore core = new GitCore(); + core.makeMerge("b1", new BiFunction() { + + @Override + public Path apply(Path t, Path u) { + // TODO Auto-generated method stub + return null; + } + }); + + assertEquals("master", core.getCurrentBranchName()); + assertTrue(Files.exists(Paths.get("testdir/dir1/file_d1.txt"))); + assertTrue(Files.exists(Paths.get("testdir/file.txt"))); + } } From bcf815e36fb7327c67281af5458a50269182f7fd Mon Sep 17 00:00:00 2001 From: Anton Date: Fri, 2 Nov 2018 01:12:56 +0300 Subject: [PATCH 08/16] =?UTF-8?q?=D0=A1=D0=B4=D0=B5=D0=BB=D0=B0=D0=BD?= =?UTF-8?q?=D0=B0=20=D1=81=D0=B1=D0=BE=D1=80=D0=BA=D0=B0=20=D0=B2=20jar.?= =?UTF-8?q?=20=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=20=D1=81?= =?UTF-8?q?=D0=BA=D1=80=D0=B8=D0=BF=D1=82=20=D0=B4=D0=BB=D1=8F=20=D0=B7?= =?UTF-8?q?=D0=B0=D0=BF=D1=83=D1=81=D0=BA=D0=B0.=20=D0=94=D0=BE=D0=B1?= =?UTF-8?q?=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=D0=BE=20=D1=81=D0=BE=D0=BE=D0=B1?= =?UTF-8?q?=D1=89=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=BE=20=D0=BD=D0=B5=D0=B4?= =?UTF-8?q?=D0=BE=D1=81=D1=82=D0=B0=D1=82=D0=BE=D1=87=D0=BD=D0=BE=D0=BC=20?= =?UTF-8?q?=D0=BA=D0=BE=D0=BB=D0=B8=D1=87=D0=B5=D1=81=D1=82=D0=B2=D0=B5=20?= =?UTF-8?q?=D0=B0=D1=80=D0=B3=D1=83=D0=BC=D0=B5=D0=BD=D1=82=D0=BE=D0=B2.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 5 ++-- hw_git/mygit | 3 +++ hw_git/pom.xml | 34 ++++++++++++++++++++++++ hw_git/src/main/java/hw_git/GitCli.java | 2 ++ hw_git/src/main/java/hw_git/GitCore.java | 6 ++--- hw_git/src/test/java/hw_git/AppTest.java | 12 +++++---- 6 files changed, 52 insertions(+), 10 deletions(-) create mode 100755 hw_git/mygit diff --git a/README.md b/README.md index 8feee6a..5eeb441 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,8 @@ ## Мой GIT. -Для запуска выполните +Пример использования: + ``` -mvn exec:java -Dexec.mainClass=hw_git.GitCli -Dexec.args="commit commessage testdir/file1" +./mygit commit "добавлен первый файл в репозиторий" ``` diff --git a/hw_git/mygit b/hw_git/mygit new file mode 100755 index 0000000..0b61618 --- /dev/null +++ b/hw_git/mygit @@ -0,0 +1,3 @@ +#!/bin/bash + +java -jar target/hw_git-0.0.1-SNAPSHOT.jar $@ diff --git a/hw_git/pom.xml b/hw_git/pom.xml index 59b3034..5d69e27 100644 --- a/hw_git/pom.xml +++ b/hw_git/pom.xml @@ -23,6 +23,40 @@ UTF-8 + + org.apache.maven.plugins + maven-jar-plugin + 3.1.0 + + + + true + hw_git.GitCli + hw_git + true + lib/ + + + + + + org.apache.maven.plugins + maven-dependency-plugin + 3.1.0 + + + copy-dependencies + package + + copy-dependencies + + + compile + ${project.build.directory}/lib + + + + diff --git a/hw_git/src/main/java/hw_git/GitCli.java b/hw_git/src/main/java/hw_git/GitCli.java index 065ac71..0bc14f8 100644 --- a/hw_git/src/main/java/hw_git/GitCli.java +++ b/hw_git/src/main/java/hw_git/GitCli.java @@ -141,6 +141,8 @@ public static void main(String[] args) throws JsonGenerationException, JsonMappi System.out.println(e.getMessage()); } catch (IOException e) { System.out.println("IOException: " + e.getMessage()); + } catch (ArrayIndexOutOfBoundsException e) { + System.out.println("Lack of arguments"); } } } diff --git a/hw_git/src/main/java/hw_git/GitCore.java b/hw_git/src/main/java/hw_git/GitCore.java index b2e5db4..4a9d008 100644 --- a/hw_git/src/main/java/hw_git/GitCore.java +++ b/hw_git/src/main/java/hw_git/GitCore.java @@ -29,8 +29,8 @@ public class GitCore { private RepInformation inform = null; private Path informPath = null; - private final String infoFileName = ".myGitData"; - private final String storageFolder = ".mygitdata"; + private final String infoFileName = ".myGitDataFile"; + private final String storageFolder = ".myGitDataStorage"; private final String stageFolder = ".stageData"; void findRepInformation() throws JsonParseException, JsonMappingException, IOException, UnversionedException { @@ -124,7 +124,7 @@ void makeCommit(String message) throws IOException, UnversionedException, Branch if (inform.revision != inform.currentBranchLastRevision()) { throw new BranchProblemException("Staying not at end of some branch"); } - //increaseRevisionNumber(); + inform.revision = inform.nCommits; inform.commitMessages.add(message); inform.timestamps.add(new Timestamp(System.currentTimeMillis())); diff --git a/hw_git/src/test/java/hw_git/AppTest.java b/hw_git/src/test/java/hw_git/AppTest.java index bff8fdf..9ee3e27 100644 --- a/hw_git/src/test/java/hw_git/AppTest.java +++ b/hw_git/src/test/java/hw_git/AppTest.java @@ -25,7 +25,9 @@ import org.junit.Test; public class AppTest extends Assert { - + + final String storageFilename = ".myGitDataFile"; + final String storageFolder = ".myGitDataStorage"; @Before public void setUp() throws IOException { //System.out.println("setUp"); @@ -38,9 +40,9 @@ public void setUp() throws IOException { 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")); + FileUtils.deleteDirectory(Paths.get(storageFolder).toFile()); + if (Files.exists(Paths.get(storageFilename))) { + Files.delete(Paths.get(storageFilename)); } } @@ -138,7 +140,7 @@ public void testReset() throws JsonGenerationException, JsonMappingException, IO GitCli.main(new String[] {"commit", "message 2"}); GitCli.main(new String[] {"reset", "1"}); String s2; - try (Scanner in = new Scanner(new File(".myGitData"))) { + try (Scanner in = new Scanner(new File(storageFilename))) { s2 = in.nextLine(); } assertEquals(s1, s2); From 1723c0cdb493b93fe352b38f7d666690a4a851c3 Mon Sep 17 00:00:00 2001 From: Anton Date: Fri, 2 Nov 2018 11:20:24 +0300 Subject: [PATCH 09/16] =?UTF-8?q?=D0=9C=D0=B5=D0=BB=D0=BA=D0=B8=D0=B5=20?= =?UTF-8?q?=D0=B8=D1=81=D0=BF=D1=80=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8?= =?UTF-8?q?=D1=8F.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- hw_git/mygit | 2 +- hw_git/src/main/java/hw_git/GitCli.java | 8 +- hw_git/src/main/java/hw_git/GitCore.java | 99 ++++++++++------- .../src/main/java/hw_git/RepInformation.java | 6 +- hw_git/src/test/java/hw_git/AppTest.java | 100 +++++++++++++++++- 5 files changed, 167 insertions(+), 48 deletions(-) diff --git a/hw_git/mygit b/hw_git/mygit index 0b61618..d59a813 100755 --- a/hw_git/mygit +++ b/hw_git/mygit @@ -1,3 +1,3 @@ #!/bin/bash -java -jar target/hw_git-0.0.1-SNAPSHOT.jar $@ +java -jar target/hw_git-0.0.1-SNAPSHOT.jar "$@" diff --git a/hw_git/src/main/java/hw_git/GitCli.java b/hw_git/src/main/java/hw_git/GitCli.java index 0bc14f8..875a6f3 100644 --- a/hw_git/src/main/java/hw_git/GitCli.java +++ b/hw_git/src/main/java/hw_git/GitCli.java @@ -26,7 +26,7 @@ public static void printFile(Path p) { } public static Path conflictFileChooser(Path p1, Path p2) { - System.out.println("merge conflict between " + p1.toString() + "and" + p2.toString()); + System.out.println("merge conflict between " + p1.toString() + " and " + p2.toString()); printFile(p1); printFile(p2); int choice = 0; @@ -71,7 +71,7 @@ public static void main(String[] args) throws JsonGenerationException, JsonMappi case "commit": System.out.println("Commiting..."); core.makeCommit(args[1]); - System.out.println("Commit made at revision " + core.getCurrentRevision()); + System.out.println("Commit made at revision " + (core.getCurrentRevision() + 1)); break; case "checkout": if (args[1].equals("--")) { @@ -94,7 +94,7 @@ public static void main(String[] args) throws JsonGenerationException, JsonMappi core.makeReset(revision); break; case "log": - revision = args.length == 2 ? Integer.parseInt(args[1]) : -1; + revision = args.length == 2 ? Integer.parseInt(args[1]) : 0; System.out.println("Log: " + core.getLog(revision - 1)); break; case "rm": @@ -127,7 +127,7 @@ public static void main(String[] args) throws JsonGenerationException, JsonMappi } break; case "merge": - System.out.println("Merging branch " + args[1] + "to" + core.getCurrentBranchName()); + System.out.println("Merging branch " + args[1] + " to " + core.getCurrentBranchName()); core.makeMerge(args[1], GitCli::conflictFileChooser); break; default: diff --git a/hw_git/src/main/java/hw_git/GitCore.java b/hw_git/src/main/java/hw_git/GitCore.java index 4a9d008..0cee08b 100644 --- a/hw_git/src/main/java/hw_git/GitCore.java +++ b/hw_git/src/main/java/hw_git/GitCore.java @@ -83,7 +83,7 @@ private Path getStoragePath(Path keyPath, int revision) { .resolve(keyPath.getFileName().toString() + "r" + revision); } - private void addFile(Path filepath) throws IOException { + private void addFileDuringCommit(Path filepath) throws IOException { int revision = inform.revision; Path keyPath = filepath.subpath(1, filepath.getNameCount()); Path storage = getStoragePath(keyPath, revision); @@ -94,15 +94,6 @@ private void addFile(Path filepath) throws IOException { System.out.println(keyName); inform.fileNumber.put(keyName, inform.nFiles++); } - - if (inform.nCommits <= revision) { - inform.nCommits++; - inform.commitedFiles.add(new TreeSet<>()); - inform.removedFiles.add(new TreeSet<>()); - inform.prevCommit.add(inform.branchEnds.get(inform.currentBranchNumber)); - inform.branchEnds.put(inform.currentBranchNumber, revision); - inform.numberOfStartedBranchesAtRevision.add(0); - } Set currentRevisionFiles = inform.commitedFiles.get(revision); assert inform.fileNumber.get(keyName) != null; @@ -121,42 +112,51 @@ void makeAdd(String[] filenames) throws IOException, UnversionedException { void makeCommit(String message) throws IOException, UnversionedException, BranchProblemException { findRepInformation(); - if (inform.revision != inform.currentBranchLastRevision()) { + if (inform.currentBranchNumber == -1 || + inform.revision != inform.currentBranchLastRevision()) { throw new BranchProblemException("Staying not at end of some branch"); } inform.revision = inform.nCommits; inform.commitMessages.add(message); inform.timestamps.add(new Timestamp(System.currentTimeMillis())); + + { + inform.nCommits++; + inform.commitedFiles.add(new TreeSet<>()); + inform.removedFiles.add(new TreeSet<>()); + inform.prevCommit.add(inform.branchEnds.get(inform.currentBranchNumber)); + inform.branchEnds.put(inform.currentBranchNumber, inform.revision); + inform.numberOfStartedBranchesAtRevision.add(0); + } + 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 { - addFile(file); + addFileDuringCommit(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(); } @@ -199,16 +199,19 @@ private void collectVersionedFiles(int revision, Map filesToRe } private void restoreFile(Integer fileNumber, Integer revision) throws IOException { - String keyName = RepInformation.getStringByNumber(fileNumber, inform.fileNumber); + String keyName = RepInformation.getKeyByValue(fileNumber, inform.fileNumber); FileUtils.copyFile( informPath.resolve(getStoragePath(Paths.get(keyName), revision)).toFile(), informPath.resolve(keyName).toFile() ); } - void makeCheckout(int revision) throws IOException, UnversionedException { + void makeCheckout(int revision) throws IOException, UnversionedException, BranchProblemException { //revision--; findRepInformation(); + if (revision >= inform.nCommits || revision < 0) { + throw new BranchProblemException("revision number" + (revision + 1) + " is incorrect"); + } deleteVersionedFiles(informPath.toAbsolutePath().toFile()); Map filesToRestore = new TreeMap<>(); @@ -218,9 +221,20 @@ void makeCheckout(int revision) throws IOException, UnversionedException { restoreFile(fileEntry.getKey(), fileEntry.getValue()); } + inform.revision = revision; - inform.currentBranchNumber = -1; + Integer branchNumber = RepInformation.getKeyByValue(revision, inform.branchEnds); + if (branchNumber != null) { + inform.currentBranchNumber = branchNumber; + } else { + inform.currentBranchNumber = -1; + } + updateRepInformation(); + + if (branchNumber == null) { + throw new BranchProblemException("Now you're in detached state at revision " + (revision + 1)); + } } void makeCheckout(String branchName) throws JsonParseException, JsonMappingException, IOException, UnversionedException, BranchProblemException { @@ -262,25 +276,38 @@ void makeCheckout(String[] files) throws JsonParseException, JsonMappingExceptio } } - void makeReset(int revision) throws JsonParseException, JsonMappingException, IOException, UnversionedException { + void makeReset(int revision) throws JsonParseException, JsonMappingException, IOException, UnversionedException, BranchProblemException { makeCheckout(revision); FileUtils.cleanDirectory(informPath.resolve(stageFolder).toFile()); } - String getLog(int revision) throws JsonParseException, JsonMappingException, IOException, UnversionedException { - //revision--; + String getLog(int revision) throws JsonParseException, JsonMappingException, IOException, UnversionedException, BranchProblemException { findRepInformation(); + + if (revision < -1 || revision >= inform.nCommits) { + throw new BranchProblemException("revision number " + (revision + 1) + " is incorrect"); + } + if (revision == -1) { revision = inform.revision; } - if(revision == 0) { + + if(revision == -1) { return "Empty log"; } - return + + StringBuilder sb = new StringBuilder(); + while (revision >= 0) { + sb.append( "branch " + inform.getCurrentBranchName() - +"revision: " + revision + "\n" - + inform.commitMessages.get(revision - 1) + "\n" - + inform.timestamps.get(revision - 1); + +"\nrevision: " + (revision + 1) + "\n" + + inform.commitMessages.get(revision) + "\n" + + inform.timestamps.get(revision) + "\n\n" + ); + revision = inform.prevCommit.get(revision); + } + + return sb.toString(); } List getDeletedFiles() throws JsonParseException, JsonMappingException, IOException, UnversionedException { @@ -321,14 +348,12 @@ List getUntrackedFiles() throws IOException { @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.fileNumber.containsKey(informPath.relativize(file).toString())) { result.add(file.toString()); } @@ -337,13 +362,11 @@ public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IO @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; } }); @@ -369,7 +392,6 @@ private void removeFromRep(String filename) throws IOException { inform.removedFiles.get(revision).add(fileNumber); Files.deleteIfExists(informPath.resolve(stageFolder).resolve(keypath)); - //inform.fileNumber.remove(keypath.toString()); } void makeRM(String[] files) throws IOException, UnversionedException { @@ -414,11 +436,11 @@ void makeDeleteBranch(String branchName) throws JsonParseException, JsonMappingE for (Integer fileNumber : inform.commitedFiles.get(revision)) { Files.deleteIfExists( getStoragePath( - Paths.get(RepInformation.getStringByNumber(fileNumber, inform.fileNumber)), revision) + Paths.get(RepInformation.getKeyByValue(fileNumber, inform.fileNumber)), revision) ); Files.deleteIfExists( informPath.resolve( - RepInformation.getStringByNumber(fileNumber, inform.fileNumber))); + RepInformation.getKeyByValue(fileNumber, inform.fileNumber))); } inform.commitedFiles.get(revision).clear(); revision = inform.prevCommit.get(revision); @@ -454,19 +476,20 @@ void makeMerge(String otherBranchName, BiFunction fileChooser) collectVersionedFiles(otherRev, filesToRestoreOther); for (Entry fileEntry : filesToRestoreCurrent.entrySet()) { - if (!filesToRestoreOther.containsKey(fileEntry.getKey()) + Integer otherEntRevision = filesToRestoreOther.get(fileEntry.getKey()); + if (otherEntRevision == null || fileEntry.getValue() - .equals(filesToRestoreOther.get(fileEntry.getKey()))) { + .equals(otherEntRevision)) { restoreFile(fileEntry.getKey(), fileEntry.getValue()); } else { - Path keyPath = Paths.get(RepInformation.getStringByNumber(fileEntry.getValue(), inform.fileNumber)); + Path keyPath = Paths.get(RepInformation.getKeyByValue(fileEntry.getValue(), inform.fileNumber)); boolean choosenSuccessfully = false; while (!choosenSuccessfully) { try { FileUtils.copyFile( fileChooser.apply( - getStoragePath(keyPath, currRev), - getStoragePath(keyPath, otherRev)).toFile(), + getStoragePath(keyPath, fileEntry.getValue()), + getStoragePath(keyPath, otherEntRevision)).toFile(), informPath.resolve(keyPath).toFile()); choosenSuccessfully = true; } catch (FileNotFoundException e) { diff --git a/hw_git/src/main/java/hw_git/RepInformation.java b/hw_git/src/main/java/hw_git/RepInformation.java index 7cdde3f..b30d6b2 100644 --- a/hw_git/src/main/java/hw_git/RepInformation.java +++ b/hw_git/src/main/java/hw_git/RepInformation.java @@ -38,8 +38,8 @@ public RepInformation() { branchEnds.put(0, -1); } - static String getStringByNumber(Integer i, Map map) { - for (Entry ent : map.entrySet()) { + static K getKeyByValue(V i, Map map) { + for (Entry ent : map.entrySet()) { if (ent.getValue().equals(i)) { return ent.getKey(); } @@ -49,7 +49,7 @@ static String getStringByNumber(Integer i, Map map) { } String getCurrentBranchName() { - return getStringByNumber(currentBranchNumber, branchNumbers); + return getKeyByValue(currentBranchNumber, branchNumbers); } int currentBranchLastRevision() { diff --git a/hw_git/src/test/java/hw_git/AppTest.java b/hw_git/src/test/java/hw_git/AppTest.java index 9ee3e27..5b73a0a 100644 --- a/hw_git/src/test/java/hw_git/AppTest.java +++ b/hw_git/src/test/java/hw_git/AppTest.java @@ -288,7 +288,7 @@ public void testBranchDeleteAndRestore() throws JsonParseException, IOException, } @Test - public void testMerge() throws JsonParseException, IOException, UnversionedException, BranchProblemException { + public void testMergeNoConflict() throws JsonParseException, IOException, UnversionedException, BranchProblemException { GitCli.main(new String[] {"init"}); GitCli.main(new String[] {"add", "testdir/file.txt"}); GitCli.main(new String[] {"commit", "message 1"}); @@ -306,7 +306,6 @@ public void testMerge() throws JsonParseException, IOException, UnversionedExcep @Override public Path apply(Path t, Path u) { - // TODO Auto-generated method stub return null; } }); @@ -315,4 +314,101 @@ public Path apply(Path t, Path u) { assertTrue(Files.exists(Paths.get("testdir/dir1/file_d1.txt"))); assertTrue(Files.exists(Paths.get("testdir/file.txt"))); } + + @Test + public void testMergeConflict() throws JsonParseException, IOException, UnversionedException, BranchProblemException { + GitCli.main(new String[] {"init"}); + GitCli.main(new String[] {"add", "testdir/file.txt"}); + GitCli.main(new String[] {"commit", "message 1"}); + + GitCli.main(new String[] {"commit", "message 2"}); + assertTrue(Files.exists(Paths.get(".myGitDataStorage/testdir/file.txtr0"))); + assertFalse(Files.exists(Paths.get(".myGitDataStorage/testdir/file.txtr1"))); + + GitCli.main(new String[] {"checkout", "1"}); + GitCli.main(new String[] {"branch", "b1"}); + GitCli.main(new String[] {"checkout", "b1"}); + + GitCli.main(new String[] {"add", "testdir/file.txt"}); + GitCli.main(new String[] {"commit", "message b1"}); + + GitCli.main(new String[] {"checkout", "master"}); + + GitCore core = new GitCore(); + + core.makeMerge("b1", new BiFunction() { + + @Override + public Path apply(Path t, Path u) { + assertEquals(".myGitDataStorage/testdir/file.txtr0", t.toString()); + assertEquals(".myGitDataStorage/testdir/file.txtr2", u.toString()); + return t; + } + }); + + } + + @Test + public void testLog() throws JsonParseException, IOException, UnversionedException, BranchProblemException { + GitCli.main(new String[] {"init"}); + GitCli.main(new String[] {"add", "testdir/file.txt"}); + GitCore core = new GitCore(); + assertEquals("Empty log", core.getLog(-1)); + GitCli.main(new String[] {"commit", "message 1"}); + + assertNotEquals("Empty log", core.getLog(-1)); + assertEquals(core.getLog(-1), core.getLog(0)); + } + + @Test(expected = BranchProblemException.class) + public void testIncorrectBigCheckoutRevision() throws JsonParseException, IOException, UnversionedException, BranchProblemException { + GitCli.main(new String[] {"init"}); + GitCli.main(new String[] {"add", "testdir/file.txt"}); + GitCli.main(new String[] {"commit", "message 1"}); + + GitCore core = new GitCore(); + try { + core.makeCheckout(2); + } catch (BranchProblemException bpe) { + assertEquals("revision number" + 3 + " is incorrect", bpe.message); + throw bpe; + } + } + + @Test + public void testDetachedState() throws JsonParseException, IOException, UnversionedException, BranchProblemException { + GitCli.main(new String[] {"init"}); + GitCli.main(new String[] {"add", "testdir/file.txt"}); + GitCli.main(new String[] {"commit", "message 1"}); + + GitCli.main(new String[] {"add", "testdir/file.txt"}); + GitCli.main(new String[] {"commit", "message 2"}); + + GitCore core = new GitCore(); + try { + core.makeCheckout(0); + assertTrue(false); + } catch (BranchProblemException bpe) { + assertEquals("Now you're in detached state at revision 1", bpe.message); + } + + try { + core.makeCommit("abc"); + assertTrue(false); + } catch (BranchProblemException bpe) { + assertEquals("Staying not at end of some branch", bpe.message); + } + } + + @Test + public void testEmptyCommitNotFails() throws JsonParseException, IOException, UnversionedException, BranchProblemException { + GitCli.main(new String[] {"init"}); + GitCli.main(new String[] {"add", "testdir/file.txt"}); + GitCli.main(new String[] {"commit", "message 1"}); + + GitCli.main(new String[] {"commit", "message 2"}); + + GitCore core = new GitCore(); + core.getLog(-1); + } } From 7266812535672be19cd9816b37b4c0c02a5a8977 Mon Sep 17 00:00:00 2001 From: Anton Date: Fri, 2 Nov 2018 13:29:17 +0300 Subject: [PATCH 10/16] =?UTF-8?q?=D0=98=D1=81=D0=BF=D1=80=D0=B0=D0=B2?= =?UTF-8?q?=D0=BB=D0=B5=D0=BD=D0=B0=20=D0=B1=D0=B0=D0=B3=D0=B0=20=D0=BF?= =?UTF-8?q?=D1=80=D0=B8=20=D0=BF=D0=BE=D0=BB=D1=83=D1=87=D0=B5=D0=BD=D0=B8?= =?UTF-8?q?=D0=B8=20=D0=BF=D1=83=D1=82=D0=B8=20=D0=B4=D0=BB=D1=8F=20=D1=84?= =?UTF-8?q?=D0=B0=D0=B9=D0=BB=D0=BE=D0=B2=20=D0=B2=20=D0=BA=D0=BE=D1=80?= =?UTF-8?q?=D0=BD=D0=B5.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- hw_git/src/main/java/hw_git/GitCore.java | 2 +- hw_git/src/test/java/hw_git/AppTest.java | 17 +++++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/hw_git/src/main/java/hw_git/GitCore.java b/hw_git/src/main/java/hw_git/GitCore.java index 0cee08b..9ea331b 100644 --- a/hw_git/src/main/java/hw_git/GitCore.java +++ b/hw_git/src/main/java/hw_git/GitCore.java @@ -79,7 +79,7 @@ private Path getKeyPath(String filename) { private Path getStoragePath(Path keyPath, int revision) { return informPath.resolve(storageFolder) - .resolve(keyPath.getParent()) + .resolve(keyPath.getParent() == null ? Paths.get("") : keyPath.getParent()) .resolve(keyPath.getFileName().toString() + "r" + revision); } diff --git a/hw_git/src/test/java/hw_git/AppTest.java b/hw_git/src/test/java/hw_git/AppTest.java index 5b73a0a..4e4bb00 100644 --- a/hw_git/src/test/java/hw_git/AppTest.java +++ b/hw_git/src/test/java/hw_git/AppTest.java @@ -28,12 +28,14 @@ public class AppTest extends Assert { final String storageFilename = ".myGitDataFile"; final String storageFolder = ".myGitDataStorage"; + final String stageFolder = ".stageData"; @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")); + Files.createFile(Paths.get("one.txt")); } @After @@ -41,9 +43,13 @@ public void tearDown() throws IOException { //System.out.println("tearDown"); FileUtils.deleteDirectory(Paths.get("testdir").toFile()); FileUtils.deleteDirectory(Paths.get(storageFolder).toFile()); + FileUtils.deleteDirectory(Paths.get(stageFolder).toFile()); if (Files.exists(Paths.get(storageFilename))) { Files.delete(Paths.get(storageFilename)); } + if (Files.exists(Paths.get("one.txt"))) { + Files.delete(Paths.get("one.txt")); + } } @Test @@ -411,4 +417,15 @@ public void testEmptyCommitNotFails() throws JsonParseException, IOException, Un GitCore core = new GitCore(); core.getLog(-1); } + + @Test + public void testCommitFileInRoot() throws JsonParseException, IOException, UnversionedException, BranchProblemException { + GitCli.main(new String[] {"init"}); + GitCli.main(new String[] {"add", "one.txt"}); + GitCli.main(new String[] {"commit", "message 2"}); + + GitCore core = new GitCore(); + core.getLog(-1); + } + } From e307d1524bbf335f78744a68b4c7bfb5731d4658 Mon Sep 17 00:00:00 2001 From: Anton Date: Fri, 2 Nov 2018 13:43:05 +0300 Subject: [PATCH 11/16] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D1=8B=20"=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D0=BD=D1=8B=D0=B5"=20=D1=84=D0=B0=D0=B9=D0=BB?= =?UTF-8?q?=D1=8B=20=D0=B2=20status.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- hw_git/src/main/java/hw_git/GitCli.java | 4 ++++ hw_git/src/main/java/hw_git/GitCore.java | 29 ++++++++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/hw_git/src/main/java/hw_git/GitCli.java b/hw_git/src/main/java/hw_git/GitCli.java index 875a6f3..1f9f8ce 100644 --- a/hw_git/src/main/java/hw_git/GitCli.java +++ b/hw_git/src/main/java/hw_git/GitCli.java @@ -104,6 +104,10 @@ public static void main(String[] args) throws JsonGenerationException, JsonMappi case "status": core.findRepInformation(); System.out.println("Status:"); + System.out.println("Staged files:\n________________"); + for (String fname : core.getStagedFiles()) { + System.out.println(fname); + } System.out.println("Deleted files:\n________________"); for (String fname : core.getDeletedFiles()) { System.out.println(fname); diff --git a/hw_git/src/main/java/hw_git/GitCore.java b/hw_git/src/main/java/hw_git/GitCore.java index 9ea331b..30cab99 100644 --- a/hw_git/src/main/java/hw_git/GitCore.java +++ b/hw_git/src/main/java/hw_git/GitCore.java @@ -342,6 +342,35 @@ List getChangedFiles() throws JsonParseException, JsonMappingException, return result; } + List getStagedFiles() throws JsonParseException, JsonMappingException, IOException, UnversionedException { + ArrayList result = new ArrayList<>(); + Files.walkFileTree(informPath.resolve(stageFolder), new FileVisitor() { + + @Override + public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException { + return FileVisitResult.CONTINUE; + } + + @Override + public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { + result.add(file.toString()); + return FileVisitResult.CONTINUE; + } + + @Override + public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOException { + return FileVisitResult.CONTINUE; + } + + @Override + public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException { + return FileVisitResult.CONTINUE; + } + }); + + return result; + } + List getUntrackedFiles() throws IOException { ArrayList result = new ArrayList<>(); Files.walkFileTree(Paths.get(""), new FileVisitor() { From f8c8bc1c723d5ee6b36f79ad2125263bd66f1b7c Mon Sep 17 00:00:00 2001 From: Anton Date: Sun, 4 Nov 2018 12:49:55 +0300 Subject: [PATCH 12/16] =?UTF-8?q?=D0=9E=D0=B6=D0=B8=D0=B4=D0=B0=D0=B5?= =?UTF-8?q?=D0=BC=D0=BE=D0=B5=20=D0=BF=D0=BE=D0=B2=D0=B5=D0=B4=D0=B5=D0=BD?= =?UTF-8?q?=D0=B8=D0=B5=20=D0=BF=D1=80=D0=BE=D0=B3=D1=80=D0=B0=D0=BC=D0=BC?= =?UTF-8?q?=D1=8B=20=D1=81=D1=82=D0=B0=D0=BB=D0=BE=20=D0=BF=D0=BE=D1=87?= =?UTF-8?q?=D1=82=D0=B8=20=D1=82=D0=B0=D0=BA=D0=B8=D0=BC=20=D0=B6=D0=B5,?= =?UTF-8?q?=20=D0=BA=D0=B0=D0=BA=20=D1=83=20git.=20(=D0=9A=D1=80=D0=BE?= =?UTF-8?q?=D0=BC=D0=B5=20merge)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- hw_git/src/main/java/hw_git/GitCli.java | 21 +-- hw_git/src/main/java/hw_git/GitCore.java | 120 ++++++++++-------- .../src/main/java/hw_git/RepInformation.java | 21 ++- hw_git/src/test/java/hw_git/AppTest.java | 50 +++----- 4 files changed, 107 insertions(+), 105 deletions(-) diff --git a/hw_git/src/main/java/hw_git/GitCli.java b/hw_git/src/main/java/hw_git/GitCli.java index 1f9f8ce..075d7ca 100644 --- a/hw_git/src/main/java/hw_git/GitCli.java +++ b/hw_git/src/main/java/hw_git/GitCli.java @@ -91,7 +91,7 @@ public static void main(String[] args) throws JsonGenerationException, JsonMappi case "reset": revision = Integer.parseInt(args[1]); System.out.println("Performing reset to revision " + revision); - core.makeReset(revision); + core.makeReset(revision - 1); break; case "log": revision = args.length == 2 ? Integer.parseInt(args[1]) : 0; @@ -102,24 +102,7 @@ public static void main(String[] args) throws JsonGenerationException, JsonMappi core.makeRM(Arrays.copyOfRange(args, 1, args.length)); break; case "status": - core.findRepInformation(); - System.out.println("Status:"); - System.out.println("Staged files:\n________________"); - for (String fname : core.getStagedFiles()) { - System.out.println(fname); - } - 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); - } + System.out.println(core.getStatus()); break; case "branch": if (args[1].equals("-d")) { diff --git a/hw_git/src/main/java/hw_git/GitCore.java b/hw_git/src/main/java/hw_git/GitCore.java index 30cab99..dd041d8 100644 --- a/hw_git/src/main/java/hw_git/GitCore.java +++ b/hw_git/src/main/java/hw_git/GitCore.java @@ -79,8 +79,7 @@ private Path getKeyPath(String filename) { private Path getStoragePath(Path keyPath, int revision) { return informPath.resolve(storageFolder) - .resolve(keyPath.getParent() == null ? Paths.get("") : keyPath.getParent()) - .resolve(keyPath.getFileName().toString() + "r" + revision); + .resolve(keyPath.toString() + "r" + revision); } private void addFileDuringCommit(Path filepath) throws IOException { @@ -112,8 +111,7 @@ void makeAdd(String[] filenames) throws IOException, UnversionedException { void makeCommit(String message) throws IOException, UnversionedException, BranchProblemException { findRepInformation(); - if (inform.currentBranchNumber == -1 || - inform.revision != inform.currentBranchLastRevision()) { + if (inform.currentBranchNumber == -1) { throw new BranchProblemException("Staying not at end of some branch"); } @@ -207,11 +205,11 @@ private void restoreFile(Integer fileNumber, Integer revision) throws IOExceptio } void makeCheckout(int revision) throws IOException, UnversionedException, BranchProblemException { - //revision--; findRepInformation(); if (revision >= inform.nCommits || revision < 0) { throw new BranchProblemException("revision number" + (revision + 1) + " is incorrect"); } + deleteVersionedFiles(informPath.toAbsolutePath().toFile()); Map filesToRestore = new TreeMap<>(); @@ -221,20 +219,13 @@ void makeCheckout(int revision) throws IOException, UnversionedException, Branch restoreFile(fileEntry.getKey(), fileEntry.getValue()); } - inform.revision = revision; - Integer branchNumber = RepInformation.getKeyByValue(revision, inform.branchEnds); - if (branchNumber != null) { - inform.currentBranchNumber = branchNumber; - } else { - inform.currentBranchNumber = -1; - } + inform.detachedHeadRevision = revision; + inform.currentBranchNumber = -1; updateRepInformation(); - - if (branchNumber == null) { - throw new BranchProblemException("Now you're in detached state at revision " + (revision + 1)); - } + + throw new BranchProblemException("HEAD detached on revison " + (revision + 1)); } void makeCheckout(String branchName) throws JsonParseException, JsonMappingException, IOException, UnversionedException, BranchProblemException { @@ -246,7 +237,10 @@ void makeCheckout(String branchName) throws JsonParseException, JsonMappingExcep int branchRevision = inform.branchEnds.get(branchNumber); - makeCheckout(branchRevision); + try { + makeCheckout(branchRevision); + } catch (BranchProblemException e) {} + inform.currentBranchNumber = branchNumber; updateRepInformation(); } @@ -277,13 +271,23 @@ void makeCheckout(String[] files) throws JsonParseException, JsonMappingExceptio } void makeReset(int revision) throws JsonParseException, JsonMappingException, IOException, UnversionedException, BranchProblemException { + findRepInformation(); + + inform.revision = revision; + if (inform.currentBranchNumber != -1) { + inform.branchEnds.put(inform.currentBranchNumber, revision); + } + makeCheckout(revision); - FileUtils.cleanDirectory(informPath.resolve(stageFolder).toFile()); + + updateRepInformation(); } - String getLog(int revision) throws JsonParseException, JsonMappingException, IOException, UnversionedException, BranchProblemException { + ArrayList getLog(int revision) throws JsonParseException, JsonMappingException, IOException, UnversionedException, BranchProblemException { findRepInformation(); + ArrayList result = new ArrayList<>(); + if (revision < -1 || revision >= inform.nCommits) { throw new BranchProblemException("revision number " + (revision + 1) + " is incorrect"); } @@ -293,21 +297,21 @@ String getLog(int revision) throws JsonParseException, JsonMappingException, IOE } if(revision == -1) { - return "Empty log"; + result.add("Empty log"); + return result; } - StringBuilder sb = new StringBuilder(); while (revision >= 0) { - sb.append( - "branch " + inform.getCurrentBranchName() - +"\nrevision: " + (revision + 1) + "\n" - + inform.commitMessages.get(revision) + "\n" - + inform.timestamps.get(revision) + "\n\n" + result.add( + "\nrevision: " + (revision + 1) + "\n" + + inform.commitMessages.get(revision) ); + result.add(inform.timestamps.get(revision) + "\n"); + revision = inform.prevCommit.get(revision); } - return sb.toString(); + return result; } List getDeletedFiles() throws JsonParseException, JsonMappingException, IOException, UnversionedException { @@ -437,7 +441,7 @@ void makeBranch(String branchName) throws JsonParseException, JsonMappingExcepti throw new BranchProblemException("Branch already exists: " + branchName); } - Integer newBranchNumber = ++inform.lastBranchNumber; + Integer newBranchNumber = inform.nBranches++; inform.branchNumbers.put(branchName, newBranchNumber); inform.branchEnds.put(newBranchNumber, inform.revision); addAtIdx(inform.numberOfStartedBranchesAtRevision, inform.revision, 1); @@ -445,41 +449,23 @@ void makeBranch(String branchName) throws JsonParseException, JsonMappingExcepti } void makeDeleteBranch(String branchName) throws JsonParseException, JsonMappingException, IOException, UnversionedException, BranchProblemException { - makeCheckout(branchName); + //makeCheckout(branchName); + findRepInformation(); Integer branchNumber = inform.branchNumbers.get(branchName); + if (branchNumber == null) { throw new BranchProblemException("No such branch: " + branchName); } - - Integer revision = inform.branchEnds.get(branchNumber); - if (inform.numberOfStartedBranchesAtRevision.get(revision) > 0) { - throw new BranchProblemException("There is no free end of branch " + branchName); + + if (branchNumber.equals(inform.currentBranchNumber)) { + throw new BranchProblemException("You can't delete this branch while staying on it."); } inform.branchEnds.remove(branchNumber); inform.branchNumbers.remove(branchName); - while (revision >= 0 && inform.numberOfStartedBranchesAtRevision.get(revision) == 0) { - for (Integer fileNumber : inform.commitedFiles.get(revision)) { - Files.deleteIfExists( - getStoragePath( - Paths.get(RepInformation.getKeyByValue(fileNumber, inform.fileNumber)), revision) - ); - Files.deleteIfExists( - informPath.resolve( - RepInformation.getKeyByValue(fileNumber, inform.fileNumber))); - } - inform.commitedFiles.get(revision).clear(); - revision = inform.prevCommit.get(revision); - } - - if (revision >= 0) { - addAtIdx(inform.numberOfStartedBranchesAtRevision, revision, -1); - } - - inform.currentBranchNumber = -1; updateRepInformation(); } @@ -541,4 +527,34 @@ String getCurrentBranchName() throws JsonParseException, JsonMappingException, I findRepInformation(); return inform.getCurrentBranchName(); } + + public ArrayList getStatus() throws JsonParseException, JsonMappingException, IOException, UnversionedException { + ArrayList result = new ArrayList<>(); + + findRepInformation(); + result.add("Status:"); + if (inform.currentBranchNumber != -1) { + result.add("branch " + inform.getCurrentBranchName()); + } else { + result.add("detached head at " + inform.detachedHeadRevision); + } + + result.add("Staged files:\n________________"); + for (String fname : getStagedFiles()) { + result.add(fname); + } + result.add("Deleted files:\n________________"); + for (String fname : getDeletedFiles()) { + result.add(fname); + } + result.add("Changed files:\n________________"); + for (String fname : getChangedFiles()) { + result.add(fname); + } + result.add("Untracked files:\n________________"); + for (String fname : getUntrackedFiles()) { + result.add(fname); + } + return null; + } } diff --git a/hw_git/src/main/java/hw_git/RepInformation.java b/hw_git/src/main/java/hw_git/RepInformation.java index b30d6b2..1842676 100644 --- a/hw_git/src/main/java/hw_git/RepInformation.java +++ b/hw_git/src/main/java/hw_git/RepInformation.java @@ -11,9 +11,11 @@ public class RepInformation { int revision = -1; int currentBranchNumber = 0; + int detachedHeadRevision; + int nCommits = 0; int nFiles = 0; - int lastBranchNumber = 0; + int nBranches = 1; ArrayList commitMessages = new ArrayList<>(); @@ -154,12 +156,12 @@ public void setnFiles(int nFiles) { this.nFiles = nFiles; } - public int getLastBranchNumber() { - return lastBranchNumber; + public int getnBranches() { + return nBranches; } - public void setLastBranchNumber(int lastBranchNumber) { - this.lastBranchNumber = lastBranchNumber; + public void setnBranches(int lastBranchNumber) { + this.nBranches = lastBranchNumber; } public ArrayList getNumberOfStartedBranchesAtRevision() { @@ -169,4 +171,13 @@ public ArrayList getNumberOfStartedBranchesAtRevision() { public void setNumberOfStartedBranchesAtRevision(ArrayList numberOfStartedBrancesAtRevision) { this.numberOfStartedBranchesAtRevision = numberOfStartedBrancesAtRevision; } + + public int getDetachedHeadRevision() { + return detachedHeadRevision; + } + + public void setDetachedHeadRevision(int detachedHeadRevision) { + this.detachedHeadRevision = detachedHeadRevision; + } + } diff --git a/hw_git/src/test/java/hw_git/AppTest.java b/hw_git/src/test/java/hw_git/AppTest.java index 4e4bb00..d8da458 100644 --- a/hw_git/src/test/java/hw_git/AppTest.java +++ b/hw_git/src/test/java/hw_git/AppTest.java @@ -65,7 +65,6 @@ public void testInformationLoad() throws JsonGenerationException, JsonMappingExc public void testUnversioned() throws IOException, UnversionedException { GitCore core = new GitCore(); core.findRepInformation(); - //core.makeCheckout(0); } @Test @@ -109,26 +108,24 @@ 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[] {"add", "testdir/file.txt"}); + GitCli.main(new String[] {"add", "testdir/file.txt", "testdir/dir1/file_d1.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"); + out.print("commit 2 content"); } GitCli.main(new String[] {"add", "testdir/file.txt"}); - GitCli.main(new String[] {"commit", "message 3"}); + GitCli.main(new String[] {"commit", "message 2"}); - GitCli.main(new String[] {"checkout", "2"}); + GitCli.main(new String[] {"checkout", "1"}); try (Scanner in = new Scanner(new File("testdir/file.txt"))) { assertEquals(in.nextLine(), "commit 1 content"); } - GitCli.main(new String[] {"checkout", "3"}); + GitCli.main(new String[] {"checkout", "2"}); try (Scanner in = new Scanner(new File("testdir/file.txt"))) { - assertEquals(in.nextLine(), "commit 3 content"); + assertEquals(in.nextLine(), "commit 2 content"); } } @@ -251,20 +248,15 @@ public void testFilesInBranches() throws JsonGenerationException, JsonMappingExc } } - @Test(expected = BranchProblemException.class) public void testIncorrectBranchRm() throws JsonParseException, IOException, UnversionedException, BranchProblemException { GitCli.main(new String[] {"init"}); - GitCli.main(new String[] {"add", "testdir/file.txt"}); - GitCli.main(new String[] {"commit", "message 1"}); - - GitCli.main(new String[] {"branch", "b1"}); - GitCli.main(new String[] {"checkout", "b1"}); - - GitCli.main(new String[] {"add", "testdir/dir1/file_d1.txt"}); - GitCli.main(new String[] {"commit", "message 2"}); - GitCore core = new GitCore(); - core.makeDeleteBranch("master"); + try { + core.makeDeleteBranch("master"); + assert false; + } catch (BranchProblemException bpe) { + assertEquals("You can't delete this branch while staying on it.", bpe.message); + } } @Test @@ -279,14 +271,14 @@ public void testBranchDeleteAndRestore() throws JsonParseException, IOException, GitCli.main(new String[] {"add", "testdir/dir1/file_d1.txt"}); GitCli.main(new String[] {"commit", "message 2"}); + GitCli.main(new String[] {"checkout", "master"}); GitCli.main(new String[] {"branch", "-d", "b1"}); - + GitCore core = new GitCore(); - assertNull(core.getCurrentBranchName()); - - assertFalse(Files.exists(Paths.get("testdir/dir1/file_d1.txt"))); - assertTrue(Files.exists(Paths.get("testdir/file.txt"))); + try { + core.makeCheckout(0); + } catch (BranchProblemException e) {} core.makeBranch("b1"); core.makeCheckout("b1"); assertFalse(Files.exists(Paths.get("testdir/dir1/file_d1.txt"))); @@ -355,14 +347,14 @@ public Path apply(Path t, Path u) { } @Test - public void testLog() throws JsonParseException, IOException, UnversionedException, BranchProblemException { + public void testLogBasic() throws JsonParseException, IOException, UnversionedException, BranchProblemException { GitCli.main(new String[] {"init"}); GitCli.main(new String[] {"add", "testdir/file.txt"}); GitCore core = new GitCore(); - assertEquals("Empty log", core.getLog(-1)); + assertEquals("Empty log", core.getLog(-1).get(0)); GitCli.main(new String[] {"commit", "message 1"}); - assertNotEquals("Empty log", core.getLog(-1)); + assertEquals("\nrevision: 1\nmessage 1", core.getLog(-1).get(0)); assertEquals(core.getLog(-1), core.getLog(0)); } @@ -395,7 +387,7 @@ public void testDetachedState() throws JsonParseException, IOException, Unversio core.makeCheckout(0); assertTrue(false); } catch (BranchProblemException bpe) { - assertEquals("Now you're in detached state at revision 1", bpe.message); + assertEquals("HEAD detached on revison 1", bpe.message); } try { From dbf8f00236d02f82c1f1ced561a73357338bdc5d Mon Sep 17 00:00:00 2001 From: Anton Date: Mon, 5 Nov 2018 21:12:39 +0300 Subject: [PATCH 13/16] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D1=8B=20=D1=82=D0=B5=D1=81=D1=82=D1=8B=20=D1=81=20?= =?UTF-8?q?=D0=BF=D1=80=D0=BE=D0=B2=D0=B5=D1=80=D0=BA=D0=B0=D0=BC=D0=B8=20?= =?UTF-8?q?log=20=D0=B8=20status.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- hw_git/src/main/java/hw_git/GitCli.java | 59 ++- hw_git/src/main/java/hw_git/GitCore.java | 57 +-- hw_git/src/test/java/hw_git/AppTest.java | 237 ++++++------ hw_git/src/test/java/hw_git/ComplexTests.java | 358 ++++++++++++++++++ 4 files changed, 539 insertions(+), 172 deletions(-) create mode 100644 hw_git/src/test/java/hw_git/ComplexTests.java diff --git a/hw_git/src/main/java/hw_git/GitCli.java b/hw_git/src/main/java/hw_git/GitCli.java index 075d7ca..67f8b4e 100644 --- a/hw_git/src/main/java/hw_git/GitCli.java +++ b/hw_git/src/main/java/hw_git/GitCli.java @@ -5,8 +5,10 @@ import java.io.IOException; import java.nio.file.Path; import java.nio.file.Paths; +import java.util.ArrayList; import java.util.Arrays; import java.util.Scanner; +import java.util.stream.Collectors; import com.fasterxml.jackson.core.JsonGenerationException; import com.fasterxml.jackson.databind.JsonMappingException; @@ -54,7 +56,19 @@ public static Path conflictFileChooser(Path p1, Path p2) { } } - public static void main(String[] args) throws JsonGenerationException, JsonMappingException{ + public static void main(String[] args) throws JsonGenerationException, JsonMappingException { + System.out.println( + processArgs(args) + .stream() + .collect( + Collectors.joining("\n") + ) + ); + } + + public static ArrayList processArgs(String[] args) throws JsonGenerationException, JsonMappingException{ + + ArrayList res = new ArrayList<>(); GitCore core = new GitCore(); int revision; @@ -63,73 +77,78 @@ public static void main(String[] args) throws JsonGenerationException, JsonMappi switch (args[0]) { case "init": core.makeInit(); + res.add("Repository initiated."); break; case "add": - System.out.println("Addition..."); + res.add("Addition..."); core.makeAdd(Arrays.copyOfRange(args, 1, args.length)); break; case "commit": - System.out.println("Commiting..."); + res.add("Commiting..."); core.makeCommit(args[1]); - System.out.println("Commit made at revision " + (core.getCurrentRevision() + 1)); + res.add("Commit made at revision " + (core.getCurrentRevision() + 1)); break; case "checkout": if (args[1].equals("--")) { - System.out.println("Checking out files..."); + res.add("Checking out files..."); core.makeCheckout(Arrays.copyOfRange(args, 2, args.length)); } else { try { revision = Integer.parseInt(args[1]); - System.out.println("Check out to revision " + revision); + res.add("Checkout to revision " + revision); core.makeCheckout(revision - 1); + res.add("HEAD detached on revison " + revision); } catch (NumberFormatException e) { - System.out.println("Checking out branch..."); + res.add("Checking out branch..."); core.makeCheckout(args[1]); } } break; case "reset": revision = Integer.parseInt(args[1]); - System.out.println("Performing reset to revision " + revision); + res.add("Performing reset to revision " + revision); core.makeReset(revision - 1); break; case "log": revision = args.length == 2 ? Integer.parseInt(args[1]) : 0; - System.out.println("Log: " + core.getLog(revision - 1)); + res.add("Log:"); + res.addAll(core.getLog(revision - 1)); break; case "rm": - System.out.println("Removing..."); + res.add("Removing..."); core.makeRM(Arrays.copyOfRange(args, 1, args.length)); break; case "status": - System.out.println(core.getStatus()); + res.addAll(core.getStatus()); break; case "branch": if (args[1].equals("-d")) { - System.out.println("Deleting branch " + args[2]); + res.add("Deleting branch " + args[2]); core.makeDeleteBranch(args[2]); } else { - System.out.println("Making branch " + args[1]); + res.add("Making branch " + args[1]); core.makeBranch(args[1]); } break; case "merge": - System.out.println("Merging branch " + args[1] + " to " + core.getCurrentBranchName()); + res.add("Merging branch " + args[1] + " to " + core.getCurrentBranchName()); core.makeMerge(args[1], GitCli::conflictFileChooser); break; default: - System.out.println("Unknown argument: " + args[0]); + res.add("Unknown argument: " + args[0]); } } catch (UnversionedException e) { - System.out.println("This directory is not versioned"); + res.add("This directory is not versioned"); } catch (BranchProblemException e) { - System.out.println(e.message); + res.add(e.message); } catch (FileNotFoundException e) { - System.out.println(e.getMessage()); + res.add(e.getMessage()); } catch (IOException e) { - System.out.println("IOException: " + e.getMessage()); + res.add("IOException: " + e.getMessage()); } catch (ArrayIndexOutOfBoundsException e) { - System.out.println("Lack of arguments"); + res.add("Lack of arguments"); } + + return res; } } diff --git a/hw_git/src/main/java/hw_git/GitCore.java b/hw_git/src/main/java/hw_git/GitCore.java index dd041d8..a520360 100644 --- a/hw_git/src/main/java/hw_git/GitCore.java +++ b/hw_git/src/main/java/hw_git/GitCore.java @@ -65,7 +65,6 @@ void makeInit() throws JsonGenerationException, JsonMappingException, IOExceptio informPath = Paths.get(""); inform = new RepInformation(); updateRepInformation(); - System.out.println("Repository initiated."); } } @@ -82,9 +81,13 @@ private Path getStoragePath(Path keyPath, int revision) { .resolve(keyPath.toString() + "r" + revision); } + private Path cutRoot(Path p) { + return p.subpath(1, p.getNameCount()); + } + private void addFileDuringCommit(Path filepath) throws IOException { int revision = inform.revision; - Path keyPath = filepath.subpath(1, filepath.getNameCount()); + Path keyPath = cutRoot(filepath); Path storage = getStoragePath(keyPath, revision); storage.getParent().toFile().mkdirs(); Files.copy(filepath, storage); @@ -224,8 +227,6 @@ void makeCheckout(int revision) throws IOException, UnversionedException, Branch inform.currentBranchNumber = -1; updateRepInformation(); - - throw new BranchProblemException("HEAD detached on revison " + (revision + 1)); } void makeCheckout(String branchName) throws JsonParseException, JsonMappingException, IOException, UnversionedException, BranchProblemException { @@ -246,8 +247,9 @@ void makeCheckout(String branchName) throws JsonParseException, JsonMappingExcep } private int getLastRevisionOfFile(String keyName) { - int revision = inform.currentBranchLastRevision(); - while (revision >= 0 && !inform.commitedFiles.get(revision).contains(inform.fileNumber.get(keyName))) { + int revision = inform.revision; + while (revision >= 0 && !inform.commitedFiles.get(revision) + .contains(inform.fileNumber.get(keyName))) { revision = inform.prevCommit.get(revision); } return revision; @@ -272,14 +274,23 @@ void makeCheckout(String[] files) throws JsonParseException, JsonMappingExceptio void makeReset(int revision) throws JsonParseException, JsonMappingException, IOException, UnversionedException, BranchProblemException { findRepInformation(); - + /* inform.revision = revision; if (inform.currentBranchNumber != -1) { inform.branchEnds.put(inform.currentBranchNumber, revision); } - + + */ + int currBranchT = inform.currentBranchNumber; + int currDetachedPosT = inform.detachedHeadRevision; makeCheckout(revision); + if (currBranchT != -1) { + inform.currentBranchNumber = currBranchT; + inform.branchEnds.put(currBranchT, revision); + } + inform.detachedHeadRevision = currDetachedPosT; + updateRepInformation(); } @@ -336,7 +347,8 @@ List getChangedFiles() throws JsonParseException, JsonMappingException, if (Files.exists(informPath.resolve(keyName)) && !FileUtils.contentEquals( informPath.resolve(keyName).toFile(), - getStoragePath(Paths.get(keyName), getLastRevisionOfFile(keyName) + getStoragePath(Paths.get(keyName), + getLastRevisionOfFile(keyName) ).toFile() )) { result.add(Paths.get("").relativize(Paths.get(keyName)).toString()); @@ -357,7 +369,7 @@ public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) th @Override public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { - result.add(file.toString()); + result.add(cutRoot(file).toString()); return FileVisitResult.CONTINUE; } @@ -449,7 +461,6 @@ void makeBranch(String branchName) throws JsonParseException, JsonMappingExcepti } void makeDeleteBranch(String branchName) throws JsonParseException, JsonMappingException, IOException, UnversionedException, BranchProblemException { - //makeCheckout(branchName); findRepInformation(); Integer branchNumber = inform.branchNumbers.get(branchName); @@ -536,25 +547,21 @@ public ArrayList getStatus() throws JsonParseException, JsonMappingExcep if (inform.currentBranchNumber != -1) { result.add("branch " + inform.getCurrentBranchName()); } else { - result.add("detached head at " + inform.detachedHeadRevision); + result.add("detached head at revision " + (inform.detachedHeadRevision + 1)); } result.add("Staged files:\n________________"); - for (String fname : getStagedFiles()) { - result.add(fname); - } + result.addAll(getStagedFiles()); + result.add("Deleted files:\n________________"); - for (String fname : getDeletedFiles()) { - result.add(fname); - } + result.addAll(getDeletedFiles()); + result.add("Changed files:\n________________"); - for (String fname : getChangedFiles()) { - result.add(fname); - } + result.addAll(getChangedFiles()); + result.add("Untracked files:\n________________"); - for (String fname : getUntrackedFiles()) { - result.add(fname); - } - return null; + result.addAll(getUntrackedFiles()); + + return result; } } diff --git a/hw_git/src/test/java/hw_git/AppTest.java b/hw_git/src/test/java/hw_git/AppTest.java index d8da458..6282c6d 100644 --- a/hw_git/src/test/java/hw_git/AppTest.java +++ b/hw_git/src/test/java/hw_git/AppTest.java @@ -7,6 +7,7 @@ import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; +import java.util.ArrayList; import java.util.Arrays; import java.util.Scanner; import java.util.function.BiFunction; @@ -21,20 +22,24 @@ import org.junit.After; import org.junit.Assert; import org.junit.Before; -import org.junit.Ignore; import org.junit.Test; public class AppTest extends Assert { - final String storageFilename = ".myGitDataFile"; - final String storageFolder = ".myGitDataStorage"; - final String stageFolder = ".stageData"; + public static final String storageFilename = ".myGitDataFile"; + public static final String storageFolder = ".myGitDataStorage"; + public static final String stageFolder = ".stageData"; + + //files + final String file1 = "testdir/file.txt"; + final String file2 = "testdir/dir1/file_d1.txt"; + @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")); + Files.createFile(Paths.get(file2)); + Files.createFile(Paths.get(file1)); Files.createFile(Paths.get("one.txt")); } @@ -58,7 +63,6 @@ public void testInformationLoad() throws JsonGenerationException, JsonMappingExc GitCore core = new GitCore(); core.findRepInformation(); assertEquals(core.getCurrentRevision(), -1); - //Files.delete(Paths.get(".myGitData")); } @Test(expected = UnversionedException.class) @@ -70,34 +74,34 @@ public void testUnversioned() throws IOException, UnversionedException { @Test public void testCheckout() throws JsonGenerationException, JsonMappingException, IOException { GitCli.main(new String[] {"init"}); - GitCli.main(new String[] {"add", "testdir/file.txt"}); + GitCli.main(new String[] {"add", file1}); GitCli.main(new String[] {"commit", "message 1"}); - GitCli.main(new String[] {"add", "testdir/dir1/file_d1.txt"}); + GitCli.main(new String[] {"add", file2}); GitCli.main(new String[] {"commit", "message 2"}); GitCli.main(new String[] {"checkout", "1"}); - assertTrue(Files.exists(Paths.get("testdir/file.txt"))); - assertFalse(Files.exists(Paths.get("testdir/dir1/file_d1.txt"))); + assertTrue(Files.exists(Paths.get(file1))); + assertFalse(Files.exists(Paths.get(file2))); GitCli.main(new String[] {"checkout", "2"}); - assertTrue(Files.exists(Paths.get("testdir/file.txt"))); - assertTrue(Files.exists(Paths.get("testdir/dir1/file_d1.txt"))); + assertTrue(Files.exists(Paths.get(file1))); + assertTrue(Files.exists(Paths.get(file2))); } @Test public void testCheckoutFiles() throws JsonGenerationException, JsonMappingException, IOException { GitCli.main(new String[] {"init"}); - try (PrintWriter out = new PrintWriter(new File("testdir/file.txt"))) { + try (PrintWriter out = new PrintWriter(new File(file1))) { out.println("text 1"); } - GitCli.main(new String[] {"add", "testdir/file.txt"}); + GitCli.main(new String[] {"add", file1}); GitCli.main(new String[] {"commit", "message 1"}); - try (PrintWriter out = new PrintWriter(new File("testdir/file.txt"))) { + try (PrintWriter out = new PrintWriter(new File(file1))) { out.println("text 2"); } - GitCli.main(new String[] {"checkout", "--", "testdir/file.txt"}); - try (Scanner in = new Scanner(new File("testdir/file.txt"))) { + GitCli.main(new String[] {"checkout", "--", file1}); + try (Scanner in = new Scanner(new File(file1))) { assertTrue(in.nextLine().equals("text 1")); } } @@ -105,95 +109,76 @@ public void testCheckoutFiles() throws JsonGenerationException, JsonMappingExcep @Test public void testFileChangeBetweenCommits() throws JsonGenerationException, JsonMappingException, IOException { GitCli.main(new String[] {"init"}); - try (PrintWriter out = new PrintWriter(new File("testdir/file.txt"))) { + try (PrintWriter out = new PrintWriter(new File(file1))) { out.print("commit 1 content"); } - GitCli.main(new String[] {"add", "testdir/file.txt", "testdir/dir1/file_d1.txt"}); + GitCli.main(new String[] {"add", file1, file2}); GitCli.main(new String[] {"commit", "message 1"}); - try (PrintWriter out = new PrintWriter(new File("testdir/file.txt"))) { + try (PrintWriter out = new PrintWriter(new File(file1))) { out.print("commit 2 content"); } - GitCli.main(new String[] {"add", "testdir/file.txt"}); + GitCli.main(new String[] {"add", file1}); GitCli.main(new String[] {"commit", "message 2"}); GitCli.main(new String[] {"checkout", "1"}); - try (Scanner in = new Scanner(new File("testdir/file.txt"))) { + try (Scanner in = new Scanner(new File(file1))) { assertEquals(in.nextLine(), "commit 1 content"); } GitCli.main(new String[] {"checkout", "2"}); - try (Scanner in = new Scanner(new File("testdir/file.txt"))) { + try (Scanner in = new Scanner(new File(file1))) { assertEquals(in.nextLine(), "commit 2 content"); } } - @Ignore - @Test - public void testReset() throws JsonGenerationException, JsonMappingException, IOException { - GitCli.main(new String[] {"init"}); - 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[] {"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(storageFilename))) { - s2 = in.nextLine(); - } - 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[] {"add", file1}); GitCli.main(new String[] {"commit", "message 1"}); - GitCli.main(new String[] {"add", "testdir/file.txt"}); + GitCli.main(new String[] {"add", file1}); GitCli.main(new String[] {"commit", "message 2"}); - Files.delete(Paths.get("testdir/file.txt")); - GitCli.main(new String[] {"rm", "testdir/file.txt"}); + Files.delete(Paths.get(file1)); + GitCli.main(new String[] {"rm", file1}); GitCli.main(new String[] {"checkout", "2"}); - assertFalse(Files.exists(Paths.get("testdir/file.txt"))); + assertFalse(Files.exists(Paths.get(file1))); GitCli.main(new String[] {"checkout", "1"}); - assertTrue(Files.exists(Paths.get("testdir/file.txt"))); + assertTrue(Files.exists(Paths.get(file1))); } @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[] {"add", file1}); 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.getUntrackedFiles(), Arrays.asList(file2)); assertEquals(core.getDeletedFiles(), Arrays.asList()); - try (PrintWriter out = new PrintWriter(new File("testdir/file.txt"))) { + try (PrintWriter out = new PrintWriter(new File(file1))) { out.print("commit 3 content"); } - assertEquals(core.getChangedFiles(), Arrays.asList("testdir/file.txt")); + assertEquals(core.getChangedFiles(), Arrays.asList(file1)); - Files.delete(Paths.get("testdir/file.txt")); + Files.delete(Paths.get(file1)); + + assertEquals(core.getDeletedFiles(), Arrays.asList(file1)); - assertEquals(core.getDeletedFiles(), Arrays.asList("testdir/file.txt")); } @Test public void testAddBranch() throws UnversionedException, JsonParseException, IOException { GitCore core = new GitCore(); GitCli.main(new String[] {"init"}); - GitCli.main(new String[] {"add", "testdir/file.txt"}); + GitCli.main(new String[] {"add", file1}); GitCli.main(new String[] {"commit", "message 1"}); assertEquals("master", core.getCurrentBranchName()); @@ -210,91 +195,85 @@ public void testAddBranch() throws UnversionedException, JsonParseException, IOE @Test public void testFilesInBranches() throws JsonGenerationException, JsonMappingException, FileNotFoundException { GitCli.main(new String[] {"init"}); - GitCli.main(new String[] {"add", "testdir/file.txt"}); + GitCli.main(new String[] {"add", file1}); GitCli.main(new String[] {"commit", "message 1"}); GitCli.main(new String[] {"branch", "b1"}); GitCli.main(new String[] {"checkout", "b1"}); - try(PrintWriter out = new PrintWriter(new File("testdir/dir1/file_d1.txt"))) { + try(PrintWriter out = new PrintWriter(new File(file2))) { out.println("b1 content"); } - GitCli.main(new String[] {"add", "testdir/dir1/file_d1.txt"}); + GitCli.main(new String[] {"add", file2}); GitCli.main(new String[] {"commit", "message 2"}); - assertTrue(Files.exists(Paths.get("testdir/file.txt"))); - assertTrue(Files.exists(Paths.get("testdir/dir1/file_d1.txt"))); + assertTrue(Files.exists(Paths.get(file1))); + assertTrue(Files.exists(Paths.get(file2))); GitCli.main(new String[] {"checkout", "master"}); - assertFalse(Files.exists(Paths.get("testdir/dir1/file_d1.txt"))); + assertFalse(Files.exists(Paths.get(file2))); GitCli.main(new String[] {"branch", "b2"}); GitCli.main(new String[] {"checkout", "b2"}); - try(PrintWriter out = new PrintWriter(new File("testdir/dir1/file_d1.txt"))) { + try(PrintWriter out = new PrintWriter(new File(file2))) { out.println("b2 content"); } - GitCli.main(new String[] {"add", "testdir/dir1/file_d1.txt"}); + GitCli.main(new String[] {"add", file2}); GitCli.main(new String[] {"commit", "message 3"}); GitCli.main(new String[] {"checkout", "b1"}); - try (Scanner in = new Scanner(new File("testdir/dir1/file_d1.txt"))) { + try (Scanner in = new Scanner(new File(file2))) { assertEquals("b1 content", in.nextLine()); } GitCli.main(new String[] {"checkout", "b2"}); - try (Scanner in = new Scanner(new File("testdir/dir1/file_d1.txt"))) { + try (Scanner in = new Scanner(new File(file2))) { assertEquals("b2 content", in.nextLine()); } } public void testIncorrectBranchRm() throws JsonParseException, IOException, UnversionedException, BranchProblemException { GitCli.main(new String[] {"init"}); - GitCore core = new GitCore(); - try { - core.makeDeleteBranch("master"); - assert false; - } catch (BranchProblemException bpe) { - assertEquals("You can't delete this branch while staying on it.", bpe.message); - } + assertEquals( + "You can't delete this branch while staying on it.", + GitCli.processArgs(new String[] {"branch", "-d", "master"}) + .get(0)); } @Test public void testBranchDeleteAndRestore() throws JsonParseException, IOException, UnversionedException, BranchProblemException { GitCli.main(new String[] {"init"}); - GitCli.main(new String[] {"add", "testdir/file.txt"}); + GitCli.main(new String[] {"add", file1}); GitCli.main(new String[] {"commit", "message 1"}); GitCli.main(new String[] {"branch", "b1"}); GitCli.main(new String[] {"checkout", "b1"}); - GitCli.main(new String[] {"add", "testdir/dir1/file_d1.txt"}); + GitCli.main(new String[] {"add", file2}); GitCli.main(new String[] {"commit", "message 2"}); GitCli.main(new String[] {"checkout", "master"}); GitCli.main(new String[] {"branch", "-d", "b1"}); - GitCore core = new GitCore(); - - try { - core.makeCheckout(0); - } catch (BranchProblemException e) {} - core.makeBranch("b1"); - core.makeCheckout("b1"); - assertFalse(Files.exists(Paths.get("testdir/dir1/file_d1.txt"))); - assertTrue(Files.exists(Paths.get("testdir/file.txt"))); + GitCli.main(new String[] {"checkout", "0"}); + GitCli.main(new String[] {"branch", "b1"}); + GitCli.main(new String[] {"checkout", "b1"}); + + assertFalse(Files.exists(Paths.get(file2))); + assertTrue(Files.exists(Paths.get(file1))); } @Test public void testMergeNoConflict() throws JsonParseException, IOException, UnversionedException, BranchProblemException { GitCli.main(new String[] {"init"}); - GitCli.main(new String[] {"add", "testdir/file.txt"}); + GitCli.main(new String[] {"add", file1}); GitCli.main(new String[] {"commit", "message 1"}); GitCli.main(new String[] {"branch", "b1"}); GitCli.main(new String[] {"checkout", "b1"}); - GitCli.main(new String[] {"add", "testdir/dir1/file_d1.txt"}); + GitCli.main(new String[] {"add", file2}); GitCli.main(new String[] {"commit", "message 2"}); GitCli.main(new String[] {"checkout", "master"}); @@ -309,14 +288,14 @@ public Path apply(Path t, Path u) { }); assertEquals("master", core.getCurrentBranchName()); - assertTrue(Files.exists(Paths.get("testdir/dir1/file_d1.txt"))); - assertTrue(Files.exists(Paths.get("testdir/file.txt"))); + assertTrue(Files.exists(Paths.get(file2))); + assertTrue(Files.exists(Paths.get(file1))); } @Test public void testMergeConflict() throws JsonParseException, IOException, UnversionedException, BranchProblemException { GitCli.main(new String[] {"init"}); - GitCli.main(new String[] {"add", "testdir/file.txt"}); + GitCli.main(new String[] {"add", file1}); GitCli.main(new String[] {"commit", "message 1"}); GitCli.main(new String[] {"commit", "message 2"}); @@ -327,7 +306,7 @@ public void testMergeConflict() throws JsonParseException, IOException, Unversio GitCli.main(new String[] {"branch", "b1"}); GitCli.main(new String[] {"checkout", "b1"}); - GitCli.main(new String[] {"add", "testdir/file.txt"}); + GitCli.main(new String[] {"add", file1}); GitCli.main(new String[] {"commit", "message b1"}); GitCli.main(new String[] {"checkout", "master"}); @@ -349,65 +328,69 @@ public Path apply(Path t, Path u) { @Test public void testLogBasic() throws JsonParseException, IOException, UnversionedException, BranchProblemException { GitCli.main(new String[] {"init"}); - GitCli.main(new String[] {"add", "testdir/file.txt"}); - GitCore core = new GitCore(); - assertEquals("Empty log", core.getLog(-1).get(0)); + GitCli.main(new String[] {"add", file1}); + + assertEquals("Empty log", + GitCli.processArgs(new String[] {"log"}).get(1)); GitCli.main(new String[] {"commit", "message 1"}); - assertEquals("\nrevision: 1\nmessage 1", core.getLog(-1).get(0)); - assertEquals(core.getLog(-1), core.getLog(0)); + assertEquals("\nrevision: 1\nmessage 1", + GitCli.processArgs(new String[] {"log"}).get(1)); + assertEquals( + GitCli.processArgs(new String[] {"log"}), + GitCli.processArgs(new String[] {"log", "1"})); } - @Test(expected = BranchProblemException.class) + public void testIncorrectBigCheckoutRevision() throws JsonParseException, IOException, UnversionedException, BranchProblemException { GitCli.main(new String[] {"init"}); - GitCli.main(new String[] {"add", "testdir/file.txt"}); + GitCli.main(new String[] {"add", file1}); GitCli.main(new String[] {"commit", "message 1"}); - GitCore core = new GitCore(); - try { - core.makeCheckout(2); - } catch (BranchProblemException bpe) { - assertEquals("revision number" + 3 + " is incorrect", bpe.message); - throw bpe; - } + assertEquals( + "revision number" + 2 + " is incorrect", + GitCli.processArgs(new String[] {"checkout", "2"}).get(0)); + + assertEquals( + "revision number" + 0 + " is incorrect", + GitCli.processArgs(new String[] {"checkout", "0"}).get(0)); + + assertEquals( + "revision number" + 2 + " is incorrect", + GitCli.processArgs(new String[] {"reset", "2"}).get(0)); + + assertEquals( + "revision number" + 0 + " is incorrect", + GitCli.processArgs(new String[] {"reset", "0"}).get(0)); } @Test public void testDetachedState() throws JsonParseException, IOException, UnversionedException, BranchProblemException { GitCli.main(new String[] {"init"}); - GitCli.main(new String[] {"add", "testdir/file.txt"}); + GitCli.main(new String[] {"add", file1}); GitCli.main(new String[] {"commit", "message 1"}); - GitCli.main(new String[] {"add", "testdir/file.txt"}); + GitCli.main(new String[] {"add", file1}); GitCli.main(new String[] {"commit", "message 2"}); - GitCore core = new GitCore(); - try { - core.makeCheckout(0); - assertTrue(false); - } catch (BranchProblemException bpe) { - assertEquals("HEAD detached on revison 1", bpe.message); - } + assertEquals("HEAD detached on revison 1", + GitCli.processArgs(new String[] {"checkout", "1"}).get(1)); - try { - core.makeCommit("abc"); - assertTrue(false); - } catch (BranchProblemException bpe) { - assertEquals("Staying not at end of some branch", bpe.message); - } + assertEquals("Staying not at end of some branch", + GitCli.processArgs(new String[] {"commit", "abc"}).get(1)); } @Test public void testEmptyCommitNotFails() throws JsonParseException, IOException, UnversionedException, BranchProblemException { GitCli.main(new String[] {"init"}); - GitCli.main(new String[] {"add", "testdir/file.txt"}); + GitCli.main(new String[] {"add", file1}); GitCli.main(new String[] {"commit", "message 1"}); GitCli.main(new String[] {"commit", "message 2"}); - - GitCore core = new GitCore(); - core.getLog(-1); + + ArrayList logRes = GitCli.processArgs(new String[] {"log"}); + assertEquals("\nrevision: 2\nmessage 2", logRes.get(1)); + assertEquals("\nrevision: 1\nmessage 1", logRes.get(3)); } @Test @@ -416,8 +399,8 @@ public void testCommitFileInRoot() throws JsonParseException, IOException, Unver GitCli.main(new String[] {"add", "one.txt"}); GitCli.main(new String[] {"commit", "message 2"}); - GitCore core = new GitCore(); - core.getLog(-1); + ArrayList logRes = GitCli.processArgs(new String[] {"log"}); + assertEquals("\nrevision: 1\nmessage 2", logRes.get(1)); } } diff --git a/hw_git/src/test/java/hw_git/ComplexTests.java b/hw_git/src/test/java/hw_git/ComplexTests.java new file mode 100644 index 0000000..51ba08f --- /dev/null +++ b/hw_git/src/test/java/hw_git/ComplexTests.java @@ -0,0 +1,358 @@ +package hw_git; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Test; + +import java.io.File; +import java.io.IOException; +import java.io.PrintWriter; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Scanner; + +import org.apache.commons.io.FileUtils; + +public class ComplexTests extends Assert { + + final String testdir = "testdir/"; + static ArrayList removeTimestampsFromLog(ArrayList orig) { + ArrayList res = new ArrayList<>(); + res.add(orig.get(0)); + for (int i = 1; i < orig.size(); i += 2) { + res.add(orig.get(i)); + } + return res; + } + + @After + public void deleteTestFiles() throws IOException { + FileUtils.deleteDirectory(new File(testdir)); + FileUtils.deleteDirectory(new File(AppTest.storageFolder)); + FileUtils.deleteDirectory(new File(AppTest.stageFolder)); + FileUtils.forceDelete(new File(AppTest.storageFilename)); + } + + @Test + public void testCheckoutWithLogAndStatus() throws IOException { + FileUtils.touch(Paths.get(testdir).resolve("file1").toFile()); + + assertEquals("This directory is not versioned", + GitCli.processArgs(new String[] {"add", "testdir/file1"}).get(1)); + + assertEquals("This directory is not versioned", + GitCli.processArgs(new String[] {"status"}).get(0)); + assertEquals("This directory is not versioned", + GitCli.processArgs(new String[] {"log"}).get(1)); + + assertEquals("Repository initiated.", + GitCli.processArgs(new String[] {"init"}).get(0)); + + assertEquals( + Arrays.asList( + "Status:", + "branch master", + "Staged files:\n________________", + "Deleted files:\n________________", + "Changed files:\n________________", + "Untracked files:\n________________"), + GitCli.processArgs(new String[] {"status"}).subList(0, 6)); + + assertEquals("Empty log", + GitCli.processArgs(new String[] {"log"}).get(1)); + + GitCli.main(new String[] {"add", testdir + "file1"}); + + assertEquals("Empty log", + GitCli.processArgs(new String[] {"log"}).get(1)); + + + assertEquals( + Arrays.asList( + "Status:", + "branch master", + "Staged files:\n________________", + "testdir/file1", + "Deleted files:\n________________", + "Changed files:\n________________", + "Untracked files:\n________________"), + GitCli.processArgs(new String[] {"status"}).subList(0, 7)); + + GitCli.main(new String[] {"commit", "mes 1"}); + + assertEquals( + Arrays.asList( + "Log:", + "\nrevision: 1\nmes 1"), + GitCli.processArgs(new String[] {"log"}).subList(0, 2)); + + assertEquals( + Arrays.asList( + "Status:", + "branch master", + "Staged files:\n________________", + "Deleted files:\n________________", + "Changed files:\n________________", + "Untracked files:\n________________"), + GitCli.processArgs(new String[] {"status"}).subList(0, 6)); + + assertEquals(Arrays.asList( + "Commiting...", + "Commit made at revision 2"), + GitCli.processArgs(new String[] {"commit", "empty commit"})); + + assertEquals( + Arrays.asList( + "Log:", + "\nrevision: 2\nempty commit", + "\nrevision: 1\nmes 1"), + removeTimestampsFromLog(GitCli.processArgs(new String[] {"log"}))); + + assertEquals(Arrays.asList( + "Checkout to revision 1", + "HEAD detached on revison 1"), + GitCli.processArgs(new String[] {"checkout", "1"})); + + assertEquals( + Arrays.asList( + "Status:", + "detached head at revision 1", + "Staged files:\n________________", + "Deleted files:\n________________", + "Changed files:\n________________", + "Untracked files:\n________________"), + GitCli.processArgs(new String[] {"status"}).subList(0, 6)); + + assertEquals( + Arrays.asList( + "Log:", + "\nrevision: 1\nmes 1"), + removeTimestampsFromLog(GitCli.processArgs(new String[] {"log"}))); + + assertEquals(Arrays.asList( + "Checkout to revision 2", + "HEAD detached on revison 2"), + GitCli.processArgs(new String[] {"checkout", "2"})); + + assertEquals( + Arrays.asList( + "Status:", + "detached head at revision 2", + "Staged files:\n________________", + "Deleted files:\n________________", + "Changed files:\n________________", + "Untracked files:\n________________"), + GitCli.processArgs(new String[] {"status"}).subList(0, 6)); + + assertEquals( + Arrays.asList( + "Log:", + "\nrevision: 2\nempty commit", + "\nrevision: 1\nmes 1"), + removeTimestampsFromLog(GitCli.processArgs(new String[] {"log"}))); + + assertEquals(Arrays.asList( + "Checking out branch..."), + GitCli.processArgs(new String[] {"checkout", "master"})); + + assertEquals( + Arrays.asList( + "Log:", + "\nrevision: 2\nempty commit", + "\nrevision: 1\nmes 1"), + removeTimestampsFromLog(GitCli.processArgs(new String[] {"log"}))); + + GitCli.main(new String[] {"checkout", "1"}); + GitCli.main(new String[] {"branch", "b1"}); + GitCli.main(new String[] {"checkout", "b1"}); + + assertEquals( + Arrays.asList( + "Status:", + "branch b1", + "Staged files:\n________________", + "Deleted files:\n________________", + "Changed files:\n________________", + "Untracked files:\n________________"), + GitCli.processArgs(new String[] {"status"}).subList(0, 6)); + + assertEquals( + Arrays.asList( + "Log:", + "\nrevision: 1\nmes 1"), + removeTimestampsFromLog(GitCli.processArgs(new String[] {"log"}))); + + } + + @Test + public void testResetWithLogAndStatus() throws IOException { + FileUtils.touch(Paths.get(testdir).resolve("file1").toFile()); + try (PrintWriter out = new PrintWriter(new File("testdir/file1"))) { + out.println("initial content"); + } + + assertEquals("Repository initiated.", + GitCli.processArgs(new String[] {"init"}).get(0)); + + GitCli.main(new String[] {"add", "testdir/file1"}); + + GitCli.main(new String[] {"commit", "mes 1"}); + + try (PrintWriter out = new PrintWriter("testdir/file1")) { + out.println("revision 2 content"); + } + + GitCli.main(new String[] {"add", "testdir/file1"}); + + assertEquals(Arrays.asList( + "Commiting...", + "Commit made at revision 2"), + GitCli.processArgs(new String[] {"commit", "second commit"})); + + try (Scanner in = new Scanner(new File("testdir/file1"))) { + assertEquals("revision 2 content", in.nextLine()); + } + + assertEquals( + Arrays.asList( + "Performing reset to revision 1"), + removeTimestampsFromLog(GitCli.processArgs(new String[] {"reset", "1"}))); + + assertEquals( + Arrays.asList( + "Status:", + "branch master", + "Staged files:\n________________", + "Deleted files:\n________________", + "Changed files:\n________________", + "Untracked files:\n________________"), + GitCli.processArgs(new String[] {"status"}).subList(0, 6)); + + assertEquals( + Arrays.asList( + "Log:", + "\nrevision: 1\nmes 1"), + removeTimestampsFromLog(GitCli.processArgs(new String[] {"log"}))); + + try (Scanner in = new Scanner(new File("testdir/file1"))) { + assertEquals("initial content", in.nextLine()); + } + + try (PrintWriter out = new PrintWriter("testdir/file1")) { + out.println("reset state content"); + } + + assertEquals( + Arrays.asList( + "Status:", + "branch master", + "Staged files:\n________________", + "Deleted files:\n________________", + "Changed files:\n________________", + "testdir/file1", + "Untracked files:\n________________"), + GitCli.processArgs(new String[] {"status"}).subList(0, 7)); + + GitCli.main(new String[] {"add", "testdir/file1"}); + assertEquals(Arrays.asList( + "Commiting...", + "Commit made at revision 3"), + GitCli.processArgs(new String[] {"commit", "third commit"})); + + try (Scanner in = new Scanner(new File("testdir/file1"))) { + assertEquals("reset state content", in.nextLine()); + } + + assertEquals( + Arrays.asList( + "Log:", + "\nrevision: 3\nthird commit", + "\nrevision: 1\nmes 1"), + removeTimestampsFromLog(GitCli.processArgs(new String[] {"log"}))); + + GitCli.main(new String[] {"reset", "2"}); + + try (Scanner in = new Scanner(new File("testdir/file1"))) { + assertEquals("revision 2 content", in.nextLine()); + } + + assertEquals( + Arrays.asList( + "Status:", + "branch master", + "Staged files:\n________________", + "Deleted files:\n________________", + "Changed files:\n________________", + "Untracked files:\n________________"), + GitCli.processArgs(new String[] {"status"}).subList(0, 6)); + + GitCli.main(new String[] {"checkout", "1"}); + GitCli.main(new String[] {"reset", "3"}); + + assertEquals( + Arrays.asList( + "Log:", + "\nrevision: 3\nthird commit", + "\nrevision: 1\nmes 1"), + removeTimestampsFromLog(GitCli.processArgs(new String[] {"log"}))); + + assertEquals( + Arrays.asList( + "Status:", + "detached head at revision 1", + "Staged files:\n________________", + "Deleted files:\n________________", + "Changed files:\n________________", + "Untracked files:\n________________"), + GitCli.processArgs(new String[] {"status"}).subList(0, 6)); + + try (Scanner in = new Scanner(new File("testdir/file1"))) { + assertEquals("reset state content", in.nextLine()); + } + + GitCli.main(new String[] {"checkout", "master"}); + + try (Scanner in = new Scanner(new File("testdir/file1"))) { + assertEquals("revision 2 content", in.nextLine()); + } + } + + @Test + public void testBranchRM() throws IOException { + FileUtils.touch(Paths.get(testdir).resolve("file1").toFile()); + try (PrintWriter out = new PrintWriter(new File("testdir/file1"))) { + out.println("initial content"); + } + + assertEquals("Repository initiated.", + GitCli.processArgs(new String[] {"init"}).get(0)); + + GitCli.main(new String[] {"add", "testdir/file1"}); + + GitCli.main(new String[] {"commit", "mes 1"}); + + try (PrintWriter out = new PrintWriter("testdir/file1")) { + out.println("revision 2 content"); + } + + GitCli.main(new String[] {"add", "testdir/file1"}); + + GitCli.main(new String[] {"commit", "mes 2"}); + GitCli.main(new String[] {"checkout", "1"}); + + GitCli.main(new String[] {"branch", "b1"}); + GitCli.main(new String[] {"checkout", "b1"}); + + try (PrintWriter out = new PrintWriter("testdir/file1")) { + out.println("revision 3 content"); + } + GitCli.main(new String[] {"commit", "mes 3"}); + + assertEquals( + Arrays.asList( + "Deleting branch b1", + "You can't delete this branch while staying on it."), + GitCli.processArgs(new String[] {"branch", "-d", "b1"})); + } +} From 3184bd18b25553581683c55a1c352a966572f4a0 Mon Sep 17 00:00:00 2001 From: Anton Date: Wed, 7 Nov 2018 13:23:08 +0300 Subject: [PATCH 14/16] =?UTF-8?q?=D0=A1=D0=B4=D0=B5=D0=BB=D0=B0=D0=BD=20me?= =?UTF-8?q?rge,=20=D0=BF=D0=BE=D1=85=D0=BE=D0=B6=D0=B8=D0=B9=20=D0=BD?= =?UTF-8?q?=D0=B0=20=D0=BE=D1=80=D0=B8=D0=B3=D0=B8=D0=BD=D0=B0=D0=BB=D1=8C?= =?UTF-8?q?=D0=BD=D1=8B=D0=B9.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Добавлен базовый тест к нему. getChangedFiles и getDeletedFiles теперь только на файлы в текущем пути до корня смотрят. --- hw_git/src/main/java/hw_git/GitCli.java | 33 +---- hw_git/src/main/java/hw_git/GitCore.java | 129 ++++++++++++------ hw_git/src/test/java/hw_git/AppTest.java | 66 +-------- hw_git/src/test/java/hw_git/ComplexTests.java | 87 +++++++++++- 4 files changed, 178 insertions(+), 137 deletions(-) diff --git a/hw_git/src/main/java/hw_git/GitCli.java b/hw_git/src/main/java/hw_git/GitCli.java index 67f8b4e..73175ca 100644 --- a/hw_git/src/main/java/hw_git/GitCli.java +++ b/hw_git/src/main/java/hw_git/GitCli.java @@ -27,35 +27,6 @@ public static void printFile(Path p) { } } - public static Path conflictFileChooser(Path p1, Path p2) { - System.out.println("merge conflict between " + p1.toString() + " and " + p2.toString()); - printFile(p1); - printFile(p2); - int choice = 0; - while (!(choice == 1 || choice == 2 || choice == 3)) { - System.out.println("Enter \"1\", if you want to use first file in merging\n" - + "Enter \"2\" to use second\n" - + "Enter \"3\" to specify file manually"); - try (Scanner in = new Scanner(System.in)) { - choice = in.nextInt(); - } catch (Exception e) {} - } - - switch (choice) { - case 1: - return p1; - case 2: - return p2; - default: - String choosenPath = null; - System.out.println("Specify path to file:"); - try (Scanner in = new Scanner(System.in)) { - choosenPath = in.nextLine(); - } - return Paths.get(choosenPath); - } - } - public static void main(String[] args) throws JsonGenerationException, JsonMappingException { System.out.println( processArgs(args) @@ -131,8 +102,8 @@ public static ArrayList processArgs(String[] args) throws JsonGeneration } break; case "merge": - res.add("Merging branch " + args[1] + " to " + core.getCurrentBranchName()); - core.makeMerge(args[1], GitCli::conflictFileChooser); + res.add("Merging branch " + args[1] + " to current state"); + res.addAll(core.makeMerge(args[1])); break; default: res.add("Unknown argument: " + args[0]); diff --git a/hw_git/src/main/java/hw_git/GitCore.java b/hw_git/src/main/java/hw_git/GitCore.java index a520360..c2489d1 100644 --- a/hw_git/src/main/java/hw_git/GitCore.java +++ b/hw_git/src/main/java/hw_git/GitCore.java @@ -1,8 +1,11 @@ package hw_git; +import java.io.BufferedReader; import java.io.File; import java.io.FileNotFoundException; +import java.io.FileReader; import java.io.IOException; +import java.io.PrintWriter; import java.nio.file.FileVisitResult; import java.nio.file.FileVisitor; import java.nio.file.Files; @@ -14,7 +17,6 @@ import java.util.List; import java.util.Map; import java.util.Map.Entry; -import java.util.function.BiFunction; import java.util.Set; import java.util.TreeMap; import java.util.TreeSet; @@ -114,9 +116,6 @@ void makeAdd(String[] filenames) throws IOException, UnversionedException { void makeCommit(String message) throws IOException, UnversionedException, BranchProblemException { findRepInformation(); - if (inform.currentBranchNumber == -1) { - throw new BranchProblemException("Staying not at end of some branch"); - } inform.revision = inform.nCommits; inform.commitMessages.add(message); @@ -159,6 +158,12 @@ public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOEx }); updateRepInformation(); + + + if (inform.currentBranchNumber == -1) { + throw new BranchProblemException("Staying not at end of some branch."); + } + } private void deleteVersionedFiles(File root) { @@ -329,9 +334,16 @@ List getDeletedFiles() throws JsonParseException, JsonMappingException, ArrayList result = new ArrayList<>(); findRepInformation(); - for (String keypath : inform.fileNumber.keySet()) { - if (!Files.exists(informPath.resolve(keypath))) { - result.add(Paths.get("").relativize(Paths.get(keypath)).toString()); + int revision = inform.revision; + TreeMap filesToRestore = new TreeMap<>(); + collectVersionedFiles(revision, filesToRestore); + for (Entry fileEnt : filesToRestore.entrySet()) { + String keyName = RepInformation.getKeyByValue( + fileEnt.getKey(), inform.fileNumber); + if (!Files.exists( + informPath.resolve(keyName))) + { + result.add(keyName); } } @@ -343,18 +355,19 @@ List getChangedFiles() throws JsonParseException, JsonMappingException, ArrayList result = new ArrayList<>(); findRepInformation(); - for (String keyName : inform.fileNumber.keySet()) { - if (Files.exists(informPath.resolve(keyName)) - && !FileUtils.contentEquals( - informPath.resolve(keyName).toFile(), - getStoragePath(Paths.get(keyName), - getLastRevisionOfFile(keyName) - ).toFile() - )) { - result.add(Paths.get("").relativize(Paths.get(keyName)).toString()); + int revision = inform.revision; + TreeMap filesToRestore = new TreeMap<>(); + collectVersionedFiles(revision, filesToRestore); + for (Entry fileEnt : filesToRestore.entrySet()) { + String keyName = RepInformation.getKeyByValue( + fileEnt.getKey(), inform.fileNumber); + if (!FileUtils.contentEquals( + informPath.resolve(keyName).toFile(), + getStoragePath(Paths.get(keyName), fileEnt.getValue()).toFile())) + { + result.add(keyName); } } - return result; } @@ -480,20 +493,40 @@ void makeDeleteBranch(String branchName) throws JsonParseException, JsonMappingE updateRepInformation(); } - void makeMerge(String otherBranchName, BiFunction fileChooser) throws JsonParseException, JsonMappingException, IOException, UnversionedException, BranchProblemException { + private int findLCA(int u, int v) { + int ulen = 0, vlen = 0; + for (int u1 = u; u1 >= 0; u1 = inform.prevCommit.get(u1), ulen++); + for (int v1 = v; v1 >= 0; v1 = inform.prevCommit.get(v1), vlen++); + + for (;ulen > vlen; ulen--, u = inform.prevCommit.get(u)); + for (;vlen > ulen; vlen--, v = inform.prevCommit.get(v)); + + for(; u != v; + u = inform.prevCommit.get(u), + v = inform.prevCommit.get(v)); + return u; + } + + ArrayList makeMerge(String otherBranchName) throws JsonParseException, JsonMappingException, IOException, UnversionedException, BranchProblemException { findRepInformation(); + /* + if (inform.currentBranchNumber == -1) { + throw new BranchProblemException("You have to stay at some branch before merging"); + } + */ + Integer otherBranchNumber = inform.branchNumbers.get(otherBranchName); if (otherBranchNumber == null) { throw new BranchProblemException("No branch with name " + otherBranchName + " found."); } - if (inform.currentBranchNumber == -1) { - throw new BranchProblemException("You have to stay at some branch before merging"); - } + ArrayList res = new ArrayList<>(); + res.add("Please, resolve conflicts in these files:"); - int currRev = inform.currentBranchLastRevision(); + int currRev = inform.revision; int otherRev = inform.branchEnds.get(otherBranchNumber); + //fileNumber, revision Map filesToRestoreCurrent = new TreeMap<>(), filesToRestoreOther = new TreeMap<>(); @@ -501,37 +534,57 @@ void makeMerge(String otherBranchName, BiFunction fileChooser) collectVersionedFiles(currRev, filesToRestoreCurrent); collectVersionedFiles(otherRev, filesToRestoreOther); + Integer lca = findLCA(currRev, otherRev); + for (Entry fileEntry : filesToRestoreCurrent.entrySet()) { + Integer thisEntRevision = fileEntry.getValue(); Integer otherEntRevision = filesToRestoreOther.get(fileEntry.getKey()); + Integer entFileNum = fileEntry.getKey(); + String keyName = RepInformation.getKeyByValue(entFileNum, inform.fileNumber); + if (otherEntRevision == null - || fileEntry.getValue() - .equals(otherEntRevision)) { - restoreFile(fileEntry.getKey(), fileEntry.getValue()); + || otherEntRevision <= lca) { + //restoreFile(entFileNum, thisEntRevision); + //makeAdd(new String[] {keyName}); + } else if (thisEntRevision <= lca && otherEntRevision > lca) { + restoreFile(entFileNum, otherEntRevision); + makeAdd(new String[] {keyName}); } else { - Path keyPath = Paths.get(RepInformation.getKeyByValue(fileEntry.getValue(), inform.fileNumber)); - boolean choosenSuccessfully = false; - while (!choosenSuccessfully) { - try { - FileUtils.copyFile( - fileChooser.apply( - getStoragePath(keyPath, fileEntry.getValue()), - getStoragePath(keyPath, otherEntRevision)).toFile(), - informPath.resolve(keyPath).toFile()); - choosenSuccessfully = true; - } catch (FileNotFoundException e) { - + + File fCurr = getStoragePath(Paths.get(keyName), thisEntRevision).toFile(); + File fOth = getStoragePath(Paths.get(keyName), otherEntRevision).toFile(); + + try (PrintWriter out = new PrintWriter(new File(keyName))) { + out.println("===============Content from revision " + thisEntRevision + " ========"); + try (BufferedReader in = new BufferedReader(new FileReader(fCurr))) { + in.lines().forEach(l -> out.println(l)); + } + out.println("===============Content from revision " + otherEntRevision + " ========"); + try (BufferedReader in = new BufferedReader(new FileReader(fOth))) { + in.lines().forEach(l -> out.println(l)); } } - } + + res.add(keyName); + + } } for (Entry fileEntry : filesToRestoreOther.entrySet()) { if (!filesToRestoreCurrent.containsKey(fileEntry.getKey())) { restoreFile(fileEntry.getKey(), fileEntry.getValue()); + String keyName = RepInformation.getKeyByValue( + fileEntry.getKey(), inform.fileNumber); + makeAdd(new String[] {keyName}); + //res.add(keyName); } } updateRepInformation(); + + if (res.size() == 1) + res.clear(); + return res; } String getCurrentBranchName() throws JsonParseException, JsonMappingException, IOException, UnversionedException { diff --git a/hw_git/src/test/java/hw_git/AppTest.java b/hw_git/src/test/java/hw_git/AppTest.java index 6282c6d..b0169ca 100644 --- a/hw_git/src/test/java/hw_git/AppTest.java +++ b/hw_git/src/test/java/hw_git/AppTest.java @@ -5,13 +5,10 @@ import java.io.IOException; import java.io.PrintWriter; import java.nio.file.Files; -import java.nio.file.Path; import java.nio.file.Paths; import java.util.ArrayList; import java.util.Arrays; import java.util.Scanner; -import java.util.function.BiFunction; - import org.apache.commons.io.FileUtils; @@ -264,67 +261,6 @@ public void testBranchDeleteAndRestore() throws JsonParseException, IOException, assertTrue(Files.exists(Paths.get(file1))); } - @Test - public void testMergeNoConflict() throws JsonParseException, IOException, UnversionedException, BranchProblemException { - GitCli.main(new String[] {"init"}); - GitCli.main(new String[] {"add", file1}); - GitCli.main(new String[] {"commit", "message 1"}); - - GitCli.main(new String[] {"branch", "b1"}); - GitCli.main(new String[] {"checkout", "b1"}); - - GitCli.main(new String[] {"add", file2}); - GitCli.main(new String[] {"commit", "message 2"}); - - GitCli.main(new String[] {"checkout", "master"}); - - GitCore core = new GitCore(); - core.makeMerge("b1", new BiFunction() { - - @Override - public Path apply(Path t, Path u) { - return null; - } - }); - - assertEquals("master", core.getCurrentBranchName()); - assertTrue(Files.exists(Paths.get(file2))); - assertTrue(Files.exists(Paths.get(file1))); - } - - @Test - public void testMergeConflict() throws JsonParseException, IOException, UnversionedException, BranchProblemException { - GitCli.main(new String[] {"init"}); - GitCli.main(new String[] {"add", file1}); - GitCli.main(new String[] {"commit", "message 1"}); - - GitCli.main(new String[] {"commit", "message 2"}); - assertTrue(Files.exists(Paths.get(".myGitDataStorage/testdir/file.txtr0"))); - assertFalse(Files.exists(Paths.get(".myGitDataStorage/testdir/file.txtr1"))); - - GitCli.main(new String[] {"checkout", "1"}); - GitCli.main(new String[] {"branch", "b1"}); - GitCli.main(new String[] {"checkout", "b1"}); - - GitCli.main(new String[] {"add", file1}); - GitCli.main(new String[] {"commit", "message b1"}); - - GitCli.main(new String[] {"checkout", "master"}); - - GitCore core = new GitCore(); - - core.makeMerge("b1", new BiFunction() { - - @Override - public Path apply(Path t, Path u) { - assertEquals(".myGitDataStorage/testdir/file.txtr0", t.toString()); - assertEquals(".myGitDataStorage/testdir/file.txtr2", u.toString()); - return t; - } - }); - - } - @Test public void testLogBasic() throws JsonParseException, IOException, UnversionedException, BranchProblemException { GitCli.main(new String[] {"init"}); @@ -376,7 +312,7 @@ public void testDetachedState() throws JsonParseException, IOException, Unversio assertEquals("HEAD detached on revison 1", GitCli.processArgs(new String[] {"checkout", "1"}).get(1)); - assertEquals("Staying not at end of some branch", + assertEquals("Staying not at end of some branch.", GitCli.processArgs(new String[] {"commit", "abc"}).get(1)); } diff --git a/hw_git/src/test/java/hw_git/ComplexTests.java b/hw_git/src/test/java/hw_git/ComplexTests.java index 51ba08f..559a0b3 100644 --- a/hw_git/src/test/java/hw_git/ComplexTests.java +++ b/hw_git/src/test/java/hw_git/ComplexTests.java @@ -7,6 +7,7 @@ import java.io.File; import java.io.IOException; import java.io.PrintWriter; +import java.nio.file.Files; import java.nio.file.Paths; import java.util.ArrayList; import java.util.Arrays; @@ -187,7 +188,8 @@ public void testCheckoutWithLogAndStatus() throws IOException { @Test public void testResetWithLogAndStatus() throws IOException { - FileUtils.touch(Paths.get(testdir).resolve("file1").toFile()); + Files.createDirectory(Paths.get(testdir)); + try (PrintWriter out = new PrintWriter(new File("testdir/file1"))) { out.println("initial content"); } @@ -319,8 +321,9 @@ public void testResetWithLogAndStatus() throws IOException { } @Test - public void testBranchRM() throws IOException { - FileUtils.touch(Paths.get(testdir).resolve("file1").toFile()); + public void testBranchRM() throws IOException, UnversionedException, BranchProblemException { + Files.createDirectory(Paths.get(testdir)); + try (PrintWriter out = new PrintWriter(new File("testdir/file1"))) { out.println("initial content"); } @@ -347,12 +350,90 @@ public void testBranchRM() throws IOException { try (PrintWriter out = new PrintWriter("testdir/file1")) { out.println("revision 3 content"); } + GitCli.main(new String[] {"commit", "mes 3"}); + ArrayList beforeRMLog = GitCli.processArgs(new String[] {"log"}); + assertEquals(beforeRMLog, GitCli.processArgs(new String[] {"log", "3"})); + assertEquals( Arrays.asList( "Deleting branch b1", "You can't delete this branch while staying on it."), GitCli.processArgs(new String[] {"branch", "-d", "b1"})); + + GitCli.main(new String[] {"checkout", "master"}); + try (Scanner in = new Scanner(new File("testdir/file1"))) { + assertEquals("revision 2 content", in.nextLine()); + } + + assertEquals( + Arrays.asList( + "Deleting branch b1"), + GitCli.processArgs(new String[] {"branch", "-d", "b1"})); + + assertEquals(beforeRMLog, GitCli.processArgs(new String[] {"log", "3"})); + assertEquals( + Arrays.asList( + "Checking out branch...", + "Branch not exists: b1"), + GitCli.processArgs(new String[] {"checkout", "b1"})); + GitCli.main(new String[] {"checkout", "3"}); + + assertEquals(beforeRMLog, GitCli.processArgs(new String[] {"log"})); + GitCore core = new GitCore(); + core.makeBranch("b1"); + core.makeCheckout("b1"); + } + + @Test + public void testMergeNoConflict() throws IOException, UnversionedException, BranchProblemException { + Files.createDirectory(Paths.get(testdir)); + try (PrintWriter out = new PrintWriter(new File("testdir/file1"))) { + out.println("initial 1 content"); + } + try (PrintWriter out = new PrintWriter(new File("testdir/file2"))) { + out.println("initial 2 content"); + } + + GitCli.main(new String[] {"init"}); + GitCli.main(new String[] {"add", "testdir/file1", "testdir/file2"}); + GitCli.main(new String[] {"commit", "mes 1"}); + + try (PrintWriter out = new PrintWriter(new File("testdir/file2"))) { + out.println("2 content"); + } + + GitCli.main(new String[] {"add", "testdir/file2"}); + GitCli.main(new String[] {"commit", "mes 2"}); + + GitCli.main(new String[] {"checkout", "1"}); + GitCli.main(new String[] {"branch", "b1"}); + GitCli.main(new String[] {"checkout", "b1"}); + + try (PrintWriter out = new PrintWriter(new File("testdir/file3"))) { + out.println("3 content"); + } + + GitCli.main(new String[] {"add", "testdir/file3"}); + GitCli.main(new String[] {"commit", "mes 3"}); + + GitCli.main(new String[] {"checkout", "master"}); + + assertEquals(Arrays.asList("Merging branch b1 to current state"), + GitCli.processArgs(new String[] {"merge", "b1"})); + + //new GitCore().makeMerge("b1"); + + assertEquals( + Arrays.asList( + "Status:", + "branch master", + "Staged files:\n________________", + "testdir/file3", + "Deleted files:\n________________", + "Changed files:\n________________", + "Untracked files:\n________________"), + GitCli.processArgs(new String[] {"status"}).subList(0, 7)); } } From e2d95509edf2cc434a2e37d9b67c3757ec8ef039 Mon Sep 17 00:00:00 2001 From: Anton Date: Thu, 8 Nov 2018 19:49:21 +0300 Subject: [PATCH 15/16] =?UTF-8?q?=D0=98=D1=81=D0=BF=D1=80=D0=B0=D0=B2?= =?UTF-8?q?=D0=BB=D0=B5=D0=BD=D0=BE=20=D1=83=D0=B4=D0=B0=D0=BB=D0=B5=D0=BD?= =?UTF-8?q?=D0=B8=D0=B5=20=D1=84=D0=B0=D0=B9=D0=BB=D0=BE=D0=B2.=20=D0=A2?= =?UTF-8?q?=D0=B5=D0=BF=D0=B5=D1=80=D1=8C=20=D0=BE=D0=BD=D0=BE=20=D0=BD?= =?UTF-8?q?=D0=B5=20=D0=B2=D0=BB=D0=B8=D1=8F=D0=B5=D1=82=20=D0=BD=D0=B0=20?= =?UTF-8?q?=D1=81=D0=B4=D0=B5=D0=BB=D0=B0=D0=BD=D0=BD=D1=8B=D0=B9=20=D0=BA?= =?UTF-8?q?=D0=BE=D0=BC=D0=BC=D0=B8=D1=82.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- hw_git/src/main/java/hw_git/GitCore.java | 30 ++-- .../src/main/java/hw_git/RepInformation.java | 10 ++ hw_git/src/test/java/hw_git/AppTest.java | 41 +++++- hw_git/src/test/java/hw_git/ComplexTests.java | 131 ++++++++++++++++++ 4 files changed, 201 insertions(+), 11 deletions(-) diff --git a/hw_git/src/main/java/hw_git/GitCore.java b/hw_git/src/main/java/hw_git/GitCore.java index c2489d1..3d9e0b0 100644 --- a/hw_git/src/main/java/hw_git/GitCore.java +++ b/hw_git/src/main/java/hw_git/GitCore.java @@ -20,6 +20,7 @@ import java.util.Set; import java.util.TreeMap; import java.util.TreeSet; +import java.util.stream.Collectors; import org.apache.commons.io.FileUtils; @@ -130,6 +131,9 @@ void makeCommit(String message) throws IOException, UnversionedException, Branch inform.numberOfStartedBranchesAtRevision.add(0); } + inform.removedFiles.get(inform.revision).addAll(inform.stageRemovedFiles); + inform.stageRemovedFiles.clear(); + Files.walkFileTree( informPath.resolve(stageFolder), new FileVisitor() { @@ -290,6 +294,9 @@ void makeReset(int revision) throws JsonParseException, JsonMappingException, IO int currDetachedPosT = inform.detachedHeadRevision; makeCheckout(revision); + FileUtils.cleanDirectory(Paths.get(stageFolder).toFile()); + inform.stageRemovedFiles.clear(); + if (currBranchT != -1) { inform.currentBranchNumber = currBranchT; inform.branchEnds.put(currBranchT, revision); @@ -331,9 +338,9 @@ ArrayList getLog(int revision) throws JsonParseException, JsonMappingExc } List getDeletedFiles() throws JsonParseException, JsonMappingException, IOException, UnversionedException { - ArrayList result = new ArrayList<>(); + //ArrayList result = new ArrayList<>(); findRepInformation(); - + /* int revision = inform.revision; TreeMap filesToRestore = new TreeMap<>(); collectVersionedFiles(revision, filesToRestore); @@ -346,8 +353,12 @@ List getDeletedFiles() throws JsonParseException, JsonMappingException, result.add(keyName); } } - - return result; + */ + + + return inform.stageRemovedFiles.stream() + .map(i -> RepInformation.getKeyByValue(i, inform.fileNumber)) + .collect(Collectors.toList()); } @@ -439,7 +450,7 @@ int getCurrentRevision() { private void removeFromRep(String filename) throws IOException { Path keypath = getKeyPath(filename); - int revision = inform.revision; + //int revision = inform.revision; Integer fileNumber = inform.fileNumber.get(keypath.toString()); @@ -447,7 +458,8 @@ private void removeFromRep(String filename) throws IOException { throw new FileNotFoundException("File not versioned: " + filename); } - inform.removedFiles.get(revision).add(fileNumber); + //inform.removedFiles.get(revision).add(fileNumber); + inform.stageRemovedFiles.add(fileNumber); Files.deleteIfExists(informPath.resolve(stageFolder).resolve(keypath)); } @@ -521,7 +533,7 @@ ArrayList makeMerge(String otherBranchName) throws JsonParseException, J } ArrayList res = new ArrayList<>(); - res.add("Please, resolve conflicts in these files:"); + res.add("Please, resolve conflicts in these files, and \"add\" them to commit:"); int currRev = inform.revision; int otherRev = inform.branchEnds.get(otherBranchNumber); @@ -555,11 +567,11 @@ ArrayList makeMerge(String otherBranchName) throws JsonParseException, J File fOth = getStoragePath(Paths.get(keyName), otherEntRevision).toFile(); try (PrintWriter out = new PrintWriter(new File(keyName))) { - out.println("===============Content from revision " + thisEntRevision + " ========"); + out.println("===============Content from revision " + (thisEntRevision + 1) + " ========"); try (BufferedReader in = new BufferedReader(new FileReader(fCurr))) { in.lines().forEach(l -> out.println(l)); } - out.println("===============Content from revision " + otherEntRevision + " ========"); + out.println("===============Content from revision " + (otherEntRevision + 1) + " ========"); try (BufferedReader in = new BufferedReader(new FileReader(fOth))) { in.lines().forEach(l -> out.println(l)); } diff --git a/hw_git/src/main/java/hw_git/RepInformation.java b/hw_git/src/main/java/hw_git/RepInformation.java index 1842676..9e7d942 100644 --- a/hw_git/src/main/java/hw_git/RepInformation.java +++ b/hw_git/src/main/java/hw_git/RepInformation.java @@ -34,6 +34,8 @@ public class RepInformation { TreeMap branchEnds = new TreeMap<>(); ArrayList numberOfStartedBranchesAtRevision = new ArrayList<>(); + + ArrayList stageRemovedFiles = new ArrayList<>(); public RepInformation() { branchNumbers.put("master", 0); @@ -179,5 +181,13 @@ public int getDetachedHeadRevision() { public void setDetachedHeadRevision(int detachedHeadRevision) { this.detachedHeadRevision = detachedHeadRevision; } + + public ArrayList getStageRemovedFiles() { + return stageRemovedFiles; + } + + public void setStageRemovedFiles(ArrayList stageRemovedFiles) { + this.stageRemovedFiles = stageRemovedFiles; + } } diff --git a/hw_git/src/test/java/hw_git/AppTest.java b/hw_git/src/test/java/hw_git/AppTest.java index b0169ca..3069599 100644 --- a/hw_git/src/test/java/hw_git/AppTest.java +++ b/hw_git/src/test/java/hw_git/AppTest.java @@ -139,11 +139,14 @@ public void testRM() throws JsonGenerationException, JsonMappingException, IOExc GitCli.main(new String[] {"commit", "message 2"}); Files.delete(Paths.get(file1)); GitCli.main(new String[] {"rm", file1}); + GitCli.main(new String[] {"commit", "remove file1"}); GitCli.main(new String[] {"checkout", "2"}); - assertFalse(Files.exists(Paths.get(file1))); + assertTrue(Files.exists(Paths.get(file1))); GitCli.main(new String[] {"checkout", "1"}); assertTrue(Files.exists(Paths.get(file1))); + GitCli.main(new String[] {"checkout", "master"}); + assertFalse(Files.exists(Paths.get(file1))); } @Test @@ -167,7 +170,7 @@ public void testStatus() throws JsonGenerationException, JsonMappingException, I Files.delete(Paths.get(file1)); - assertEquals(core.getDeletedFiles(), Arrays.asList(file1)); + assertEquals(core.getChangedFiles(), Arrays.asList(file1)); } @@ -339,4 +342,38 @@ public void testCommitFileInRoot() throws JsonParseException, IOException, Unver assertEquals("\nrevision: 1\nmessage 2", logRes.get(1)); } + @Test + public void testResetClearsStage() throws JsonGenerationException, JsonMappingException { + GitCli.main(new String[] {"init"}); + GitCli.main(new String[] {"add", "one.txt"}); + GitCli.main(new String[] {"commit", "message 1"}); + + GitCli.main(new String[] {"add", "testdir/file.txt"}); + GitCli.main(new String[] {"rm", "one.txt"}); + + assertEquals( + Arrays.asList( + "Status:", + "branch master", + "Staged files:\n________________", + "testdir/file.txt", + "Deleted files:\n________________", + "one.txt", + "Changed files:\n________________", + "Untracked files:\n________________"), + GitCli.processArgs(new String[] {"status"}).subList(0, 8)); + + GitCli.main(new String[] {"reset", "1"}); + + assertEquals( + Arrays.asList( + "Status:", + "branch master", + "Staged files:\n________________", + "Deleted files:\n________________", + "Changed files:\n________________", + "Untracked files:\n________________"), + GitCli.processArgs(new String[] {"status"}).subList(0, 6)); + } + } diff --git a/hw_git/src/test/java/hw_git/ComplexTests.java b/hw_git/src/test/java/hw_git/ComplexTests.java index 559a0b3..de9e09c 100644 --- a/hw_git/src/test/java/hw_git/ComplexTests.java +++ b/hw_git/src/test/java/hw_git/ComplexTests.java @@ -4,7 +4,9 @@ import org.junit.Assert; import org.junit.Test; +import java.io.BufferedReader; import java.io.File; +import java.io.FileReader; import java.io.IOException; import java.io.PrintWriter; import java.nio.file.Files; @@ -12,6 +14,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Scanner; +import java.util.stream.Collectors; import org.apache.commons.io.FileUtils; @@ -436,4 +439,132 @@ public void testMergeNoConflict() throws IOException, UnversionedException, Bran "Untracked files:\n________________"), GitCli.processArgs(new String[] {"status"}).subList(0, 7)); } + + @Test + public void testMergeWithConflicts() throws IOException, UnversionedException, BranchProblemException { + Files.createDirectory(Paths.get(testdir)); + try (PrintWriter out = new PrintWriter(new File("testdir/file1"))) { + out.println("initial 1 content"); + } + + try (PrintWriter out = new PrintWriter(new File("testdir/file2"))) { + out.println("initial 2 content"); + } + + try (PrintWriter out = new PrintWriter(new File("testdir/file3"))) { + out.println("initial 3 content"); + } + + try (PrintWriter out = new PrintWriter(new File("testdir/file4"))) { + out.println("initial 4 content"); + } + + try (PrintWriter out = new PrintWriter(new File("testdir/file5"))) { + out.println("initial 5 content"); + } + + try (PrintWriter out = new PrintWriter(new File("testdir/file6"))) { + out.println("initial 6 content"); + } + + try (PrintWriter out = new PrintWriter(new File("testdir/file7"))) { + out.println("initial 7 content"); + } + + GitCli.main(new String[] {"init"}); + GitCli.main(new String[] {"add", "testdir/file1", "testdir/file2", "testdir/file5"}); + GitCli.main(new String[] {"add", "testdir/file3", "testdir/file4", "testdir/file7"}); + GitCli.main(new String[] {"commit", "mes 1"}); + + try (PrintWriter out = new PrintWriter(new File("testdir/file2"))) { + out.println("2 content"); + } + + try (PrintWriter out = new PrintWriter(new File("testdir/file4"))) { + out.println("4 content"); + } + + GitCli.main(new String[] {"rm", "testdir/file7"}); + GitCli.main(new String[] {"add", "testdir/file2", "testdir/file4"}); + GitCli.main(new String[] {"commit", "mes 2"}); + + GitCli.main(new String[] {"checkout", "1"}); + GitCli.main(new String[] {"branch", "b1"}); + GitCli.main(new String[] {"checkout", "b1"}); + + try (PrintWriter out = new PrintWriter(new File("testdir/file3"))) { + out.println("3 from b1 content"); + } + + GitCli.main(new String[] {"rm", "testdir/file5"}); + + try (PrintWriter out = new PrintWriter(new File("testdir/file4"))) { + out.println("4 b1 content"); + } + GitCli.main(new String[] {"add", "testdir/file3", "testdir/file4", "testdir/file6"}); + GitCli.main(new String[] {"commit", "mes 3"}); + + + GitCli.main(new String[] {"rm", "testdir/file6"}); + GitCli.main(new String[] {"commit", "mes 4"}); + + try (Scanner in = new Scanner(new File("testdir/file6"))) { + assertEquals("initial 6 content", in.nextLine()); + } + + GitCli.main(new String[] {"checkout", "master"}); + + assertEquals(Arrays.asList("Merging branch b1 to current state", + "Please, resolve conflicts in these files, and \"add\" them to commit:", + "testdir/file4"), + GitCli.processArgs(new String[] {"merge", "b1"})); + + //new GitCore().makeMerge("b1"); + + assertEquals( + Arrays.asList( + "Status:", + "branch master", + "Staged files:\n________________", + "testdir/file3", + "testdir/file7", + "Deleted files:\n________________", + "Changed files:\n________________", + "testdir/file3", + "testdir/file4", + "Untracked files:\n________________"), + GitCli.processArgs(new String[] {"status"}).subList(0, 10)); + + try (Scanner in = new Scanner(new File("testdir/file1"))) { + assertEquals("initial 1 content", in.nextLine()); + } + + try (Scanner in = new Scanner(new File("testdir/file2"))) { + assertEquals("2 content", in.nextLine()); + } + + try (Scanner in = new Scanner(new File("testdir/file3"))) { + assertEquals("3 from b1 content", in.nextLine()); + } + + try (BufferedReader in = new BufferedReader(new FileReader(new File("testdir/file4")))) { + + assertEquals(Arrays.asList( + "===============Content from revision 2 ========", + "4 content", + "===============Content from revision 3 ========", + "4 b1 content") + , in.lines().collect(Collectors.toList())); + } + + try (Scanner in = new Scanner(new File("testdir/file5"))) { + assertEquals("initial 5 content", in.nextLine()); + } + + assertFalse(Files.exists(Paths.get("testdir/file6"))); + + try (Scanner in = new Scanner(new File("testdir/file7"))) { + assertEquals("initial 7 content", in.nextLine()); + } + } } From 8eb8bea9c16c3527aa98b585a1efc6b2c4816df7 Mon Sep 17 00:00:00 2001 From: Anton Date: Thu, 8 Nov 2018 21:12:11 +0300 Subject: [PATCH 16/16] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=20surefire=20plugin=20=D0=B2=20maven.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit После merge напоминание о том что надо сделать коммит. --- hw_git/pom.xml | 5 +++ hw_git/src/main/java/hw_git/GitCli.java | 4 +-- hw_git/src/main/java/hw_git/GitCore.java | 36 ++----------------- hw_git/src/test/java/hw_git/ComplexTests.java | 6 ++-- 4 files changed, 13 insertions(+), 38 deletions(-) diff --git a/hw_git/pom.xml b/hw_git/pom.xml index 5d69e27..2402663 100644 --- a/hw_git/pom.xml +++ b/hw_git/pom.xml @@ -23,6 +23,11 @@ UTF-8 + + org.apache.maven.plugins + maven-surefire-plugin + 3.0.0-M1 + org.apache.maven.plugins maven-jar-plugin diff --git a/hw_git/src/main/java/hw_git/GitCli.java b/hw_git/src/main/java/hw_git/GitCli.java index 73175ca..82c3528 100644 --- a/hw_git/src/main/java/hw_git/GitCli.java +++ b/hw_git/src/main/java/hw_git/GitCli.java @@ -4,7 +4,6 @@ import java.io.FileNotFoundException; import java.io.IOException; import java.nio.file.Path; -import java.nio.file.Paths; import java.util.ArrayList; import java.util.Arrays; import java.util.Scanner; @@ -102,7 +101,8 @@ public static ArrayList processArgs(String[] args) throws JsonGeneration } break; case "merge": - res.add("Merging branch " + args[1] + " to current state"); + res.add("Merging branch " + args[1] + " to current state." + + "\nYou should make commit then."); res.addAll(core.makeMerge(args[1])); break; default: diff --git a/hw_git/src/main/java/hw_git/GitCore.java b/hw_git/src/main/java/hw_git/GitCore.java index 3d9e0b0..f07862f 100644 --- a/hw_git/src/main/java/hw_git/GitCore.java +++ b/hw_git/src/main/java/hw_git/GitCore.java @@ -283,13 +283,7 @@ void makeCheckout(String[] files) throws JsonParseException, JsonMappingExceptio void makeReset(int revision) throws JsonParseException, JsonMappingException, IOException, UnversionedException, BranchProblemException { findRepInformation(); - /* - inform.revision = revision; - if (inform.currentBranchNumber != -1) { - inform.branchEnds.put(inform.currentBranchNumber, revision); - } - - */ + int currBranchT = inform.currentBranchNumber; int currDetachedPosT = inform.detachedHeadRevision; makeCheckout(revision); @@ -338,24 +332,8 @@ ArrayList getLog(int revision) throws JsonParseException, JsonMappingExc } List getDeletedFiles() throws JsonParseException, JsonMappingException, IOException, UnversionedException { - //ArrayList result = new ArrayList<>(); findRepInformation(); - /* - int revision = inform.revision; - TreeMap filesToRestore = new TreeMap<>(); - collectVersionedFiles(revision, filesToRestore); - for (Entry fileEnt : filesToRestore.entrySet()) { - String keyName = RepInformation.getKeyByValue( - fileEnt.getKey(), inform.fileNumber); - if (!Files.exists( - informPath.resolve(keyName))) - { - result.add(keyName); - } - } - */ - - + return inform.stageRemovedFiles.stream() .map(i -> RepInformation.getKeyByValue(i, inform.fileNumber)) .collect(Collectors.toList()); @@ -450,7 +428,6 @@ int getCurrentRevision() { private void removeFromRep(String filename) throws IOException { Path keypath = getKeyPath(filename); - //int revision = inform.revision; Integer fileNumber = inform.fileNumber.get(keypath.toString()); @@ -458,7 +435,6 @@ private void removeFromRep(String filename) throws IOException { throw new FileNotFoundException("File not versioned: " + filename); } - //inform.removedFiles.get(revision).add(fileNumber); inform.stageRemovedFiles.add(fileNumber); Files.deleteIfExists(informPath.resolve(stageFolder).resolve(keypath)); @@ -521,11 +497,6 @@ private int findLCA(int u, int v) { ArrayList makeMerge(String otherBranchName) throws JsonParseException, JsonMappingException, IOException, UnversionedException, BranchProblemException { findRepInformation(); - /* - if (inform.currentBranchNumber == -1) { - throw new BranchProblemException("You have to stay at some branch before merging"); - } - */ Integer otherBranchNumber = inform.branchNumbers.get(otherBranchName); if (otherBranchNumber == null) { @@ -556,8 +527,6 @@ ArrayList makeMerge(String otherBranchName) throws JsonParseException, J if (otherEntRevision == null || otherEntRevision <= lca) { - //restoreFile(entFileNum, thisEntRevision); - //makeAdd(new String[] {keyName}); } else if (thisEntRevision <= lca && otherEntRevision > lca) { restoreFile(entFileNum, otherEntRevision); makeAdd(new String[] {keyName}); @@ -588,7 +557,6 @@ ArrayList makeMerge(String otherBranchName) throws JsonParseException, J String keyName = RepInformation.getKeyByValue( fileEntry.getKey(), inform.fileNumber); makeAdd(new String[] {keyName}); - //res.add(keyName); } } diff --git a/hw_git/src/test/java/hw_git/ComplexTests.java b/hw_git/src/test/java/hw_git/ComplexTests.java index de9e09c..ac72a78 100644 --- a/hw_git/src/test/java/hw_git/ComplexTests.java +++ b/hw_git/src/test/java/hw_git/ComplexTests.java @@ -423,7 +423,8 @@ public void testMergeNoConflict() throws IOException, UnversionedException, Bran GitCli.main(new String[] {"checkout", "master"}); - assertEquals(Arrays.asList("Merging branch b1 to current state"), + assertEquals(Arrays.asList("Merging branch b1 to current state." + + "\nYou should make commit then."), GitCli.processArgs(new String[] {"merge", "b1"})); //new GitCore().makeMerge("b1"); @@ -514,7 +515,8 @@ public void testMergeWithConflicts() throws IOException, UnversionedException, B GitCli.main(new String[] {"checkout", "master"}); - assertEquals(Arrays.asList("Merging branch b1 to current state", + assertEquals(Arrays.asList("Merging branch b1 to current state." + + "\nYou should make commit then.", "Please, resolve conflicts in these files, and \"add\" them to commit:", "testdir/file4"), GitCli.processArgs(new String[] {"merge", "b1"}));