diff --git a/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/repo/GitProjectRepo.java b/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/repo/GitProjectRepo.java index 6f020d79ad..5c7ac2cb07 100644 --- a/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/repo/GitProjectRepo.java +++ b/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/repo/GitProjectRepo.java @@ -240,6 +240,7 @@ public class GitProjectRepo implements ProjectRepo { ) throws IOException, GitAPIException { Preconditions.checkState(repository.isPresent()); Repository repo = getJGitRepository(); + resetHard(); String name = getProjectName(); Log.info("[{}] Writing commit", name); contents.write(); diff --git a/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/repo/NoGitignoreIterator.java b/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/repo/NoGitignoreIterator.java index 065aa6d024..64103c075e 100644 --- a/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/repo/NoGitignoreIterator.java +++ b/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/repo/NoGitignoreIterator.java @@ -1,6 +1,7 @@ package uk.ac.ic.wlgitbridge.bridge.repo; import org.eclipse.jgit.lib.Repository; +import org.eclipse.jgit.treewalk.AbstractTreeIterator; import org.eclipse.jgit.treewalk.FileTreeIterator; import org.eclipse.jgit.treewalk.WorkingTreeIterator; import org.eclipse.jgit.treewalk.WorkingTreeOptions; @@ -64,6 +65,8 @@ public class NoGitignoreIterator extends FileTreeIterator { super(p, root, fs, fileModeStrategy); } + // Note: the `list` is a list of top-level entities in this directory, + // not a full list of files in the tree. @Override protected void init(Entry[] list) { super.init(list); @@ -74,4 +77,11 @@ public class NoGitignoreIterator extends FileTreeIterator { } } + // When entering a sub-directory, create a new instance of this class, + // so we can also ignore gitignore specifications in sub-directories + @Override + protected AbstractTreeIterator enterSubtree() { + String fullPath = getDirectory().getAbsolutePath() + "/" + current().getName(); + return new NoGitignoreIterator(this, new File(fullPath), fs, fileModeStrategy); + } } diff --git a/services/git-bridge/src/test/java/uk/ac/ic/wlgitbridge/application/WLGitBridgeIntegrationTest.java b/services/git-bridge/src/test/java/uk/ac/ic/wlgitbridge/application/WLGitBridgeIntegrationTest.java index 9fcef7ccf3..5ee773bede 100644 --- a/services/git-bridge/src/test/java/uk/ac/ic/wlgitbridge/application/WLGitBridgeIntegrationTest.java +++ b/services/git-bridge/src/test/java/uk/ac/ic/wlgitbridge/application/WLGitBridgeIntegrationTest.java @@ -147,6 +147,10 @@ public class WLGitBridgeIntegrationTest { put("cannotCloneAHasDotGitProject", new HashMap() {{ put("state", new SnapshotAPIStateBuilder(getResourceAsStream("/cannotCloneAHasDotGitProject/state/state.json")).build()); }}); + put("canPullIgnoredForceAddedFile", new HashMap() {{ + put("base", new SnapshotAPIStateBuilder(getResourceAsStream("/canPullIgnoredForceAddedFile/base/state.json")).build()); + put("withUpdatedMainFile", new SnapshotAPIStateBuilder(getResourceAsStream("/canPullIgnoredForceAddedFile/withUpdatedMainFile/state.json")).build()); + }}); }}; @Rule @@ -995,6 +999,52 @@ public class WLGitBridgeIntegrationTest { assertTrue(responseString.contains("Git LFS is not supported on Overleaf")); } + @Test + public void canPullIgnoredForceAddedFile() throws IOException, InterruptedException { + int gitBridgePort = 33891; + int mockServerPort = 3891; + server = new MockSnapshotServer(mockServerPort, getResource("/canPullIgnoredForceAddedFile").toFile()); + server.start(); + server.setState(states.get("canPullIgnoredForceAddedFile").get("base")); + wlgb = new GitBridgeApp(new String[] { + makeConfigFile(gitBridgePort, mockServerPort) + }); + wlgb.run(); + File testProjDir = gitClone("testproj", gitBridgePort, dir); + File one = new File(testProjDir, "sub/one.txt"); + one.createNewFile(); + FileWriter fw = new FileWriter(one.getPath()); + fw.write("1"); + fw.close(); + assertEquals(0, runtime.exec( + "git add -A -f", null, testProjDir + ).waitFor()); + gitCommit(testProjDir, "push"); + gitPush(testProjDir); + server.setState(states.get("canPullIgnoredForceAddedFile").get("withUpdatedMainFile")); + gitPull(testProjDir); + File f = new File(testProjDir.getPath() + "/sub/one.txt"); + assertTrue(f.exists()); + } + + @Test + public void canPullIgnoredFileFromOverleaf() throws IOException, InterruptedException { + int gitBridgePort = 33892; + int mockServerPort = 3892; + server = new MockSnapshotServer(mockServerPort, getResource("/canPullIgnoredForceAddedFile").toFile()); + server.start(); + server.setState(states.get("canPullIgnoredForceAddedFile").get("base")); + wlgb = new GitBridgeApp(new String[] { + makeConfigFile(gitBridgePort, mockServerPort) + }); + wlgb.run(); + File testProjDir = gitClone("testproj", gitBridgePort, dir); + server.setState(states.get("canPullIgnoredForceAddedFile").get("withUpdatedMainFile")); + gitPull(testProjDir); + File f = new File(testProjDir.getPath() + "/sub/one.txt"); + assertTrue(f.exists()); + } + private String makeConfigFile( int port, int apiPort diff --git a/services/git-bridge/src/test/resources/uk/ac/ic/wlgitbridge/WLGitBridgeIntegrationTest/canPullIgnoredForceAddedFile/base/state.json b/services/git-bridge/src/test/resources/uk/ac/ic/wlgitbridge/WLGitBridgeIntegrationTest/canPullIgnoredForceAddedFile/base/state.json new file mode 100644 index 0000000000..3a099a5fc0 --- /dev/null +++ b/services/git-bridge/src/test/resources/uk/ac/ic/wlgitbridge/WLGitBridgeIntegrationTest/canPullIgnoredForceAddedFile/base/state.json @@ -0,0 +1,41 @@ +[ + { + "project": "testproj", + "getDoc": { + "versionID": 1, + "createdAt": "2014-11-30T18:40:58.123Z", + "email": "jdleesmiller+1@gmail.com", + "name": "John+1" + }, + "getSavedVers": [ + { + "versionID": 1, + "comment": "init", + "email": "jdleesmiller+1@gmail.com", + "name": "John+1", + "createdAt": "2014-11-30T18:47:01.456Z" + } + ], + "getForVers": [ + { + "versionID": 1, + "srcs": [ + { + "content": "content\n", + "path": "main.tex" + }, + { + "content": "*.txt", + "path": "sub/.gitignore" + } + ], + "atts": [] + } + ], + "push": "success", + "postback": { + "type": "success", + "versionID": 2 + } + } +] diff --git a/services/git-bridge/src/test/resources/uk/ac/ic/wlgitbridge/WLGitBridgeIntegrationTest/canPullIgnoredForceAddedFile/base/testproj/main.tex b/services/git-bridge/src/test/resources/uk/ac/ic/wlgitbridge/WLGitBridgeIntegrationTest/canPullIgnoredForceAddedFile/base/testproj/main.tex new file mode 100644 index 0000000000..d95f3ad14d --- /dev/null +++ b/services/git-bridge/src/test/resources/uk/ac/ic/wlgitbridge/WLGitBridgeIntegrationTest/canPullIgnoredForceAddedFile/base/testproj/main.tex @@ -0,0 +1 @@ +content diff --git a/services/git-bridge/src/test/resources/uk/ac/ic/wlgitbridge/WLGitBridgeIntegrationTest/canPullIgnoredForceAddedFile/base/testproj/sub/.gitignore b/services/git-bridge/src/test/resources/uk/ac/ic/wlgitbridge/WLGitBridgeIntegrationTest/canPullIgnoredForceAddedFile/base/testproj/sub/.gitignore new file mode 100644 index 0000000000..2211df63dd --- /dev/null +++ b/services/git-bridge/src/test/resources/uk/ac/ic/wlgitbridge/WLGitBridgeIntegrationTest/canPullIgnoredForceAddedFile/base/testproj/sub/.gitignore @@ -0,0 +1 @@ +*.txt diff --git a/services/git-bridge/src/test/resources/uk/ac/ic/wlgitbridge/WLGitBridgeIntegrationTest/canPullIgnoredForceAddedFile/withUpdatedMainFile/state.json b/services/git-bridge/src/test/resources/uk/ac/ic/wlgitbridge/WLGitBridgeIntegrationTest/canPullIgnoredForceAddedFile/withUpdatedMainFile/state.json new file mode 100644 index 0000000000..393f5a253a --- /dev/null +++ b/services/git-bridge/src/test/resources/uk/ac/ic/wlgitbridge/WLGitBridgeIntegrationTest/canPullIgnoredForceAddedFile/withUpdatedMainFile/state.json @@ -0,0 +1,45 @@ +[ + { + "project": "testproj", + "getDoc": { + "versionID": 5, + "createdAt": "2014-11-30T18:40:58.123Z", + "email": "jdleesmiller+1@gmail.com", + "name": "John+1" + }, + "getSavedVers": [ + { + "versionID": 5, + "comment": "init", + "email": "jdleesmiller+1@gmail.com", + "name": "John+1", + "createdAt": "2014-11-30T18:47:01.456Z" + } + ], + "getForVers": [ + { + "versionID": 5, + "srcs": [ + { + "content": "content\nupdated\n", + "path": "main.tex" + }, + { + "content": "*.txt", + "path": "sub/.gitignore" + }, + { + "content": "1", + "path": "sub/one.txt" + } + ], + "atts": [] + } + ], + "push": "success", + "postback": { + "type": "success", + "versionID": 5 + } + } +] diff --git a/services/git-bridge/src/test/resources/uk/ac/ic/wlgitbridge/WLGitBridgeIntegrationTest/canPullIgnoredForceAddedFile/withUpdatedMainFile/testproj/main.tex b/services/git-bridge/src/test/resources/uk/ac/ic/wlgitbridge/WLGitBridgeIntegrationTest/canPullIgnoredForceAddedFile/withUpdatedMainFile/testproj/main.tex new file mode 100644 index 0000000000..3aa9d51a9f --- /dev/null +++ b/services/git-bridge/src/test/resources/uk/ac/ic/wlgitbridge/WLGitBridgeIntegrationTest/canPullIgnoredForceAddedFile/withUpdatedMainFile/testproj/main.tex @@ -0,0 +1,2 @@ +content +updated diff --git a/services/git-bridge/src/test/resources/uk/ac/ic/wlgitbridge/WLGitBridgeIntegrationTest/canPullIgnoredForceAddedFile/withUpdatedMainFile/testproj/sub/.gitignore b/services/git-bridge/src/test/resources/uk/ac/ic/wlgitbridge/WLGitBridgeIntegrationTest/canPullIgnoredForceAddedFile/withUpdatedMainFile/testproj/sub/.gitignore new file mode 100644 index 0000000000..2211df63dd --- /dev/null +++ b/services/git-bridge/src/test/resources/uk/ac/ic/wlgitbridge/WLGitBridgeIntegrationTest/canPullIgnoredForceAddedFile/withUpdatedMainFile/testproj/sub/.gitignore @@ -0,0 +1 @@ +*.txt diff --git a/services/git-bridge/src/test/resources/uk/ac/ic/wlgitbridge/WLGitBridgeIntegrationTest/canPullIgnoredForceAddedFile/withUpdatedMainFile/testproj/sub/one.txt b/services/git-bridge/src/test/resources/uk/ac/ic/wlgitbridge/WLGitBridgeIntegrationTest/canPullIgnoredForceAddedFile/withUpdatedMainFile/testproj/sub/one.txt new file mode 100644 index 0000000000..d00491fd7e --- /dev/null +++ b/services/git-bridge/src/test/resources/uk/ac/ic/wlgitbridge/WLGitBridgeIntegrationTest/canPullIgnoredForceAddedFile/withUpdatedMainFile/testproj/sub/one.txt @@ -0,0 +1 @@ +1