1
2
3
4
5
6
7
8
9
10 package org.eclipse.jgit.submodule;
11
12 import java.io.File;
13 import java.io.IOException;
14 import java.util.Collection;
15
16 import org.eclipse.jgit.api.Git;
17 import org.eclipse.jgit.api.SubmoduleDeinitCommand;
18 import org.eclipse.jgit.api.SubmoduleDeinitResult;
19 import org.eclipse.jgit.api.SubmoduleUpdateCommand;
20 import org.eclipse.jgit.api.errors.GitAPIException;
21 import org.eclipse.jgit.dircache.DirCache;
22 import org.eclipse.jgit.dircache.DirCacheEditor;
23 import org.eclipse.jgit.dircache.DirCacheEditor.PathEdit;
24 import org.eclipse.jgit.dircache.DirCacheEntry;
25 import org.eclipse.jgit.junit.JGitTestUtil;
26 import org.eclipse.jgit.junit.RepositoryTestCase;
27 import org.eclipse.jgit.lib.ConfigConstants;
28 import org.eclipse.jgit.lib.Constants;
29 import org.eclipse.jgit.lib.FileMode;
30 import org.eclipse.jgit.lib.Repository;
31 import org.eclipse.jgit.lib.StoredConfig;
32 import org.eclipse.jgit.revwalk.RevCommit;
33 import org.eclipse.jgit.storage.file.FileBasedConfig;
34 import org.junit.Test;
35
36 import static org.junit.Assert.assertEquals;
37 import static org.junit.Assert.assertNotEquals;
38 import static org.junit.Assert.assertNotNull;
39 import static org.junit.Assert.assertTrue;
40
41
42
43
44 public class SubmoduleDeinitTest extends RepositoryTestCase {
45
46 @Test
47 public void repositoryWithNoSubmodules() throws GitAPIException {
48 SubmoduleDeinitCommand command = new SubmoduleDeinitCommand(db);
49 Collection<SubmoduleDeinitResult> modules = command.call();
50 assertNotNull(modules);
51 assertTrue(modules.isEmpty());
52 }
53
54 @Test
55 public void alreadyClosedSubmodule() throws Exception {
56 final String path = "sub";
57 Git git = Git.wrap(db);
58
59 commitSubmoduleCreation(path, git);
60
61 SubmoduleDeinitResult result = runDeinit(new SubmoduleDeinitCommand(db).addPath("sub"));
62 assertEquals(path, result.getPath());
63 assertEquals(SubmoduleDeinitCommand.SubmoduleDeinitStatus.ALREADY_DEINITIALIZED, result.getStatus());
64 }
65
66 @Test
67 public void dirtySubmoduleBecauseUntracked() throws Exception {
68 final String path = "sub";
69 Git git = Git.wrap(db);
70
71 commitSubmoduleCreation(path, git);
72
73 Collection<String> updated = new SubmoduleUpdateCommand(db).addPath(path).setFetch(false).call();
74 assertEquals(1, updated.size());
75
76 File submoduleDir = assertSubmoduleIsInitialized();
77
78 write(new File(submoduleDir, "untracked"), "untracked");
79
80 SubmoduleDeinitResult result = runDeinit(new SubmoduleDeinitCommand(db).addPath("sub"));
81 assertEquals(path, result.getPath());
82 assertEquals(SubmoduleDeinitCommand.SubmoduleDeinitStatus.DIRTY, result.getStatus());
83
84 try (SubmoduleWalk generator = SubmoduleWalk.forIndex(db)) {
85 assertTrue(generator.next());
86 }
87 assertTrue(submoduleDir.isDirectory());
88 assertNotEquals(0, submoduleDir.list().length);
89 }
90
91 @Test
92 public void dirtySubmoduleBecauseNewCommit() throws Exception {
93 final String path = "sub";
94 Git git = Git.wrap(db);
95
96 commitSubmoduleCreation(path, git);
97
98 Collection<String> updated = new SubmoduleUpdateCommand(db).addPath(path).setFetch(false).call();
99 assertEquals(1, updated.size());
100
101 File submoduleDir = assertSubmoduleIsInitialized();
102 try (SubmoduleWalk generator = SubmoduleWalk.forIndex(db)) {
103 generator.next();
104
105
106 try (Repository submoduleLocalRepo = generator.getRepository()) {
107 JGitTestUtil.writeTrashFile(submoduleLocalRepo, "file.txt",
108 "new data");
109 Git.wrap(submoduleLocalRepo).commit().setAll(true)
110 .setMessage("local commit").call();
111 }
112 }
113 SubmoduleDeinitResult result = runDeinit(new SubmoduleDeinitCommand(db).addPath("sub"));
114 assertEquals(path, result.getPath());
115 assertEquals(SubmoduleDeinitCommand.SubmoduleDeinitStatus.DIRTY, result.getStatus());
116
117 try (SubmoduleWalk generator = SubmoduleWalk.forIndex(db)) {
118 assertTrue(generator.next());
119 }
120 assertTrue(submoduleDir.isDirectory());
121 assertNotEquals(0, submoduleDir.list().length);
122 }
123
124 private File assertSubmoduleIsInitialized() throws IOException {
125 try (SubmoduleWalk generator = SubmoduleWalk.forIndex(db)) {
126 assertTrue(generator.next());
127 File submoduleDir = new File(db.getWorkTree(), generator.getPath());
128 assertTrue(submoduleDir.isDirectory());
129 assertNotEquals(0, submoduleDir.list().length);
130 return submoduleDir;
131 }
132 }
133
134 @Test
135 public void dirtySubmoduleWithForce() throws Exception {
136 final String path = "sub";
137 Git git = Git.wrap(db);
138
139 commitSubmoduleCreation(path, git);
140
141 Collection<String> updated = new SubmoduleUpdateCommand(db).addPath(path).setFetch(false).call();
142 assertEquals(1, updated.size());
143
144 File submoduleDir = assertSubmoduleIsInitialized();
145
146 write(new File(submoduleDir, "untracked"), "untracked");
147
148 SubmoduleDeinitCommand command = new SubmoduleDeinitCommand(db).addPath("sub").setForce(true);
149 SubmoduleDeinitResult result = runDeinit(command);
150 assertEquals(path, result.getPath());
151 assertEquals(SubmoduleDeinitCommand.SubmoduleDeinitStatus.FORCED, result.getStatus());
152
153 try (SubmoduleWalk generator = SubmoduleWalk.forIndex(db)) {
154 assertTrue(generator.next());
155 }
156 assertTrue(submoduleDir.isDirectory());
157 assertEquals(0, submoduleDir.list().length);
158 }
159
160 @Test
161 public void cleanSubmodule() throws Exception {
162 final String path = "sub";
163 Git git = Git.wrap(db);
164
165 commitSubmoduleCreation(path, git);
166
167 Collection<String> updated = new SubmoduleUpdateCommand(db).addPath(path).setFetch(false).call();
168 assertEquals(1, updated.size());
169
170 File submoduleDir = assertSubmoduleIsInitialized();
171
172 SubmoduleDeinitResult result = runDeinit(new SubmoduleDeinitCommand(db).addPath("sub"));
173 assertEquals(path, result.getPath());
174 assertEquals(SubmoduleDeinitCommand.SubmoduleDeinitStatus.SUCCESS, result.getStatus());
175
176 try (SubmoduleWalk generator = SubmoduleWalk.forIndex(db)) {
177 assertTrue(generator.next());
178 }
179 assertTrue(submoduleDir.isDirectory());
180 assertEquals(0, submoduleDir.list().length);
181 }
182
183 private SubmoduleDeinitResult runDeinit(SubmoduleDeinitCommand command) throws GitAPIException {
184 Collection<SubmoduleDeinitResult> deinitialized = command.call();
185 assertNotNull(deinitialized);
186 assertEquals(1, deinitialized.size());
187 return deinitialized.iterator().next();
188 }
189
190
191 private RevCommit commitSubmoduleCreation(String path, Git git) throws IOException, GitAPIException {
192 writeTrashFile("file.txt", "content");
193 git.add().addFilepattern("file.txt").call();
194 final RevCommit commit = git.commit().setMessage("create file").call();
195
196 DirCache cache = db.lockDirCache();
197 DirCacheEditor editor = cache.editor();
198 editor.add(new PathEdit(path) {
199
200 @Override
201 public void apply(DirCacheEntry ent) {
202 ent.setFileMode(FileMode.GITLINK);
203 ent.setObjectId(commit);
204 }
205 });
206 editor.commit();
207
208 StoredConfig config = db.getConfig();
209 config.setString(ConfigConstants.CONFIG_SUBMODULE_SECTION, path,
210 ConfigConstants.CONFIG_KEY_URL, db.getDirectory().toURI()
211 .toString());
212 config.save();
213
214 FileBasedConfig modulesConfig = new FileBasedConfig(new File(
215 db.getWorkTree(), Constants.DOT_GIT_MODULES), db.getFS());
216 modulesConfig.setString(ConfigConstants.CONFIG_SUBMODULE_SECTION, path,
217 ConfigConstants.CONFIG_KEY_PATH, path);
218 modulesConfig.save();
219
220 new File(db.getWorkTree(), "sub").mkdir();
221 git.add().addFilepattern(Constants.DOT_GIT_MODULES).call();
222 git.commit().setMessage("create submodule").call();
223 return commit;
224 }
225 }