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